Programming on an Already Full Brain

Christopher Fry

PowerScout Corporation

Abstract

Programmers optimize the inner loops of their code because that's where the biggest performance gains are possible. Programming environments should do the same. The inner loop of a programming environment is figuring out what to type and typing it. Is it possible to make a programming environment that actually speeds up figuring out what to type, and speeds typing itself?

Getting correct all the details that a typical programming language demands takes lots of biological memory, frequently more than is available. But, at any point in typing code, options are usually constrained by the legal constructs of the language, the functions and data available, and the interactive context. Since the programmer's brain is already full with details of the task and algorithm, why not have the computer try to figure out what the user might type next, depending upon context? Emacs Menus is an adjunct to a text editor that presents the user with context sensitive menus containing options that are at least syntactically and type-wise legal for the code under the mouse.

Most debugging tools concentrate on finding and fixing the relatively infrequent deeper bugs such as errors in algorithms. But, in practice, too much time is taken up with edit/compile/debug cycles for minor bugs such as typos and "brainos", i.e. using "kill" instead of "delete" or reversing two arguments to a function. By catching these problems in the editing stage, Emacs Menus speeds the inner loop of programming.

The Problem

Of the things that humans do, there is, perhaps, no task more demanding of biological memory than programming. A common myth in our society is that the human brain is unlimited in its capacity for knowledge. I don't buy it. We can only store so much at a particular time, and our ability to change the contents of that finite memory over time is, to be polite, limited. Overcoming that limitation is the strong suit of the computer. Where humans are relatively good in comparison to their silicon peripherals is in abstract thought and higher level knowledge organization. Where computers are good is in storing and searching large amounts of data. Emacs Menus is a tool to help each member of the essential programming team, a computer and a person, optimize what it does best and interface smoothly to the other half of the team.

Programming isn't just writing, it's design. We can break the continuum between concept and code into four major stages:

1. Conceptual design

2. Picking the right components to assemble

3. Assembling the components

4. Testing

The conceptual design phase takes place mainly in the programmer's head. Picking the components and understanding how to assemble them requires answering questions like, "What components are there to choose from?", and "How do I put them together?". It is here that the programmer's biological memory may begin to overflow.

A modern programming language may have choices numbering in the hundreds or thousands. For those fortunate enough to have occupations that allow them to program full time, or those blessed with an infallible memory for detail, the answers to these questions may pop to mind immediately. The rest of us tend to stick to a small set of familiar commands that we are likely to use correctly, and give up on the rest, regardless of their utility.

Understanding what parts are available and how to put them together is crucial. Since the need for this information is greatest just as the user is about to type, the approach of Emacs Menus is to build an agent into the text editor that dynamically computes what choices are available, through knowledge of the programming language and knowledge of the interactive context. The help is made available, not in some "help window" or "help mode", but on a popup menu right at the point of insertion, exactly where you need it. Further, unlike most help systems, it doesn't just tell you what you should do, it saves you the trouble of mistyping it.

Previous Solutions

Until now, there have been two approaches to the problem of inputting programs. The classic solution has been to type programs in an unrestricted text editor, just like you might type a natural language document. The second solution is for the system to provide a text based structure editor. The third is a special kind of sturcture editor that uses icons instead of text to represent the program source.

1. Text Editors: The non-solution

Text editors give you so much rope that its hard to use them to correctly specify so simple a task as hanging yourself, let alone writing a valid piece of software. You create a new document and are presented with a large blank space into which you can enter just about any amount of garbage composed of characters. You have the freedom to create illegal syntax, nonsensical vocabulary and comment the code with whatever you like, regardless of validity.

After a document is created in the text editor, the next step is to submit it to a compiler or interpreter, which checks the validity of the syntax and report errors. If the program makes it through this step, it is executed, and any semantic errors that arise are reported. In either case, any errors force the programmer back to the text editor. The programmer is faced with the cognitive task of associating the error message with the place in the code that caused it. Several errors may be reported at once, which may have either a single underlying cause or a series of independent causes, further confusing the matter. While modern programming environments try to minimize the overhead of context-switching in the edit/compile/debug cycle, it is nonetheless significant, even in the best of them. This violates the principle of immediacy [see the Ungar, et. al. article in this issue].

2. Structure editors and form-based languages: The bureaucratic solution

An approach that tries to retain the flexibility of text editing, while adding knowledge about the programming language structure, is structure editing [10]. In this approach, the unambiguous structure of function calls or data structure description is neatly delineated by a form which permits you to enter text into a named slot. Free text editing is only allowed within the fields.

