: A Retrospective Lessonsfor Flexible System Design

Nathaniel S. Borenstein Information Technology Center and Computer ScienceDepartment Carnegie-Mellon University

JamesGosling Sun Microsystems,Inc.

Abstract

UNIX Emacs is well-known and widely used as a developers of future extensible systems and text editor that has been extended in a remarkable testbeds. number of directions, not always wisely. Because it is programmable in a powerful yet simple This paper is an informal reflection of many years programming language, Emacs has been used as a of experience with Emacs. One of the authors development tool for the construction of some (Gosling) is the author of UNIX Emacs and of remarkably complex user-oriented programs. many extension packages for it. The other Indeed, it has served as both a user interface (Borenstein) is the author of several of the largest management system and a user interface toolkit, UNIX Emacs applications [Z, 31. In addition to though it was designed as neither. In this paper, personal experience, this paper also reflects the we discuss the features that have made it so results of a survey, conducted over the ARPA popular for user interface development, in an Internet, of several dozen Emacs programmers. It attempt to derive lessons of value for more is unabashedly anecdotal, and the authors make powerful and more systematically designed no pretense of having conducted systematic systems in the future. studies to prove our conclusions. Rather, we are simply attempting to convey the lessons we feel I. Introduction can be learned from the Emacs experience.

Designing gencralizcd tools for user interface II. What is Emacs? design and user interface management systems are now subjects of widespread interest. In order to The name “Emacs” has become a generic term, better understand what such systems should do in referring to an entire famiiy of powerful, the future, it helps to have a clear understanding extensible text editors, beginning with the original of what has come before. Although many systems ITS/Tops-20 Emacs [4]. That family has grown have been explicitly designed to serve these and matured to the point where it now includes a purposes, few have been very widely used. wide variety of programs that rcsemblc their predecessors to greater or lesser degree, as UNIX Emacs [I ] is a popular text editor with a surveyed by Stallman [5]. The present paper powerful extension facility, that has dcvcloped a discusses one of the most widely-used versions of large and extremely satisfied user community. Emacs, known commonly as “UNIX Emacs”, but The cxtcnsion facility has allowed Emacs to be also available for other operating systems, and used, not merely as a text editor, but as a general occasionally referred to as “.” In testbed for user interface design, and as a user this paper, the term “UNIX Emacs” will bc interface management system (UIMS). Of course, applied rather freely to both the early non- Emacs was designed neither as a tcstbcd nor a commercial and the more recent commercial UIMS, but simply as a text editor. That it was versions of the program. flexible enough to be extended so far aBeId offers us the opportunity to learn from its example, in The most powerful versions of Emacs arc al! both positive and negative ways. extensible in some extension language. ITS Emacs was extensible in TECO, an extremely baroque In this paper, we will briefly describe Emacs and but powerful language in which Emacs itself was its uses. We will then try to describe the most implemcntcd. Despite the clifliculty of important features of Emacs that have programming in TECO, a wide variety of contributed to its success,and also to recount the extension packages, including mail and bulletin problems that have been most frustrating to board readers, have been implcmcnted for that serious Emacs users. From this overview, we will version of Emacs. then oIIcr suggestions that may be of USCto the Permission to copy without fee all or part of this material is granted pro- vided that the copies are not made or distributed for direct commercial advantage, the ACM copyright notice and the title of the publication and its date appear, and notice is given that copying is by permission of the 95 Association for Computing Machinery. To copy otherwise, or to republish, rewires a fee and/or specific permission. @ 1988ACM 0-89791-283-7/88/0010/0095 $1.50 UNIX Emacs ofkrcd two major innovations over dircrcnt Emacs programs have been written to its prcdeccssors. First, because it was manage electronic communication (mail, bulletin implemcntcd under UNIX, it included powerful boards, UNIX nctncws, etc.). Others have process management facilities, allowing, for implcmcnted sprcadshccts, animation, database example, text to be filtered through arbitrary access, specialized program editing fcaturcs, and programs, and also allowing diKerent programs to even a BASIC interpreter. The longest Emacs be run in separate windows. Second, though program known to the authors is about 3000 lines UNIX Emacs is implemented in , it is cxtCnsible of source code, defining approximately 150 in a LISP-like language known as mlisp or Mock scparatc functions. Clearly the user community Lisp. The decision to USCa direreni language for regards .mlisp as a programming language extension than the one used for implementation powerful enough to do a wide range of tasks was a crucial one; it appears responsible for most beyond those related to simply editing text. of the best and worst aspects of UNIX Emacs as perceived by those who have used it most 111.What is Good about UNIX Emacs and mlisp? extcnsivcly. A discussion of the virtues and flaws of mlisp will comprise the bulk of this paper. A Why have so many application progra.ms, few brief examples, however, will scrvc to particularly user-oriented ones, been written in introduce the unfamiliar reader to the flavor of UNIX Emacs, using mlisp, when so many other the language. languages are available to the UNIX programmer? In an attempt to answer this The statement question, we distributed a questionnaire to Ema& programmers via the “UNIX-EMACS” mailing (defun (change-presidents list on the ARPA Internet and the UNIX Usenct. (replace-string “Reagan” We asked only a dozen questions, niostly open- “Mondale” ) ) ) ended ones like “If you were designing an editor extension language, what might you do that is totally dilferent from mlisp? What would you defines a new function, “change-presidents” that most particularly want to keep the same?’ will, when called, replace any occurrence of the Questions like these yield very interesting and word “Reagan” appearing after the cursor illuminating answers that are, unfortunately, position in the current document into the word extremely difficult to tabulate meaningfully. The “Mondale”. For a more complex example, the summary below represents the aggregate of the’ next program will also make sure that the new responses in the survey, with no pretense of word “Mondale” is alone and indented on a line. completenessor of meaningful quantitative data. Comments begin with semi-colons and are italicized here. Extensibility

(defun The one point on which nearly everyone seemsto (change-and-indent-presidents agree is that the best thing about UNIX Emacs is (save-excursion; Save that mlisp exists. No one even suggested that context &restorewhendone Emacs would be better without the powerful (while facility for extension and customization, although ( ! (error-occurred ; Keep it is clear that such facilities, if abused, can create loopinguntilerror an environment that changes so radically from (search-forward day to day as to be unusable for most people. “Reagan”) Donner and Notkin [6] discuss extension ,(delete-previous-word) mechanisms in general and oIT’er several (delete-white-space) ; convincing arguments for their desirability; the Delete surrounding spaces experience of Emacs users suggests that this (if (! (bolp)) desirability should- bc taken as a given. The (newline)) integration of powerful editing facilities with a ; Insertnewlineifnotat full-fledged programming language seems beginning unquestionably useful, though it remains a matter (if (! (eolp)) of some debate whether this combination is best (newline-and-backup)) achicvcd by an cxtcnsion language for a text ; Similar for end of line editor or by implementing the text editor as a (insert-string ” subroutine library in an existing programming Mondale”))l)))l language. Our experience suggests, in fact, that such a dcbatc is unresolvable, because such Mlisp is used for programs ranging from simple mechanisms serve rather difkrcnt purposes, and but repetitive editing tasks to elaborate user arc hot/ highly desirable. interface or even database systems. Dozens of

96 Simplicity of string length and storage management, and fast primitives are provided for taking portions of Nearly equally unanimous is the pcrccption that strings. OF course, one can argue that strings mlisp is a very simple and clcgant language, wcll- should be taken for granted as a basic data type suited to its intended application domain (editing in any reasonable programming language, but the text). Our survey rcvealcd that mlisp is gcncrally notion is still rather radical in the UNIX/C pcrceivcd to be an unusually easy language to community. learn and to use, perhaps partly bccausc it omitted complex features crucial to system For more complex operations, Emacs provides programming. The simplicity of mlisp will be a text “buITers” in which text can be inserted and recurring theme in discussions of both its virtues then manipulated with the full complement of and failings in the sections that follow. Emacs commands, including regular expression searching which can be used to implement A significant part of mlisp’s simplicity stems from complex parsing quite painlessly -- that is, without the implicit context available to a host of mlisp attention to the details of breaking words into commands. For example, the mlisp function tokens and similar low-level actions. (forward-character) moves the cursor forward one character in the current window or buffer. The Also popular with users as an abstraction tool is implicit context of this command is the name of the Emacs argument passing mechanism, which the current window, its contents, and the current allows each procedure to be called with a variable position within that window. A more powerful number of arguments. A procedure calls the language might allow such commands to operate “nargs” function to find out how many arguments in a wider set of contexts, but might also sacriIice it was given, and then can ask. for each argument simplicity in favor of more general operations by number. Especially popular is the feature that with more paramctcrs. Mlisp’s functions seem to allows functions to take an argument if it is given, be well-chosen to act reasonably in most contexts. or else ask the user to supply it if the function The key principle is that there is simple syntax for was called interactively, without the called simpfe operations. This does not mean that a more function ever having to know which of these two complex syntax should not be available for more alternatives actually occurred. (It should be complex operations, only that the complexity noted, however, that the parameter passing should not be forced on the programmer in a conventions are also one of the least-liked aspects simple context. of mlisp; it seemsthat the syntax and basic model are popular, but the semantics of parameter Clearly there arc other approaches to simplifed passing are almost universally despised. This is syntax. Another useful approach within the LISP discussed in a later section.) world is the optional argument syntax permitted by , which also permits easy use of Other users cited the abstract notion of “word” as defaults while allowing more complex usage when a major virtue of mlisp. Although mlisp dots not necessary. consider words as a type distinguishable from strings in general, it does provide several primitive Abstraction functions manipulating objects as “words” (e.g. forward-word and backward-word). The A major factor for many who have used mlisp is definition of “word” is provided by a buffer- the level of abstraction it provides. The language specific syntax table, which (among other things) has a built-in model of text and the operations defines which characters can be part of words and that may be performed on text (that is, a model of which characters delimit words. The notion of text editing) that is considerably more abstract the syntax tabie is extremely popular, although than that of most other languages. the interface to the syntax table is not so wcll- liked. To begin with, mlisp views text two- dimensionally, as a series of lines of arbitrary Another abstraction tool provided by Emacs is a length. It thus provides primitive functions such set of several “save-state” functions. Thcsc as next-line and previous-line, as well as forward- functions allow the user to save the some portion character and backward-character. This two- of the current state of the editor, cxecutc some dimensional view tremendously simplifies code arbitrary amount of mlisp code (which may that needs to parse small pieces of text in random include recursive edits, and hence an arbitrary parts of a file, a situation frequently cncountercd amount of interaction with the user) and then in such applications as sprcadshcets and clcctronic return to the previous state. These functions arc mail. used by nearly every major application package, although there are some complaints about a few Mlisp also provides strings as one of its basic data details of the implementation of the functions. types. Users are entirely freed from consideration Some of those survcycd went so far as to suggest Window and Process Management that mlisp should bc made a more strongly typed language, with basic types such as “window,” One of the reasons cited most often for the use of “file,” and “paragraph”. Others, the authors UNIX Emacs as a working environment is its included, would prcfcr not to be troubled with ability to function as a window manager, cvcn on type conversions bctwccn, for example, paragraph relatively unsophisticated display terminals. This and word. Implementing some of the Emacs ability is enough to convince many UNIX users to abstractions such as “windows” as data types do all their work within Emacs, using terminals would bc a dangerous undertaking, because the for which other window managers are not syntactic complications might outweigh the typically available. More important, the window proven value of the basic abstractions. At the managcmcnt features are a boon to programmers other cxtrcmc, mlisp can be viewed as taking a of user interface applications. The ACRONYM step in the direction of dynamic typing. In an idea1 help system, for example [2], responded to a user dynamically-typed system, howcvcr, the typing a question mark in the shell window by interprctcr or run-time system would detect placing help text in a second window and a menu inconsistencies in dynamically-typed objects, of further help topics in a third window. which mlisp dots not. Windowing is extremely time-consuming to code from scratch in a language such as C, but is Development Cycle built-in and trivial for the mlisp programmer.

Another commonly-cited reason for developing Our survey suggested that the window and user interfaces in mlisp and Emacs is the speed of process management features combine to make the development cycle. Because mlisp is Emacs a tool uniquely suited to the integration of interpreted, it is simple to write and debug a systems from diverse components. Because Emacs procedure at a time, without ever waiting for a treats both processesand windows at a high level compiler and a linker; in essence,mlisp provides of abstraction, it is relatively easy to write a short instant, integrated compilation and linking. As is mlisp program that passes messages back and well-known from other interpreted environments forth between, for example, a C program in one such as LISPS, this short write-test-debug cycle is window and a Lisp program in another, all under not only more satisfying for the programmer, it the control of a user communicating with the also encourages the kind of small changes that mlisp program. Many respondents indicated that tend to be so particularly important in user they had used mlisp for such integrating purposes. intcrfacc design (e.g. “Wouldn’t this look better a Typicalty, an application might have its most little further to the right?‘) computationally intensive or low-level parts coded in C, with integrating code and a user front end Another key notion in the design of miisp is that written in mlisp. the a programmer has access to the same functionality that the user has. If a user can bind Obviously, the window management facilities in a key to a function, so too a programmer can Emacs are simply not comparablc to those invoke that function. This creates an extremely available in a modern window manager [lo,1 11. simple model of learning to program, Nonetheless, most such window managers do not “programming by example”. This feature (which allow anywhere nearly as simple a manner of was not included in the earlier releases) allows access to the window facilities as was made users to type a series of keystrokes to perform a possible in Emacs via mlisp, and would benefit task, and converts the keystrokes to mlisp greatly by such a mechanism. commands automatically. Thus, entire first drafts, at least, of mlisp programs can be written Miscellaneous Virtues simply by “walking ‘through the program” by hand, using normal Emacs commands. Several Several other mlisp features were frequently users suggested that this process should be mentioned by respondents to our survey. Many generalized: user interfaces could first be expressed a fondness for the “execute-mlisp-line” developed by this walking-through process, then command, which allows an mlisp program to put debugged in mlisp with the interactive together a line of mlisp code itself and then dcvelopmcnt cycle just mentioned, and finally execute it. Others cited the help commands, translated to C for fast execution of finished which can be used to find, for example, ali defined programs. While it is unlikely that anyone will functions including the word “string”. Command ever expand mlisp to do this, current work with CompIction, whereby Emacs automatically dynamically linked languages [7,9] may yield the completes file names and mlisp function names, is same advantages in the long run. also well-liked. The “undo” command, which can undo the effect of nearly any operation not involving file manipulation, is predictably popular. Regular expressions, which facilitate

98 complex conditional text searches and thought out, and can often lead to horrible bugs replacements, are cxtremcly popular, although the in which one routine rcscts another’s variables. syntax used is less popular. The variable passing and naming schemes are so bad that they make recursion almost impossible in IV. The Down Side mlisp programs. Basically, they were designed to have the same semantics as macro expansion, Despite all the useful features, UNIX Emacs is, in which turned out to be only rarely desirable in fact, far from paradise for the user interface paramctcr passing. (However, they did permit a designer. Most of the problems fall in the correct implementation of the “case” statement as gcncral category of “implementation failings” -- an mlisp procedure.) either program bugs or fcaturcs that, in rctrospcct, should clearly work differently. Many Mlisp also suffers from poor debugging and such failings were mentioned by respondents to version control facilities. The few functions our survey, and will be mentioned here only supporting mlisp debugging were added to Emacs briefly. A more critical set of problems pertains rather late in its life,. and were never completely to inadequate integration of mlisp into the wider debugged themselves. It is also dificult to insure UNIX world; these can not fairly be categorized that several parts of a complex mlisp program arc as Emacs implementation failings because they mutually compatible, a signifcant problem for reflect the entire basic structure and relationship programs dependent on functions from the Emacs of UNIX and Emacs. Finally, many of those mlisp library. surveyed complained of specific features that are simply missing from the mlisp language. Respondents to our survey also complained about several administrative problems, including the Implementation Failings inadequacy of the Emacs help database and written documentation, the utter lack of a tutorial Most of the implementation failings in mlisp can introduction, and the cluttered state of the mlisp be traced directly to a simple misconception in its library distributed with the program. Finally, a design: mlisp was “only” an editor extension few genuine bugs were reported, primarily related language, so it was unclear that it needed to be a to the overflow of certain internal Emacs complete programming language. This is * parameters. probably the most important lesson to be learned from mlisp: extension languages arc real Integration Failings languages, not toys. Many of the respondents ‘to our survey had The most commonly cited implementation failing complaints that can be described as failures of is simpIy that mlisp is too slow. Mlisp is an integration. Typically, users complained of the interpreted language; the so-called mlisp compiler difficulty or slowness of getting access,in an mlisp merely translates tokens into a byte code for program, to the UNIX system library, the macro faster interpretation. The interpretive nature of preprocessor, low-level devices, or the internals of mlisp makes possible the rapid development cycle built-in mlisp primitives such as forward- discussed above, but most users would dearly love character. They also complained that several to see the interpreter supplemented by a true aspects of Emacs’ internal state are made dillicult compiler to allow completed applications to run or impossible for the mlisp programmer to inspect faster. However, it would be dillicult to or modify; examples of these include physical implement a real compiler without making the screen positions, the menu system, storage language more complex, which would be a shame. management, key binding state information, and text search state information. Another problem with mlisp is its inability to run asynchronously. While an mlisp program can These failings strongly reflect the fact that Emacs manipulate a large number of active is not written in mlisp; the whole point of miisp is asynchronous processes, none of them are mlisp to provide a simpler language for cxtcnding the processes;only one mlisp process can run at once. editor, with the almost inevitable result that some Worse yet, that process is uninterruptable, making things would not be available from within mlisp. an infinite loop a programming disaster. Various It is not at all clear what the right solution to version of Emacs have allowed asynchronous these problems would be; if Emacs were extcnsiblc mlisp processes,but these have typically depended in C, its implcmcntation language, it would not on variants of UNIX and could not bc supported have such problems, but would bc far less widely. convenient for most users and applications.

One part of mlisp that has been almost The integration failings also reflect the fact that universally condemned is its argument passing Emacs sufTcrs from the “design by accretion” and variable scoping. These are simply poorly syndrome. During the early stages of its life it

99 was possible to make wide sweeping changes The clear lesson to be learned from this is that, when some new feature required such changes to while flexibility in such a system is indeed fit smoothly. As Emacs became more popular, it essential, great care must be paid to get the also bccamc more entrapped by its own history. default behaviors to bc simple and natural, and to Changes became impossible because thcrc wcrc provide very clear and simple ways to use a too many users and too much mlisp code that carefully chosen small set of the most commonly dcpcndcd on the status quo. desired customizations. It may be, organizationally, that the people who build the User Interface Failings flexible tools are not necessarily the right people to figure out which are the correct defaults and It should also bc noted that, although Emacs has “standard options”. The process of making such proved to be widely popular, there remains a very choices probably requires serious observation of substantial set of pcoplc who have seen Emacs, users, or even controlled experiments, to compare tried using it, and violently despise it. There are possible system configurations. many reasons for such a reaction, but the most common one is discomfort with the general user Missing Features interface paradigm. The standard joke among such people is to extend one’s hand to another, as Finally, a number of those surveyed suggested if to shake hands, but to hold the hand twisted their favorite features that mlisp lacks. The and contorted into as unlikely a position as danger of runaway featurism is amply possible, and say, “Hi, pleased to meet you, I’m demonstrated by languages such as PL/I and an Emacs user.” Such people find Emacs’ Ada. Still, it is undeniable that many of the reliance on the CTRL key and ESC- or -X- features cited in the survey would be wonderful prelixes to be overly confusing and difllcult to additions to mlisp: floating point arithmetic, learn. complex data types, arrays, lists., case statements, graphics, fonts, underlining, highlighting, and Indeed, studies of text editor performance [12,13] pointers, and constants. Other, less clear-cut indicate that it is not too difficult to build an suggestions included vectors, infix arithmetic, editor with a more easily learned set of keyboard support for “paragraphs” at the level now given commands, with no sacrifice in expert to “words”, structured document editing, performance levels. Clearly, Emacs has succeeded alternate syntax (more like algorithmic languages in spite of its command syntax rather than such as Pascal), and multiple parenthesis types for because of it, although a surprising number of easier parenthesis balancing. people have come to regard it as natural to type CTRL-SHIFT-2 to set a mark in a buffer. In addition, it goes almost without saying that Emacs was written for a previous generation of It didn’t have to be that way. In the development computer technology; there is absolutely no of Emacs, it was far too easy to say that, since the support for the kind of sophisticated graphics basic interface was entirely customizable, it wasn’t people are coming to take for granted on a important to devote a lot of attention to getting modern workstation. the default interface to bc correct. After all, anyone who didn’t like the interface could change V. Conclusions: Implications for Future Toolkits and it. What this attitude ignored, however, was the User Interface Management Systems old rule our mothers used to teach us about the lasting value of first impressions. Many people UNIX Emacs has proven to be an extremely tried Emacs, couldn’t stand the basic interface, valuable tool for a wide variety of unintended and went back to their old standard editors, such purposes, most notably “quick-and-dirty” user as the vi editor on UNIX. interface design. The great virtue of Emacs is its extensibility; the great virtues of mlisp are its It is worth noting that this happened despite the simplicity, its abstract, high-level view of text, fact that several people, indcpcndently, strings, processes, and windows, and the quick implemented more or less complete vi emulation development and prototyping cycle it facilitates. packages for Emacs in mlisp. It seems that even Its greatest failings are its lack of integration into if a package existed that was an absolutely perfect UNIX as a whole, and specific features that simulation of vi, most of the people who prefer vi reflect a design that did not recognize the need to to Emacs would stick with the clearly less make an editor extension language a “real” powerful vi. While this is in part due to the programming language As tools are developed smaller size of vi, it is also attributable to the for rapid prototyping of user interfaces on the unacceptable difliculty, in the minds of such next generation of hardware, close attention to the people, of having to learn how to turn the vi success and failings of UNIX Emacs may make emulation package on in the frst place. those tools more generally useful than they might otherwise be.

100 The biggest uncertainty in the minds of those [4] Stallman, Richard M., “EMACS Manual for surveyed, as well as the authors when the survey TOPS-20 Users”, MIT AI Memo 556, 19X1. began, was whether or not mlisp should have been more than it is. That is, it was widely [5] Stallman, Richard M., “EMACS, the recognized that one of the great virtues of mlisp is cxtensivlc, cusotmizable self-documenting display its simplicity, and that one of the great failings of editor”, Proc. ACM SIGPLAN SIGOA mlisp is in its lack of power for specific kinds of symposium on text manipulation, Portland, tasks. It is not clear whether or not thcsc two Oregon, June, 1981. facts can be separated. Can mlisp be made significantly more powerful without destroying its [6] Donncr, Marc, and David Notkin, ‘Flexible simplicity? This is an important topic for Systems; Customization and Extension”, to programming languages in gcncral, but appear in IEEE Software. particularly so for user-oriented application programming, where rapid prototyping is most [7] Kazar, Michael, “Camphor -- A Programming essential. Language for Extensible Systems”, Usenix Conference, 1985, Portland. Later projects have pursued different stratcgics regarding the question of extension mechanisms in [8] Gosling, James, and David S. H. Rosenthal, such systems. The original Andrew Base Editor “The User Interface Toolkit’*, in Proceedings of [8], for example, retreated from the notion of a PROTEXT I Conference, 1984. full-blown extension language like mlisp, choosing instead to provide the entire facility as a powerful [9] Palay, et al., “The Andrew Toolkit: an subroutine library for the C programmer. This Overview”, Proceedings of the USENIX avoided problems of underpowered language and Technical Conference, February, 1988. over-ambitious use of the extension mechanism, but at the cost of radically lengthening the process [IO] NcWS Manual, Sun Microsystems, Inc., of prototyping and perfecting user interfaces. March, 1987. The most recent version of the Andrew Toolkit [9] improves this scheme substantially by allowing [I I] Scheifler, R. W., and J. Gettys, “The X customization via dynamically loaded C Window System”, ACM Transactions .on programs, but this is still too cumbersome for Graphics 5(2) pp. 79-109, April, 1986. casual customization purposes. it stems likely that the only “right” solution involves making the [ 121 Roberts , Teresa, and Tom Moran, “The functionality of the system available at two levels: Evaluation of Text Editors: Methodology and in the implementation language (e.g. C) for the Empirical Results”, Communications of the most serious applications, which require high ACM, April, 1983. i levels of reliability and performance, and in a simpler extension language for rapid prototyping 1131Borenstein, Nathaniel S., “The Evaluation of ! and simple customization. Text Editors: A Critical Review of the Roberts and Moran Methodology Based on New Acknowledgements Experiments”, Proceedings of CHI ‘X5 Conference, 1985. We would like to thank the dozens of mlisp programmers who took the time to respond to our survey. We would also like to thank Mike Kazar, Bruce Lucas, and several anonymous reviewers for their helpful comments on a previous draft of this paper.

Bibliography [l] Gosling, James, “Unix Emacs”, Carnegie- Mellon University Computer Science Department, 1981.

[2] Borcnstcin, Nathaniel S., “The Design and Evaluation of On-lint Help Systems”, Ph.D. Thesis, Carnegie-Mellon University, 1985.

[3] Borcnstcin, Nathaniel S., “The BAGS Message Management System”, Carnegie-Mellon University Computer Science Dcpartmcnt, 1985.

101