Direct manipulation of ADT values


A key feature of the Pivotal approach (and, before it, of the Vital approach) is that an end user is able to manipulate the values of ADTs by simple mouse operations. Or, described more carefully, a user is able to modify the source code of an expression in a Haskell document by mouse operations on its displayed value -- and thus, indirectly, alter the actual displayed value. The way that this is done relies upon the Display class and a built-in reflection mechanism.

The Display class, in addition to the display method (described in the previous section) also contains an edit method. This method (instances of which, typically, will be written by a skilled programmer, rather than by an end user), defines the way that Haskell expressions in a document are modified in response to mouse gestures by a user.

An example

Before describing the details of the mechanism, here is a simple example (an extension of the "Triangles" example from the previous section) showing an end user's view of the mechanism in action. In this example, we suppose that the edit method has been defined to be editTri, a function (defined later) that will allow a user to alter the shape of a triangle by clicking to define the new location of a vertex.

Imagine that the user has written an expression for a triangle with sides of 100, 80 and 80 units in length: TrianglesDM.hs The user is now able to modify the shape of the triangle simply by:

For example: TrianglesDM.hs This action can be carried out repeatedly. For example: TrianglesDM.hs

Notice how, in each case, the system has automatically updated the program and it is this modified program that gives rise to the modified display of the triangle. (The advantage of using this indirect approach to manipulating objects is that there is no hidden state information involved. Since any change is manifest in the document, represented by an ordinary .hs file, the modified document is both persistent (ie, it can be saved to file and reloaded) and portable (ie, it can be run on any other standard Haskell system).

We now examine how, by writing an appropriate definition of the edit method for the Display class, this effect is achieved.

The 'edit' method of the 'Display' class

Part of the definition of the Display class was described in the previous section. Here is its full definition:
class Display a where
  display :: a -> Pic
  edit    :: Int -> Int -> a -> Maybe String

  display a = PicText blue 12 (show a)  -- Default is to display as text
  edit x y a = Nothing                  -- Default is to do nothing
The purpose of the edit method is to generate a string with which to replace the currently selected expression in the document. The method is automatically invoked when a user right-clicks in a document. It takes as its arguments: It generates, as its result, a Maybe value: either Nothing (which causes no further action) or Just s, in which case the string s is used to replace the currently selected expression.

The 'edit' method for Triangles

In the present case, the edit method for the Triangle class was defined to be the function editTri. Here is the definition for this function; it simply takes the parameters (the lengths of the three sides) of the existing triangle and the (x,y) coordinates of the click point, and uses simple trigonometry to compute the lengths of the updated triangle. It then converts these values to strings and forms the text for the replacement expression. TrianglesDM.hs

Limitations

One final point: we note that this implementation of direct manipulation for Pivotal is very limited -- it suffices for demonstrating the principles involved but not for supporting sophisticated applications. This paper describes the principles behind a much fuller implementation of direct manipulation.