Structure editors do reduce the possibility of syntactic error, but lose the flexibility of free text editing. No longer can the text motion, searching and editing commands be used indiscriminately on any visible text, but specific commands to move up and down the template structure are needed. Because you can't enter illegal syntax, you can't change your code by passing through several illegal states, as is often necessary when you want to make somewhat more than a trivial modification.

Structure editors also typically take advantage only of the static knowledge of the programming language syntax. As we will see with Emacs Menus, much more can be done by taking into account the dynamic context: exactly where the user is in typing the program, what has already been typed, what variables are available at the moment, etc.

There are two kinds of structure editors. One is to embed the structure editor inside a text editor, and the templates are inserted as text. Another is form-based programming, where the template is graphical. While I was at MIT's Center for Coordination Science, I worked on a forms-based programming environment, OVAL [5].


An Oval form for specifying a data structure

This kind of programming environment provides clear on-line help for both writing and reading code. Parsing for the compiler is trivial so some checking can performed on arguments and data slot values by rather simple programs.

But forms-based programming suffers from severe space inefficiencies [as do the iconic languages discussed below]. The designer of the form can't predict one good size for an argument to take up. Dynamically varying the size of fields via scrolling or resizing the form consumes either more operations in the user interface, more space for controls, or both. Embedding forms within forms is the logical strategy for depicting nesting, but the borders tend to take up an ever larger amount of screen real estate.

3. Iconic languages: The straight-jacket solution

Iconic programming environments offer many benefits to the memory-challenged [8]. They provide palettes of functions so you need not remember what functions exist or how each is spelled. They provide constrained ways to wire up functions so that you can't enter syntactically incorrect code. Furthermore, the operations to edit your code can be as intuitive as dragging a wire between an output and an input. But for large, complex programs the iconic cure is often worse than the freedom-of-text disease.

Much as I love graphics, words are more spatially efficient. One word is worth a thousand pixels of icon, yet takes up less screen real estate. Iconic programs can't display as large a section of the program at once, and the smaller the piece of your program you can see at once, the harder it is to mentally piece the whole thing together, causing yet another biological memory problem. If we try to have a large set of small icons, we run into the same memory problems again. Marian Petre [7] discovered that a graphic representation was so hard to understand that people tended to use the textual representation to help them understand the graphical one rather than the other way around.

Visual programming also confronts the programmer with the task of spatial layout of the icons. Unfortunately, programming is a task where constant revisions are necessary. Sometimes you want to add ten times as much code in a particular area than your original layout left room for. Now you've got to spread everything out to make more space. Your original work in laying out is wasted. There are automatic layout programs but these are tricky to get right and often don't convey the "semantic proximity" that the programmer intended.

So are we doomed to do no better than a text editor?

Emacs Menus: The best of several worlds solution

It should come as no surprise that I chose rather conventional text as the medium for displaying code. It is the most flexible and the most dense. I'm all for careful pretty printing of that text, but that is already provided in decent text editors.

Superset of a Text Editor

Hackers familiar with text editors who switch to different kinds of programming environments often lament the lack of their favorite features of their favorite text editor. The first characteristic of a programming tool I wanted to achieve was to be no worse than an existing text editor. So I chose to implement Emacs Menus on top of an Emacs-like text editor. All the commands of the underlying text editor are present. Also I do not waste permanent screen real estate on displaying palettes of commands, as in many iconic environments. In fact, unless you are aware of the enhancements, you may be unable to detect that a powerful tool awaits under your mouse.

At any time while the user is in the text editor, holding down the mouse brings up a pop-up menu, after a short delay. The delay is so that a quick click will simply reposition the text cursor, without bringing up the menu. Holding down the mouse requests help from the system, "What might I do next?". It is important the menu appear right at the point of insertion, where the user's attention is focused, and not elsewhere on the screen.

The Emacs Menus top-level menu

The contents of the menu that actually appears at any moment is highly dependent upon the textual context. Emacs Menus analyzes the surrounding code, and displays only those choices that make sense for the current context. Since the user is faced with a large space of possible choices, the popup menu does present a large number of items, but as we'll see, the categorization of items, and special "4D Menu" navigation features make these large menus less scary than they might first appear.

Just In Time Help

The menu that pops up contains submenus of:

code to insert,

other commands to perform and

knowledge about what you've just clicked on.

I describe that last functionality first.

