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.
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.
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.
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].
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].
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.
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?
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.
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 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.
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.
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.
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?
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.
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.
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.
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?
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.
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.
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.
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.
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.
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.
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.
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.
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.
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!
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.
[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.
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