Emacs Menus works on Common Lisp code. I have built a database that contains information on what functions and global variables exist in Common Lisp. Each variable has associated with it the type of values it can hold, and several typical values with one of them designated as a default value. The database entry for each function contains the type of the result, as well as the name, type, typical values and a default value for each parameter. Parameters to Lisp functions can be required, optional, keyword or "&rest" [meaning any number of arguments can be passed].

For the below discussion I will use parameter to mean the description of the kind of value that can be passed to a function whereas the word argument means a particular value passed in a particular function call.

A typical mouse-down will be on an argument to a function. The Emacs Menus inside-out parser [see below for details] figures out which parameter to which function, looks it up in the EM Common Lisp database, and constructs, on the fly, a submenu containing items for information purposes only. [Selecting one of such items does nothing]. The items are:

The name of the enclosing function call and rank of the argument, such as "2nd arg to +"

The kind of the parameter [required, optional, etc.]

The type of the parameter [number, sequence, etc.]

The type of the actual argument being passed [integer, string, etc.]

Whether or not the type of the argument matches [is the same as or a subtype of] the parameter type.

Usually EM can infer the argument type by knowing either the result type of arguments that are function calls, the type of Common Lisp global variables, or the type of literals. For lexical variables and some other constructs, EM can't infer the type. This type-checking helps catch a lot of errors that in a weakly typed language like Lisp might not be caught until run-time. In a strongly typed language like Java, it will catch errors before the compiler is invoked.

The Context Info Menu showing information about the 2nd argument to +.

Inside-out Parsing

If we are to escape from the straight-jacket of iconic programming and the regimentation of forms-based programming, we've got to let the user create illegal code fragments. Maintaining an accurate model of what all the text in a buffer represents is therefore difficult at best. Emacs Menus simply doesn't do it.

However, Emacs Menus relies on having detailed information about the code under the mouse. Every time you click down and hold on some code a parse of the underlying text is started. Most parsers start at the beginning and move sequentially through the text. Theoretically Emacs Menus could start at the beginning of the buffer, but this would take too long, particularly in the face of illegal code between the beginning of the buffer and the mouse position. You see, the Emacs Menus user interface requires that a fraction of a second after you click down, a context-specific menu of information and commands pops up. The parser starts where you have clicked and parses outwards. It stops when it has captured just enough to identify the current statement and its enclosing form, which usually means which argument of which function call.

Coding via Mouse

The sooner you can catch errors in the coding process the better. One reason that's true is simply that you have some mental state built up in the current code you're working on. Creating that mental state takes time.

The information menu in EM helps catch errors such as wrong number of arguments to a function or wrong type of an argument before the compiler or run time but after they've already been entered. But can we catch errors even sooner?

Using the information menu described above you can get just-in-time help on an argument before you enter it. Say you type in a function call to the Common Lisp function i.e. (elt ) which returns the nth element of a list, but you wonder whether its the first or the second parameter that accepts the sequence in question. You can use the information menu to tell you the name and type of the first argument to elt. You'll find that the first argument is a sequence and you can then type in your sequence. That's a lot faster than looking up the function in the documentation, but can we do even better?

Another submenu off of the main EM menu contains typical values for the place under the mouse. In the case of the second argument to + where you must pass a number, you'd see menu elements for -2, -1, 0, 1, and 2 giving you examples of what kinds of values can go there. A correct set of examples not only make a strong hint as to the type of value that can be used but also tell you the syntax of those values. But can we do even better?

The Typical Values menu for an argument to +

In the case of functions like the second argument to +, certain values are very common. Several small integers qualify. If you select an item from the typical values menu, that item is inserted into the program text at the place of the mouse. This avoids typing the code in, but even more importantly avoids you making a mistake, forcing you to go through a compile/debug/edit cycle. For parameters of type sequence, the menu of typical values might contain the empty string "", the empty list () and the empty array #[]. A user can pick one to insert it, then edit those values to contain exactly what they want. EM can't read your mind, but it at least helps out with getting the basic syntax right.

Typing in unbalanced delimiters is a common bug in Lisp coding that need never occur if you use Emacs Menus. In fact I found this so compelling a use that I made a special menu containing just delimiters. Common Lisp multi-line comment delimiters are particularly error prone. If you insert delimiters on whitespace just an empty pair is inserted. But if you are over an expression or select some text then choose insert, the delimiters are wrapped around the text in question.

The Delimiters menu.

Inserting Lexical Variables

Sometimes the code you want for an argument is not a literal, but the name of a lexical variable [also called local variable which includes the names of function parameters]. Another one of the submenus off the main EM menu contains a list of all the lexical variables that are legal [i.e. "in scope"] at that point in the program. Thus you only have to type in the name of each variable once [to declare it]. From then on you can pick it from a menu avoiding inconsistent spellings altogether. Since the menu only contains variables that are legal at that point, you'll never get an "undeclared variable" error. Unfortunately EM doesn't yet infer the types of lexical variables so, unfortunately, you can insert a typewise incorrect variable. Fixing this is a natural extension to Emacs Menus.

Inserting Function Calls

Complex code frequently has deep nesting of function calls. We need easy ways of inserting function calls. When you pick a function call off of an Emacs Menus insert menu, a call to the function is inserted, including both open and closed parentheses. The cursor is moved to the position of the first argument so that you're ready to pick it from a menu as well.

The real problem with functions is that there's so many to choose from. Common Lisp contains about a thousand. Its nice having all that functionality in the language but wading through them to find what you want is a real challenge even for seasoned hackers. Emacs Menus to the rescue.

The first trick is to figure out what functions the user is likely to want to call based on context, then stick them on the typical values menu. A few special cases can go a long way. The first is at top level within a file. When the user clicks down on whitespace that is not within another construct, the typical values are forms for defining functions, macros and global variables. EM's typical values for top level menu also contains the package declaration form and a call to load a file. As a group, these make up the vast majority of top level forms in most programs.

The top level insert function call menu.

As it turns out, function calls that are at the top level within a function definition also fall into a relatively constrained pattern. Declaring and setting local variables, and a few control structures like if, cond, and do loops make up a significant fraction of many top level calls in a definition. Once you've started off with these two tricks, you can rely on picking typical values for arguments of the above functions for a fair fraction of your code. Typical values may include function calls themselves indicating common idioms.

But obviously these tricks don't cover many important cases. Once we add the thousand or so Common Lisp functions to the functions for a decent window system and a few other utility packages, we've got several thousand possibilities. Egad, all on one menu?

4D Menus

A linear one dimensional menu becomes very cumbersome with more than 20 or 30 items. We can get a second dimension using hierarchical menus. That helps for a few hundred items at best. Are we finally going to have to resort to remembering what to type out of our already full brain?

I invented a new kind of menu that has two more dimensions. The third is the horizontal. A 4D menu contains several columns of items. I've found three or four columns to be reasonable. You can scan 80 items, in four columns of 20 rows fairly quickly.

The fourth dimension is "pages". By moving the mouse outside of the menu then jiggling the mouse slightly to the right or left, you can employ minimal movements to quickly flip these two dimensional pages. Just as humans with good spatial memory can remember "some blob in the lower right hand corner of a page in a book" and can flip the pages to find the right page, so can an Emacs Menus user relocate a menu item they've been to before. I've used color as an additional redundant clue to help you recognize a page and as an indicator as to how deep you are in a page stack.

Using pages with, say 50 items and page stacks that are five deep gets you 250 items all without scrolling. Adding hierarchical submenus makes it easy to get up to several thousand items, all without scrolling.

Menu Organization

Being able to put thousands of items on a menu is nice, but without proper organization, finding what you want can be really time consuming. I concluded that we need more than one organization of the Common Lisp functions as you want to 'look them up" in different "indexes".

Alphabetical ordering is an obvious organization, although it is not in the current implementation. Having the front page of the menu contain all the starting characters of functions with each item being hierarchical is an easy way to take advantage of 4D menus.

My primary organization is by returned type. All the functions that return strings are under one subtree, all the functions that return numbers under another, etc. This was particularly convenient when you were about to insert an argument to a function call where you knew the type of the argument and the general functionality that you were after but had no idea of how to spell the function name.


This menu of types contains submenus which list functions that return values of that type.

I found though, that this wasn't always what I needed. Sometimes I didn't really care about the returned type of the function, but I just need to scan the functions that manipulate

strings. Some of them return non-strings so you can't simply look under the String subtype menu and find them. So I built a menu organized by the chapter of Common Lisp the Language [9] that the function was documented in. This proved to be a valuable way to capture semantic neighborhood.

Even with such structuring some of the submenus still have a confusing number of items on them. The horrible thing about large dictionaries and large programming languages is that if you are looking for a common word, it takes you much longer than looking for a common word in a smaller language. So I've split large categories into common and uncommon parts. First you scan the common list and if you don't find what you want you can delve into a submenu of the less frequently used functions. This is especially useful for beginners since it makes the primary disadvantage of a large language disappear. Anything we can do to help the user pick the correct function the first time will save debugging time down the road.

Commands

Programming is not just inserting text. You've got to edit text, even text that is syntactically correct. There are also a number of debugging tools that you'd like to invoke which take code fragments as arguments [4]. Emacs Menus has an extensive tools menu that simplifies the invocation of tools. I'll briefly describe just one, one that is so important I moved it to the top level menu.

The Debug Tools menu

Lisp has long had a function named "apropos". It takes an argument of a string and prints out all of the Lisp functions and global variables whose names contain that substring. The "Find Symbols" that I developed for Emacs Menus gives you many more ways to filter the space of possible functions than traditional apropos. You might consider it to be an interactive way to construct custom menus of functions in case the above organizations using 4D menus weren't convenient enough. With a few mouse clicks, the Find Symbols dialog enables you to filter down the set of interesting functions to an easily scannable 10 to 30. You can then get documentation on each and, when you'd finally found the right one, click on it to insert it into your program. Since Find Symbols could be invoked on some selected text already in your editor buffer, you didn't even need to type the initial substring as you would when invoking conventional apropos.

The Find Symbols dialog

There's few things more frustrating than being in the middle of fixing a bug and inadvertently introducing a second bug by misusing a debugging tool. If Emacs Menus fails to prevent the first kind of bug, it can at least prevent the second.

The bigger picture: Language design, hardware

Although the problems and the solutions I provide can be applied to just about any textual programming language, the particulars of the syntax makes a difference. The more inconsistent and complex a language is, the more you need help and the harder it is to write the code to give you that help. Elegant syntaxes like Lisp are easiest for logical humans and programs to parse. Languages which combine infix and prefix syntax like C and Java make life more difficult for the user and tool-builder alike.

Emacs Menus is software that desperately needs input interface hardware designed with humans in mind. Switching between mouse and keyboard is bad. Most hackers I know think in terms of key bindings that can perform equivalent mouse operations so they don't have to switch to and from the mouse. I think in the opposite direction so that you don't have to switch to and from the keyboard. EM provides most operations via the mouse, but you still need to enter each new identifier at least once.

We need five buttons on a mouse. If you've ever had to hold down a keyboard key in combination with a mouse-click you should understand how badly the designers of the one, two or three button mouse blew it. Having scrolling on the mouse eliminates the need for scroll bars which take up lots of screen real estate. Putting the default action on a button eliminates the coordination necessary for double-clicking. Having help and an "addtional operations" menu each on its own mouse button eliminates the need to move up to the menu bar for operations.

I'm a firm believer that the pen is mightier than the mouse and can even be more covenient for entering small amounts of text. Character recognition is getting to be quite reliable especially with stylized characters such as those used in the "Graffiti" product. [6] On-screen keyboards are potentially even faster than Graffiti particularly if well laid out such as Instant Text [11].

Throughout the design of Emacs menus I wanted a pen-based computer. Note that it is not good enough to have a tablet, you need a screen that you can write on. Its hard to get five buttons on a pen but with a pen we get not only higher spatial resolution, but the additional dimensions of pen angle and pressure that make up for the measly one or two buttons that you can fit comfortably on a pen. Speech recognition could be advantageously employed as could two pointing devices, one for each hand [1].

Once we make the leap to throw out the keyboard and use input devices that are actually designed to fit the human body, the smooth integration of hardware and software becomes very attractive. Under those circumstances, tools like Emacs Menus can really shine because the hardware doesn't get between you and your bugs.

Repetitive Strain Injury

For many hackers, debugging is a painful activity, both mentally and physically. Hackers hack long hours. This prevents them from getting AIDS or addicted to crack but they are not immune to RSI, the Hacker's Disease. I bet overuse of the text editor Emacs is the cause for half of the RSI in East Cambridge, including that of its inventor, Richard Stallman.

Emacs Menus permits you to perform most operations using the mouse which, unfortunately, can cause RSI in your mousing hand. But you do not have to suffer either extreme. Since it is trivial to move between keyboard and mouse, a user can pick whichever input device is less painful at the moment, making their movements less, um, repetitive. Furthermore, the mouse, particularly the one button variety found on Macintoshes, has many variations. You can use it with either hand. You can augment it with head trackers, eye-trackers, trackballs, trackpads, the IBM Trackpoint or even devices operated with the feet or voice. Emacs Menus allows programmers to distribute their physical stresses across a variety of input mechanisms.

No less dangerous than repetitive strain injury of the hand is repetitive strain injury of the brain. Programming environments that require repetitive, low-level, mind-numbing operations to get anything done are a prime cause of programmer burnout.

Status and Future Work

Emacs Menus was implemented on the Mac using Macintosh Common Lisp [2] with lots of assistance from Emacs Menus. What good is a tool that can't help make itself better?

The Common Lisp database to support Emacs Menus is not fully implemented. I put in support for enough functions to test the basic ideas but many more need to be implemented before EM lives up to its promise for coding Common Lisp. The system has never had extensive use outside of its use in developing itself. It could benefit greatly from user studies.

Summary

All programming environments involve trade-offs. The trick with Emacs Menus was to design a system that didn't make it easy to make mistakes [like a text editor] yet made it easy to do whatever you wanted [like a text editor]. This was achieved by using one giant context sensitive "4D" menu that gives the user just-in-time help, the ability to insert textual code without typing, and access to appropriate tools all with minimal cognitive overhead.

If organized right, new kinds of menus have the power of giving you thousands of operations without requiring the biological memory that would be taken up by thousands of words. Regardless of the capacity of your memory system, when it's full, you need help!

Acknowledgments

These ideas were not developed in a vacuum but rather in Cambridge MA. which is as distant semantically from an intellectual vacuum as anywhere in the known universe. Stars of this environment for me have been:

The folks at Coral Software who I worked with to develop the first version of Macintosh Common Lisp.

David Levitt, who roped me in to co-founding Hip Software, a terribly creative '80s start-up doing iconic programming environments that went nowhere financially.

Tom Malone of MIT's Center for Coordination Science, for the vision of a generalized Information Lens that employed forms-based programming.

Jo Marks of Harlequin for the kind of wisdom seldom found amongst software developers.

Mike Plusch of PowerScout Corporation for creativity broad and deep

Henry Lieberman of MIT's Media Lab for the best comrade in arms I can imagine during our long battle for innovation in programming environments.

References

[1] Buxton. Bill "The Natural Language of Interaction" in The Art of Human-Computer Interface Design, Brenda Laurel, Addison Wesley, Reading MA, 1990

[2] Digitool, Macintosh Common Lisp, Digitool, Cambridge, MA, 1996

[3] Goldberg, David, and Cate Richardson. Touch typing with a stylus. In Proc. Conference on Human Factors in Computing Systems (INTERCHI), pages 80-87. ACM/SigCHI, Apr 1993.

[4] Lieberman, Henry, and Fry, Christopher, ZStep 95, A Reversible, Animated Source Code Stepper, in Software Visualization: Programming as a Multimedia Experience, John Domingue, John Stasko and Blaine Price, eds., MIT Press, Cambridge, MA, 1997.

[5] Malone, Thomas, Kum-Yew Lai and Christopher Fry "Experiments with Oval: A Radically Tailorable Tool for Cooperative Work" in Proceedings of the ACM Conference on Computer Supported Cooperative Work [CSCW], 1992

[6] Palm Computing Inc., Graffiti, 4410 El Camino Real, Suite 108, Los Altos, CA 94022

[7] Petre, Marian, Why Looking Isn't Always Seeing: Readership Skills and Graphical Programming. Communications of the ACM, Volume 38, Number 6, June 1995, p.33-44

[8] Shu, Nan Visual Programming Van Nostrand Reinhold Company, New York, 1988

[9] Steele, Guy L. Jr. Common Lisp the Language, Digital Press, 1990

[10] Szwillus, Gerd, and Lisa Neal, Structure Based Editors and Environments, Academic Press, 1996.

[11] Textware Solutions, Instant Text, 83 Cambridge St., Burlington, MA 01803

[12] Ungar, David, Henry Lieberman and Christopher Fry, Debugging and the Experience of Immediacy, Communications of the ACM, April 1997.

About the author

Christopher Fry is the Chief Technical Officer of PowerScout Corporation in Boston. His current primary interest is the visualization of complex data structures as diverse as the World Wide Web or intermediate values within a program development environment. Over the past couple of decades, Fry has hacked at MIT and numerous MIT spin-offs. Author's Present Address: PowerScout Corp., 21 Crescent Rd., Lexington, MA 02173 USA. Email: cfry@shore.net