xref: /plan9/sys/doc/plumb.ms (revision 426d2b71458df9b491ba6c167f699b3f1f7b0428)
1.HTML "Plumbing and Other Utilities
2.TL
3Plumbing and Other Utilities
4.AU
5Rob Pike
6.AI
7.MH
8.AB
9.LP
10Plumbing is a new mechanism for inter-process communication in Plan 9,
11specifically the passing of messages between interactive programs as part of
12the user interface.
13Although plumbing shares some properties with familiar notions
14such as cut and paste,
15it offers a more general data exchange mechanism without imposing
16a particular user interface.
17.LP
18The core of the plumbing system is a program called the
19.I plumber ,
20which handles all messages and dispatches and reformats them
21according to configuration rules written in a special-purpose language.
22This approach allows the contents and context of a piece of data to define how
23it is handled.
24Unlike with drag and drop or cut and paste,
25the user doesn't need to deliver the data;
26the contents of a plumbing message, as interpreted by the plumbing rules,
27determine its destination.
28.LP
29The plumber has an unusual architecture: it is a language-driven file server.
30This design has distinct advantages.
31It makes plumbing easy to add to an existing, Unix-like command environment;
32it guarantees uniform handling of inter-application messages;
33it off-loads from those applications most of the work of extracting and dispatching messages;
34and it works transparently across a network.
35.AE
36.SH
37Introduction
38.LP
39Data moves from program to program in myriad ways.
40Command-line arguments,
41shell pipe lines,
42cut and paste,
43drag and drop, and other user interface techniques all provide some form
44of interprocess communication.
45Then there are tricks associated with special domains,
46such as HTML hyperlinks or the heuristics mail readers
47use to highlight URLs embedded in mail messages.
48Some systems provide implicit ways to automate the attachment of program to data\(emthe
49best known examples are probably the resource forks in MacOS and the
50file name extension `associations' in Microsoft Windows\(embut in practice
51humans must too often carry their data from program to program.
52.LP
53Why should a human do the work?
54Usually there is one obvious thing to do with a piece of data,
55and the data itself suggests what this is.
56Resource forks and associations speak to this issue directly, but statically and narrowly and with
57little opportunity to control the behavior.
58Mechanisms with more generality,
59such as cut and paste or drag and drop, demand too much manipulation by
60the user and are (therefore) too error-prone.
61.LP
62We want a system that, given a piece of data,
63hands it to the appropriate application by default with little or no human intervention,
64while still permitting the user to override the defaults if desired.
65.LP
66The plumbing system is an attempt to address some of these issues in a single,
67coherent, central way.
68It provides a mechanism for
69formatting and sending arbitrary messages between applications,
70typically interactive programs such as text editors, web browsers, and the window system,
71under the control of a central message-handling server called the
72.I plumber .
73Interactive programs provide application-specific connections to the plumber,
74triggering with minimal user action the transfer of data or control to other programs.
75The result is similar to a hypertext system in which all the links are implicit,
76extracted automatically by examining the data and the user's actions.
77It obviates
78cut and paste and other such hand-driven interprocess communication mechanisms.
79Plumbing delivers the goods to the right place automatically.
80.SH
81Overview
82.LP
83The plumber is implemented as a Plan 9 file server [Pike93];
84programs send messages by writing them to the plumber's file
85.CW /mnt/plumb/send ,
86and receive messages by reading them from
87.I ports ,
88which are other plumber files in
89.CW /mnt/plumb .
90For example,
91.CW /mnt/plumb/edit
92is by convention the file from which a text editor reads messages requesting it to
93open and display a file for editing.
94(See Figure 1.)
95.if h .B1 10 60
96.KF
97.PS
98down
99P1: ellipse "ProgramA"
100move
101P2: ellipse "ProgramB"
102move
103P3: ellipse "ProgramC"
104right
105INVIS: box wid 1.3 invis at P2.e
106SEND: arrow from INVIS.e "\f(CWsend \fP" ""
107arrow -> right 0.2 from P1.e; spline -> right 0.2 then down 1 to SEND.w
108arrow -> right 0.2 from P2.e; arrow -> to SEND.w
109arrow -> right 0.2 from P3.e; spline -> right 0.2 then up 1 to SEND.w
110right
111PL: box height 1 "plumber" with .w at SEND.e
112A3: arrow 0.8 -> "\f(CWimage\fP" ""; arrow ->
113O3: ellipse "Viewer"
114O2: ellipse "Browser" with .s at O3.n + (0, 0.1)
115O1: ellipse "Editor" with .s at O2.n + (0, 0.1)
116O4: ellipse "Faces" with .n at O3.s + (0, -0.1)
117O5: ellipse "..." with .n at O4.s + (0, -0.1)
118right
119A1: arrow 0.8 -> "\f(CWedit\fP" "" from PL.e + (0, .4); spline -> right 0.15 then up 0.7 then to O1.w
120right
121A2: arrow 0.8 -> "\f(CWweb\fP" "" from PL.e + (0, .2);  spline -> right 0.3 then up 0.3 then to O2.w
122right
123A4: arrow 0.8 -> "\f(CWnewmail\fP" "" from PL.e + (0, -.2);  spline -> right 0.3 then down 0.3 then to O4.w
124right
125A5: arrow 0.8 -> "\f(CW...\fP" "" from PL.e + (0, -.4);  spline -> right 0.15 then down 0.7 then to O5.w
126.PE
127.IP
128.ps -1
129Figure 1. The plumber controls the flow of messages between applications.
130Programs write to the file
131.CW send
132and receive on `ports' of various names representing services such as
133.CW edit
134or
135.CW web .
136Although the figure doesn't illustrate it, some programs may both send and receive messages,
137and some ports are read by multiple applications.
138.sp
139.KE
140.if h .B2
141.LP
142The plumber takes messages from the
143.CW send
144file and interprets their contents using rules defined by
145a special-purpose pattern-action language.
146The language specifies any rewriting of the message that is to be done by the plumber
147and defines how to dispose of a message, such as by sending it to a port or
148starting a new process to handle it.
149.LP
150The behavior is best described by example.
151Imagine that the user has, in a terminal emulator window,
152just run a compilation that has failed:
153.P1
154% make
155cc -c rmstar.c
156rmstar.c:32: syntax error
157\&...
158.P2
159The user points the typing cursor somewhere in the string
160.CW rmstar.c:32:
161and executes the
162.CW plumb
163menu entry.
164This causes the terminal emulator to format a plumbing message
165containing the entire string surrounding the cursor,
166.CW rmstar:32: ,
167and to write it to
168.CW /mnt/plumb/send .
169The plumber receives this message and compares it sequentially to the various
170patterns in its configuration.
171Eventually, it will find one that breaks the string into pieces,
172.CW rmstar.c ,
173a colon,
174.CW 32 ,
175and the final colon.
176Other associated patterns verify that
177.CW rmstar.c
178is a file in the current directory of the program generating
179the message, and that
180.CW 32
181looks like a line number within it.
182The plumber rewrites the message,
183setting the data to the string
184.CW rmstar.c
185and attaching an indication that
186.CW 32
187is a line number to display.
188Finally, it sends the resulting message to the
189.CW edit
190port.
191The text editor picks up the message, opens
192.CW rmstar.c
193(if it's not already open) and highlights line 32, the location of the syntax error.
194.LP
195From the user's point of view, this process is simple: the error message appears,
196it is `plumbed', and the editor jumps to the problem.
197.LP
198Of course, there are many different ways to cause compiler messages to
199pop up the source of an error,
200but the design of the plumber addresses more general issues than the specific
201goal of shortening the compile/debug/edit cycle.
202It facilitates the general exchange of data among programs, interactive or otherwise,
203throughout the environment, and its
204architecture\(ema central, language-driven file server\(emalthough
205unusual, has distinct advantages.
206It makes plumbing easy to add to an existing, Unix-like command environment;
207it guarantees uniform handling of inter-application messages;
208it off-loads from those applications most of the work of extracting and dispatching messages;
209and it works transparently and effortlessly across a network.
210.LP
211This paper is organized bottom-up, beginning with the format of the messages
212and proceeding through the plumbing language, the handling of messages,
213and the interactive user interface.
214The last sections discuss the implications of the design
215and compare the plumbing system to other environments that
216provide similar services.
217.SH
218Format of messages
219.LP
220Since the language that controls the plumber is defined in terms of the
221contents of plumbing messages, we begin by describing their layout.
222.LP
223Plumbing messages have a fixed-format textual
224header followed by a free-format data section.
225The header consists of six lines of text, in set order,
226each specifying a property of the message.
227Any line may be blank except the last, which is the length of the data portion of the
228message, as a decimal string.
229The lines are, in order:
230.IP
231The source application, the name of the program generating the message.
232.IP
233The destination port, the name of the port to which the messages should be sent.
234.IP
235The working directory in which the message was generated.
236.IP
237The type of the data, analogous to a MIME type, such as
238.CW text
239or
240.CW image/gif .
241.IP
242Attributes of the message, given as blank-separated
243.I name\f(CW=\fPvalue
244pairs.
245The values may be quoted to protect
246blanks or quotes; values may not contain newlines.
247.IP
248The length of the data section, in bytes.
249.LP
250Here is a sample message, one that (conventionally) tells the editor to open the file
251.CW /usr/rob/src/mem.c
252and display line
25327 within it:
254.P1
255plumbtest
256edit
257/usr/rob/src
258text
259addr=27
2605
261mem.c
262.P2
263Because in general it need not be text, the data section of the message has no terminating newline.
264.LP
265A library interface simplifies the processing of messages by translating them
266to and from a data structure,
267.CW Plumbmsg ,
268defined like this:
269.P1
270.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n
271typedef struct Plumbattr Plumbattr;
272typedef struct Plumbmsg  Plumbmsg;
273
274struct Plumbmsg
275{
276	char			*src;		/* source application */
277	char			*dst;		/* destination port */
278	char			*wdir;	/* working directory */
279	char			*type;	/* type of data */
280	Plumbattr	*attr;	/* attribute list */
281	int			ndata;	/* #bytes of data */
282	char			*data;
283};
284
285struct Plumbattr
286{
287	char			*name;
288	char			*value;
289	Plumbattr	*next;
290};
291.P2
292The library also includes routines to send a message, receive a message,
293manipulate the attribute list, and so on.
294.SH
295The Language
296.LP
297An instance of the plumber runs for each user on each terminal or workstation.
298It
299begins by reading its rules from the file
300.CW lib/plumbing
301in the user's home directory,
302which in turn may use
303.CW include
304statements to interpolate macro definitions and
305rules from standard plumbing rule libraries stored in
306.CW /sys/lib/plumb .
307.LP
308The rules control the processing of messages.
309They are written in
310a pattern-action language comprising a sequence of blank-line-separated
311.I rule
312.I sets ,
313each of which contains one or more
314.I patterns
315followed by one or more
316.I actions .
317Each incoming message is compared against the rule sets in order.
318If all the patterns within a rule set succeed,
319one of the associated actions is taken and processing completes.
320.LP
321The syntax of the language is straightforward.
322Each rule (pattern or action) has three components, separated by white space:
323an
324.I object ,
325a
326.I verb ,
327and optional
328.I arguments .
329The object
330identifies a part of the message, such as
331the source application
332.CW src ), (
333or the data
334portion of the message
335.CW data ), (
336or the rule's own arguments
337.CW arg ); (
338or it is the keyword
339.CW plumb ,
340which introduces an action.
341The verb specifies an operation to perform on the object, such as the word
342.CW is ' `
343to require precise equality between the object and the argument, or
344.CW isdir ' `
345to require that the object be the name of a directory.
346.LP
347For instance, this rule set sends messages containing the names of files
348ending in
349.CW .gif ,
350.CW .jpg ,
351etc. to a program,
352.CW page ,
353to display them; it is analogous to a Windows association rule:
354.P1
355# image files go to page
356type is text
357data matches '[a-zA-Z0-9_\e-./]+'
358data matches '([a-zA-Z0-9_\e-./]+)\e.(jpe?g|gif|bit|tiff|ppm)'
359arg isfile $0
360plumb to image
361plumb client page -wi
362.P2
363(Lines beginning with
364.CW #
365are commentary.)
366Consider how this rule handles the following message, annotated down the left column for clarity:
367.P1
368.ta 10n
369\f2src\fP	plumbtest
370\f2dst\fP
371\f2wdir\fP	/usr/rob/pics
372\f2type\fP	text
373\f2attr\fP
374\f2ndata\fP	9
375\f2data\fP	horse.gif
376.P2
377The
378.CW is
379verb specifies a precise match, and the
380.CW type
381field of the message is the string
382.CW text ,
383so the first pattern succeeds.
384The
385.CW matches
386verb invokes a regular expression pattern match of the object (here
387.CW data )
388against the argument pattern.
389Both
390.CW matches
391patterns in this rule set will succeed, and in the process set the variables
392.CW $0
393to the matched string,
394.CW $1
395to the first parenthesized submatch, and so on (analogous to
396.CW & ,
397.CW \e1 ,
398etc. in
399.CW ed 's
400regular expressions).
401The pattern
402.CW arg
403.CW isfile
404.CW $0
405verifies that the named file,
406.CW horse.gif ,
407is an actual file in the directory
408.CW /usr/rob/pics .
409If all the patterns succeed, one of the actions will be executed.
410.LP
411There are two actions in this rule set.
412The
413.CW plumb
414.CW to
415rule specifies
416.CW image
417as the destination port of the message.
418By convention, the plumber mounts its services in the directory
419.CW /mnt/plumb ,
420so in this case if the file
421.CW /mnt/plumb/image
422has been opened, the message will be made available to the program reading from it.
423Note that the message does not name a port, but the rule set that matches
424the message does, and that is sufficient to dispatch the message.
425If on the other hand a message matches no rule but has an explicit port mentioned,
426that too is sufficient.
427.LP
428If no client has opened the
429.CW image
430port,
431that is, if the program
432.CW page
433is not already running, the
434.CW plumb
435.CW client
436action gives the execution script to start the application
437and send the message on its way; the
438.CW -wi
439arguments tell
440.CW page
441to create a window and to receive its initial arguments from the plumbing port.
442The process by which the plumber starts a program is described in more detail in the next section.
443.LP
444It may seem odd that there are two
445.CW matches
446rules in this example.
447The reason is related to the way the plumber can use the rules themselves
448to refine the
449.I data
450in the message, somewhat in the manner of Structural Regular Expressions [Pike87a].
451For example, consider what happens if the cursor is at the last character of
452.P1
453% make nightmare>horse.gif
454.P2
455and the user asks to plumb what the cursor is pointing at.
456The program creating the plumbing
457message\(emin this case the terminal emulator running the window\(emcan send the
458entire white-space-delimited string
459.CW nightmare>horse.gif
460or even the entire line, and the combination of
461.CW matches
462rules can determine that the user was referring to the string
463.CW horse.gif .
464The user could of course select the entire string
465.CW horse.gif ,
466but it's more convenient just to point in the general location and let the machine
467figure out what should be done.
468The process is as follows.
469.LP
470The application generating the message adds a special attribute to the message, named
471.CW click ,
472whose numerical value is the offset of the cursor\(emthe selection point\(emwithin the data string.
473This attribute tells the plumber two things:
474first, that the regular expressions in
475.CW matches
476rules should be used to identify the relevant data;
477and second, approximately where the relevant data lies.
478The plumber
479will then use the first
480.CW matches
481pattern to identify the longest leftmost match that touches the cursor, which will extract the string
482.CW horse.gif ,
483and the second pattern will then verify that that names a picture file.
484The rule set succeeds and the data is winnowed to the matching substring
485before being sent to its destination.
486.LP
487Each
488.CW matches
489pattern within a given rule set must match the same portion of the string, which
490guarantees that the rule set fails to match a string for which the
491second pattern matches only a portion.
492For instance, our example rule set should not execute if the data is the string
493.CW horse.gift ,
494and although the first pattern will match
495.CW horse.gift ,
496the second will match only
497.CW horse.gif
498and the rule set will fail.
499.LP
500The same approach of multiple
501.CW matches
502rules can be used to exclude, for instance, a terminal period from
503a file name or URL, so a file name or URL at the end of a sentence is recognized properly.
504.LP
505If a
506.CW click
507attribute is not specified, all patterns must match the entire string,
508so the user has an option:
509he or she may select exactly what data to send,
510or may instead indicate where the data is by clicking the selection button on the mouse
511and letting the machine locate the URL or image file name within the text.
512In other words,
513the user can control the contents of the message precisely when required,
514but the default, simplest action in the user interface does the right thing most of the time.
515.SH
516How Messages are Handled in the Plumber
517.LP
518An application creates a message header, fills in whatever fields it wishes to define,
519attaches the data, and writes the result to the file
520.CW send
521in the plumber's service directory,
522.CW /mnt/plumb .
523The plumber receives the message and applies the plumbing rules successively to it.
524When a rule set matches, the message is dispatched as indicated by that rule set
525and processing continues with the next message.
526If no rule set matches the message, the plumber indicates this by returning a write
527error to the application, that is, the write to
528.CW /mnt/plumb/send
529fails, with the resulting error string
530describing the failure.
531(Plan 9 uses strings rather than pre-defined numbers to describe error conditions.)
532Thus a program can discover whether a plumbing message has been sent successfully.
533.LP
534After a matching rule set has been identified, the plumber applies a series of rewriting
535steps to the message.  Some rewritings are defined by the rule set; others are implicit.
536For example, if the message does not specify a destination port, the outgoing message
537will be rewritten to identify it.
538If the message does specify the port, the rule set will only match if any
539.CW plumb
540.CW to
541action in the rule set names the same port.
542(If it matches no rule sets, but mentions a port, it will be sent there unmodified.)
543.LP
544The rule set may contain actions that explicitly rewrite components of the message.
545These may modify the attribute list or replace the data section of the message.
546Here is a sample rule set that does both.
547It matches strings of the form
548.CW plumb.h
549or
550.CW plumb.h:27 .
551If that string identifies a file in the standard C include directory,
552.CW /sys/include ,
553perhaps with an optional line number, the outgoing message
554is rewritten to contain the full path name and an attribute,
555.CW addr ,
556to hold the line number:
557.P1
558# .h files are looked up in /sys/include and passed to edit
559type is text
560data matches '([a-zA-Z0-9]+\e.h)(:([0-9]+))?'
561arg isfile /sys/include/$1
562data set /sys/include/$1
563attr add addr=$3
564plumb to edit
565.P2
566The
567.CW data
568.CW set
569rule replaces the contents of the data, and the
570.CW attr
571.CW add
572rule adds a new attribute to the message.
573The intent of this rule is to permit one to plumb an include file name in a C program
574to trigger the opening of that file, perhaps at a specified line, in the text editor.
575A variant of this rule, discussed below,
576tells the editor how to interpret syntax errors from the compiler,
577or the output of
578.CW grep
579.CW -n ,
580both of which use a fixed syntax
581.I file\f(CW:\fPline
582to identify a line of source.
583.LP
584The Plan 9 text editors interpret the
585.CW addr
586attribute as the definition of which portion of the file to display.
587In fact, the real rule includes a richer definition of the address syntax,
588so one may plumb strings such as
589.CW plumb.h:/plumbsend
590(using a regular expression after the
591.CW / )
592to pop up the declaration of a function in a C header file.
593.LP
594Another form of rewriting is that the plumber may modify the attribute list of
595the message to clarify how to handle the message.
596The primary example of this involves the treatment of the
597.CW click
598attribute, described in the previous section.
599If the message contains a
600.CW click
601attribute and the matching rule set uses it to extract the matching substring from the data,
602the plumber
603deletes the
604.CW click
605attribute and replaces the data with the matching substring.
606.LP
607Once the message is rewritten, the actions of the matching rule set are examined.
608If the rule set contains a
609.CW plumb
610.CW to
611action and the corresponding port is open\(emthat is, if a program is already reading
612from that port\(emthe message is delivered to the port.
613The application will receive the message and handle it as it sees fit.
614If the port is not open, a
615.CW plumb
616.CW start
617or
618.CW plumb
619.CW client
620action will start a new program to handle the message.
621.LP
622The
623.CW plumb
624.CW start
625action is the simpler: its argument specifies a command to run
626instead of passing on the message; the message is discarded.
627Here for instance is a rule that, given the process id (pid) of an existing process,
628starts the
629.CW acid
630debugger [Wint94] in a new window to examine that process:
631.P1
632# processes go to acid (assuming strlen(pid) >= 2)
633type is text
634data matches '[a-zA-Z0-9.:_\e-/]+'
635data matches '[0-9][0-9]+'
636arg isdir /proc/$0
637plumb start window acid $0
638.P2
639(Note the use of multiple
640.CW matches
641rules to avoid misfires from strings like
642.CW party.1999 .)
643The
644.CW arg
645.CW isdir
646rule checks that the pid represents a running process (or broken one; Plan 9 does not create
647.CW core
648files but leaves broken processes around for debugging) by checking that the process file
649system has a directory for that pid [Kill84].
650Using this rule, one may plumb the pid string printed by the
651.CW ps
652command or by the operating system when the program breaks;
653the debugger will then start automatically.
654.LP
655The other startup action,
656.CW plumb
657.CW client ,
658is used when a program will read messages from the plumbing port.
659For example,
660text editors can read files specified as command arguments, so one could use a
661.CW plumb
662.CW start
663rule to begin editing a file.
664If, however, the editor will read messages from the
665.CW edit
666plumbing port, letting it read the message
667from the port insures that it uses other information in the message,
668such as the line number to display.
669The
670.CW plumb
671.CW client
672action is therefore like
673.CW plumb
674.CW start ,
675but keeps the message around for delivery when the application opens the port.
676Here is the full rule set to pass a regular file to the text editor:
677.P1
678# existing files, possibly tagged by address, go to editor
679type is text
680data matches '([.a-zA-Z0-9_/\e-]*[a-zA-Z0-9_/\e-])('$addr')?'
681arg isfile $1
682data set $1
683attr add addr=$3
684plumb to edit
685plumb client window $editor
686.P2
687If the editor is already running, the
688.CW plumb
689.CW to
690rule causes it to receive the message on the port.
691If not,
692the command
693.CW window "" `
694.CW $editor '
695will create a new window (using the Plan 9 program
696.CW window )
697to run the editor, and once that starts it will open the
698.CW edit
699plumbing port as usual and discover this first message already waiting.
700.LP
701The variables
702.CW $editor
703and
704.CW $addr
705in this rule set
706are macros defined in the plumbing rules file; they specify the name of the user's favorite text editor
707and a regular expression
708that matches that editor's address syntax, such as line numbers and patterns.
709This rule set lives in a library of shared plumbing rules that
710users' private rules can build on,
711so the rule set needs to be adaptable to different editors and their address syntax.
712The macro definitions for Acme and Sam [Pike94,Pike87b] look like this:
713.P1
714editor=acme
715# or editor=sam
716addrelem='((#?[0-9]+)|(/[A-Za-z0-9_\e^]+/?)|[.$])'
717addr=:($addrelem([,;+\e-]$addrelem)*)
718.P2
719.LP
720Finally, the application reads the message from the appropriate port, such as
721.CW /mnt/plumb/edit ,
722unpacks it, and goes to work.
723.SH
724Message Delivery
725.LP
726In summary, a message is delivered by writing it to the
727.CW send
728file and having the plumber, perhaps after some rewriting, send it to the destination
729port or start a new application to handle it.
730If no destination can be found by the plumber, the original write to the
731.CW send
732file will fail, and the application will know the message could not be delivered.
733.LP
734If multiple applications are reading from the destination port, each will receive
735an identical copy of the message; that is, the plumber implements fan-out.
736The number of messages delivered is equal to the number of clients that have
737opened the destination port.
738The plumber queues the messages and makes sure that each application that opened
739the port before the message was written gets exactly one copy.
740.LP
741This design minimizes blocking in the sending applications, since the write to the
742.CW send
743file can complete as soon as the message has been queued for the appropriate port.
744If the plumber waited for the message to be read by the recipient, the sender could
745block unnecessarily.
746Unfortunately, this design also means that there is no way for a sender to know when
747the message has been handled; in fact, there are cases when
748the message will not be delivered at all, such as if the recipient exits while there are
749still messages in the queue.
750Since the plumber is part of a user interface, and not
751an autonomous message delivery system,
752the decision was made to give the
753non-blocking property priority over reliability of message delivery.
754In practice, this tradeoff has worked out well:
755applications almost always know when a message has failed to be delivered (the
756.CW write
757fails because no destination could be found),
758and those occasions when the sender believes incorrectly that the message has been delivered
759are both extremely rare and easily recognized by the user\(emusually because the recipient
760application has exited.
761.SH
762The Rules File
763.LP
764The plumber begins execution by reading the user's startup plumbing rules file,
765.CW lib/plumbing .
766Since the plumber is implemented as a file server, it can also present its current rules
767as a dynamic file, a design that provides an easily understood way to maintain the rules.
768.LP
769The file
770.CW /mnt/plumb/rules
771is the text of the rule set the plumber is currently using,
772and it may be edited like a regular file to update those rules.
773To clear the rules, truncate that file;
774to add a new rule set, append to it:
775.P1
776% echo 'type is text
777data is self-destruct
778plumb start rm -rf $HOME' >> /mnt/plumb/rules
779.P2
780This rule set will take effect immediately.
781If it has a syntax error, the write will fail with an error message from the plumber,
782such as `malformed rule' or 'undefined verb'.
783.LP
784To restore the plumber to its startup configuration,
785.P1
786% cp /usr/$user/lib/plumbing /mnt/plumb/rules
787.P2
788For more sophisticated changes,
789one can of course use a regular text editor to modify
790.CW /mnt/plumb/rules .
791.LP
792This simple way of maintaining an active service could profitably be adopted by other systems.
793It avoids the need to reboot, to update registries with special tools, or to send asynchronous signals
794to critical programs.
795.SH
796The User Interface
797.LP
798One unusual property of the plumbing system is that
799the user interface that programs provide to access it can vary considerably, yet
800the result is nonetheless a unifying force in the environment.
801Shells talk to editors, image viewers, and web browsers; debuggers talk to editors;
802editors talk to themselves; and the window system talks to everybody.
803.LP
804The plumber grew out of some of the ideas of the Acme editor/window-system/user interface [Pike94],
805in particular its `acquisition' feature.
806With a three-button mouse, clicking the right button in Acme on a piece of text tells Acme to
807get the thing being pointed to.
808If it is a file name, open the file;
809if it is a directory, open a viewer for its contents;
810if a line number, go to that line;
811if a regular expression, search for it.
812This one-click access to anything describable textually was very powerful but had several
813limitations, of which the most important were that Acme's rules for interpreting the
814text (that is, the implicit hyperlinks) were hard-wired and inflexible, and
815that they only applied to and within Acme itself.
816One could not, for example, use Acme's power to open an image file, since Acme is
817a text-only system.
818.LP
819The plumber addresses these limitations, even with Acme itself:
820Acme now uses the plumber to interpret the right button clicks for it.
821When the right button is clicked on some text,
822Acme constructs a plumbing message much as described above,
823using the
824.CW click
825attribute and the white-space-delimited text surrounding the click.
826It then writes the message to the plumber; if the write succeeds, all is well.
827If not, it falls back to its original, internal rules, which will result in a context search
828for the word within the current document.
829.LP
830If the message is sent successfully, the recipient is likely to be Acme itself, of course:
831the request may be to open a file, for example.
832Thus Acme has turned the plumber into an external component of its own operation,
833while expanding the possibilities; the operation might be to start an image viewer to
834open a picture file, something Acme cannot do itself.
835The plumber expands the power of Acme's original user interface.
836.LP
837Traditional menu-driven programs such as the text editor Sam [Pike87b] and the default
838shell window of the window
839system
840.CW 8½
841[Pike91] cannot dedicate a mouse button solely to plumbing, but they can certainly
842dedicate a menu entry.
843The editing menu for such programs now contains an entry,
844.CW plumb ,
845that creates a plumbing message using the current selection.
846(Acme manages to send a message by clicking on the text with one button;
847other programs require a click with the select button and then a menu operation.)
848For example, after this happens in a shell window:
849.P1
850% make
851cc -c shaney.c
852shaney.c:232: i undefined
853\&...
854.P2
855one can click anywhere on the string
856.CW shaney.c:232 ,
857execute the
858.CW plumb
859menu entry, and have line 232 appear in the text editor, be it Sam or Acme\(emwhichever has the
860.CW edit
861port open.
862(If this were an Acme shell window, it would be sufficient to right-click on the string.)
863.LP
864[An interesting side line is how the window system knows what directory the
865shell is running in; in other words, what value to place in the
866.CW wdir
867field of the plumb message.
868Recall that
869.CW 8½
870is, like many Plan 9 programs, a file server.
871It now serves a new file,
872.CW /dev/wdir ,
873that is private to each window.
874Programs, in particular the
875Plan 9 shell,
876.CW rc ,
877can write that file to inform the window system of its current directory.
878When a
879.CW cd
880command is executed in an interactive shell,
881.CW rc
882updates the contents of
883.CW /dev/wdir
884and plumbing can proceed with local file names.]
885.LP
886Of course, users can plumb image file names, process ids, URLs, and other items\(emany string
887whose syntax and disposition are defined in the plumbing rules file.
888An example of how the pieces fit together is the way Plan 9 now handles mail, particularly
889MIME-encoded messages.
890.LP
891When a new mail message arrives, the mail receiver process sends a plumbing message to the
892.CW newmail
893port, which notifies any interested process that new mail is here.
894The plumbing message contains information about the mail, including
895its sender, date, and current location in the file system.
896The interested processes include a program,
897.CW faces ,
898that gives a graphical display of the mail box using
899faces to represent the senders of messages [PiPr85],
900as well as interactive mail programs such as the Acme mail viewer [Pike94].
901The user can then click on the face that appears, and the
902.CW faces
903program will send another plumbing message, this time to the
904.CW showmail
905port.
906Here is the rule for that port:
907.P1
908# faces -> new mail window for message
909type is text
910data matches '[a-zA-Z0-9_\e-./]+'
911data matches '/mail/fs/[a-zA-Z0-9/]+/[0-9]+'
912plumb to showmail
913plumb start window edmail -s $0
914.P2
915If a program, such as the Acme mail reader, is reading that port, it will open a new window
916in which to display the message.
917If not, the
918.CW plumb
919.CW start
920rule will create a new window and run
921.CW edmail ,
922a conventional mail reading process, to examine it.
923Notice how the plumbing connects the components of the interface together the same way
924regardless of which components are actually being used to view mail.
925.LP
926There is more to the mail story.
927Naturally, mail boxes in Plan 9 are treated as little file systems, which are synthesized
928on demand by a special-purpose file server that takes a flat mail box file and converts
929it into a set of directories, one per message, with component files containing the header,
930body, MIME information, and so on.
931Multi-part MIME messages are unpacked into multi-level directories, like this:
932.P1
933% ls -l /mail/fs/mbox/25
934d-r-xr-xr-x M 20 rob rob     0 Nov 21 13:06 /mail/fs/mbox/25/1
935d-r-xr-xr-x M 20 rob rob     0 Nov 21 13:06 /mail/fs/mbox/25/2
936--r--r--r-- M 20 rob rob 28678 Nov 21 13:06 /mail/fs/mbox/25/body
937--r--r--r-- M 20 rob rob     0 Nov 21 13:06 /mail/fs/mbox/25/cc
938\&...
939% mail
94025 messages
941: 25
942From: presotto
943Date: Sun Nov 21 13:05:51 EST 1999
944To: rob
945
946Check this out.
947
948===> 2/ (image/jpeg) [inline]
949	/mail/fs/mbox/25/2/fabio.jpg
950:
951.P2
952Since the components are all (synthetic) files, the user can plumb the pieces
953to view embedded pictures, URLs, and so on.
954Note that the mail program can plumb the contents of
955.CW inline
956attachments automatically, without user interaction;
957in other words, plumbing lets the mailer handle multimedia data
958without itself interpreting it.
959.LP
960At a more mundane level, a shell command,
961.CW plumb ,
962can be used to send messages:
963.P1
964% cd /usr/rob/src
965% plumb mem.c
966.P2
967will send the appropriate message to the
968.CW edit
969port.
970A surprising use of the
971.CW plumb
972command is in actions within the plumbing rules file.
973In our lab, we commonly receive Microsoft Word documents by mail,
974but we do not run Microsoft operating systems on our machines so we cannot
975view them without at least rebooting.
976Therefore, when a Word document arrives in mail, we could plumb the
977.CW .doc
978file but the text editor could not decode it.
979However, we have a program,
980.CW doc2txt ,
981that decodes the Word file format to extract and format the embedded text.
982The solution is to use
983.CW plumb
984in a
985.CW plumb
986.CW start
987action to invoke
988.CW doc2txt
989on
990.CW .doc
991files and synthesize a plain text file:
992.P1
993# rule set for microsoft word documents
994type is text
995data matches '[a-zA-Z0-9_\e-./]+'
996data matches '([a-zA-Z0-9_\e-./]+)\e.doc'
997arg isfile $0
998plumb start doc2txt $data | \e
999    plumb -i -d edit -a action=showdata -a filename=$0
1000.P2
1001The arguments to
1002.CW plumb
1003tell it to take standard input as its data rather than the text of the arguments
1004.CW -i ), (
1005define the destination port
1006.CW -d "" (
1007.CW edit ),
1008and set a conventional attribute so the editor knows to show the message data
1009itself rather than interpret it as a file name
1010.CW -a "" (
1011.CW action=showdata )
1012and provide the original file name
1013.CW -a "" (
1014.CW filename=$0 ).
1015Now when a user plumbs a
1016.CW .doc
1017file the plumbing rules run a process to extract the text and send it as a
1018temporary file to the editor for viewing.
1019It's imperfect, but it's easy and it beats rebooting.
1020.LP
1021Another simple example is a rule that turns man pages into hypertext.
1022Manual page entries of the form
1023.CW plumber(1)
1024can be clicked on to pop up a window containing the formatted `man page'.
1025That man page will in turn contain more such citations, which will also be clickable.
1026The rule is a little like that for Word documents:
1027.P1
1028# man index entries are synthesized
1029type is text
1030data matches '([a-zA-Z0-9_\e-./]+)\e(([0-9])\e)'
1031plumb start man $2 $1 | \e
1032    plumb -i -d edit -a action=showdata -a filename=/man/$1($2)
1033.P2
1034.LP
1035There are many other inventive uses of plumbing.
1036One more should give some of the flavor.
1037We have a shell script,
1038.CW src ,
1039that takes as argument the name of an executable binary file.
1040It examines the symbol table of the binary to find the source file
1041from which it was compiled.
1042Since the Plan 9 compilers place full source path names in the symbol table,
1043.CW src
1044can discover the complete file name.
1045That is then passed to
1046.CW plumb ,
1047complete with the line number to find the
1048symbol
1049.CW main .
1050For example,
1051.P1
1052% src plumb
1053.P2
1054is all it takes to pop up an editor window on the
1055.CW main
1056routine of the
1057.CW plumb
1058command, beginning at line 39 of
1059.CW /sys/src/cmd/plumb/plumb.c .
1060Like most uses of plumbing,
1061this is not a breakthrough in functionality, but it is a great convenience.
1062.SH
1063Why This Architecture?
1064.LP
1065The design of the plumbing system is peculiar:
1066a centralized language-based file server does most of the work,
1067while compared to other systems the applications themselves
1068contribute relatively little.
1069This architecture is deliberate, of course.
1070.LP
1071That the plumber's behavior is derived from a linguistic description
1072gives the system great flexibility and dynamism\(emrules can be added
1073and changed at will, without rebooting\(embut the existence of a central library of rules
1074ensures that, for most users, the environment behaves in well-established ways.
1075.LP
1076That the plumber is a file server is perhaps the most unusual aspect of its design,
1077but is also one of the most important.
1078Messages are passed by regular I/O operations on files, so no extra technology
1079such as remote procedure call or request brokers needs to be provided;
1080messages are transmitted by familiar means.
1081Almost every service in Plan 9 is a file server, so services can be exported
1082trivially using the system's remote file system operations [Pike93].
1083The plumber is no exception;
1084plumbing messages pass routinely across the network to remote applications without
1085any special provision,
1086in contrast to some commercial IPC mechanisms that become
1087significantly more complex when they involve multiple machines.
1088As I write this, my window system is talking to applications running on three
1089different machines, but they all share a single instance of the plumber and so
1090can interoperate to integrate my environment.
1091Plan 9 uses a shared file name space
1092to combine multiple networked machines\(emcompute servers,
1093file servers, and interactive workstations\(eminto a single
1094computing environment; plumbing's design as a file server
1095is a natural by-product of, and contributor to, the overall system architecture
1096[Pike92].
1097.LP
1098The centrality of the plumber is also unusual.
1099Other systems tend to let the applications determine where messages will go;
1100consider mail readers that recognize and highlight URLs in the messages.
1101Why should just the mail readers do this, and why should they just do it for URLs?
1102(Acme was guilty of similar crimes.)
1103The plumber, by removing such decisions to a central authority,
1104guarantees that all applications behave the same and simultaneously
1105frees them all from figuring out what's important.
1106The ability for the plumber to excerpt useful data from within a message
1107is critical to the success of this model.
1108.LP
1109The entire system is remarkably small.
1110The plumber itself is only about two thousand lines of C code.
1111Most applications work fine in a plumbing environment without knowing about it at all;
1112some need trivial changes such as to standardize their error output;
1113a few need to generate and receive plumbing messages.
1114But even to add the ability to send and receive messages in a program such as text editor is short work,
1115involving typically a few dozen lines of code.
1116Plumbing fits well into the existing environment.
1117.LP
1118But plumbing is new and it hasn't been pushed far enough yet.
1119Most of the work so far has been with textual messages, although
1120the underlying system is capable of handling general data.
1121We plan to reimplement some of the existing data movement operations,
1122such as cut and paste or drag and drop, to use plumbing as their exchange mechanism.
1123Since the plumber is a central message handler, it is an obvious place to store the `clipboard'.
1124The clipboard could be built as a special port that holds onto messages rather than
1125deleting them after delivery.
1126Since the clipboard would then be holding a plumbing
1127message rather than plain text, as in the current Plan 9 environment,
1128it would become possible to cut and paste arbitrary data without
1129providing new mechanism.
1130In effect, we would be providing a new user interface to the existing plumbing facilities.
1131.LP
1132Another possible extension is the ability to override plumbing operations interactively.
1133Originally, the plan was to provide a mechanism, perhaps a pop-up menu, that one could
1134use to direct messages, for example to send a PostScript file to the editor rather than the
1135PostScript viewer by naming an explicit destination in the message.
1136Although this deficiency should one day be addressed, it should be done without
1137complicating the interface for invoking the default behavior.
1138Meanwhile, in practice the default behavior seems to work very well in practice\(emas it
1139must if plumbing is to be successful\(emso the lack of
1140overrides is not keenly felt.
1141.SH
1142Comparison with Other Systems
1143.LP
1144The ideas of the plumbing system grew from an
1145attempt to generalize the way Acme acquires files and data.
1146Systems further from that lineage also share some properties with plumbing.
1147Most, however, require explicit linking or message passing rather than
1148plumbing's implicit, context-based pattern matching, and none
1149has the plumber's design of a language-based file server.
1150.LP
1151Reiss's FIELD system [Reis95] probably comes the closest to providing the facilities of the plumber.
1152It has a central message-passing mechanism that connects applications together through
1153a combination of a library and a pattern-matching central message dispatcher that handles
1154message send and reply.
1155The main differences between FIELD's message dispatcher and the plumber are first
1156that the plumber is based on a special-purpose language while the FIELD
1157system uses an object-oriented library, second that the plumber has no concept
1158of a reply to a message, and finally that the FIELD system
1159has no concept of port.
1160But the key distinction is probably in the level of use.
1161In FIELD, the message dispatcher is a critical integrating force of the underlying
1162programming environment, handling everything from debugging events to
1163changing the working directory of a program.
1164Plumbing, by contrast, is intended primarily for integrating the user interface
1165of existing tools; it is more modest and very much simpler.
1166The central advantage of the plumber is its convenience and dynamism;
1167the FIELD system does not share the ease with which
1168message dispatch rules can be added or modified.
1169.LP
1170The inspiration for Acme was
1171the user interface to the object-oriented Oberon system [WiGu92].
1172Oberon's user interface interprets mouse clicks on strings such as
1173.CW Obj.meth
1174to invoke calls to the method
1175.CW meth
1176of the object
1177.CW Obj .
1178This was the starting point for Acme's middle-button execution [Pike94],
1179but nothing in Oberon is much like Acme's right-button `acquisition',
1180which was the starting point for the plumber.
1181Oberon's implicit method-based linking is not nearly as general as the pattern-matched
1182linking of the plumber, nor does its style of user-triggered method call
1183correspond well to the more general idea of inter-application communication
1184of plumbing messages.
1185.LP
1186Microsoft's OLE interface is another relative.
1187It allows one application to
1188.I embed
1189its own data within another's,
1190for example to place an Excel spreadsheet within a Frame document;
1191when Frame needs to format the page, it will start Excel itself, or at least some of its
1192DLLs, to format the spreadsheet.
1193OLE data can only be understood by the application that created it;
1194plumbing messages, by contrast, contain arbitrary data with a rigidly formatted header
1195that will be interpreted by the pattern matcher and the destination application.
1196The plumber's simplified message format may limit its
1197flexibility but makes messages easy and efficient to dispatch and to interpret.
1198At least for the cut-and-paste style of exchange OLE encourages,
1199plumbing gives up some power in return for simplicity, while avoiding
1200the need to invoke a vestigial program (if Excel can be called a vestige) every time
1201the pasted data is examined.
1202Plumbing is also better suited to
1203other styles of data exchange, such as connecting compiler errors to the
1204text editor.
1205.LP
1206The Hyperbole [Wein] package for Emacs adds hypertext facilities to existing documents.
1207It includes explicit links and, like plumbing, a rule-driven way to form implicit links.
1208Since Emacs is purely textual, like Acme, Hyperbole does not easily extend to driving
1209graphical applications, nor does it provide a general interprocess communication method.
1210For instance, although Hyperbole provides some integration for mail applications,
1211it cannot provide the glue that allows a click on a face icon in an external program to open a
1212mail message within the viewer.
1213Moreover, since it is not implemented as a file server,
1214Hyperbole does not share the advantages of that architecture.
1215.LP
1216Henry's
1217.CW error
1218program in 4BSD echoes a small but common use of plumbing.
1219It takes the error messages produced by a compiler and drives a text editor
1220through the steps of looking at each one in turn; the notion is to quicken the
1221compile/edit/debug cycle.
1222Similar results are achieved in EMACS by writing special M-LISP
1223macros to parse the error messages from various compilers.
1224Although for this particular purpose they may be more convenient than plumbing,
1225these are specific solutions to a specific problem and lack plumbing's generality.
1226.LP
1227Of course, the resource forks in MacOS and the association rules for
1228file name extensions in Windows also provide some of the functionality of
1229the plumber, although again without the generality or dynamic nature.
1230.LP
1231Closer to home, Ousterhout's Tcl (Tool Command Language) [Oust90]
1232was originally designed to embed a little command interpreter
1233in each application to control interprocess communication and
1234provide a level of integration.
1235Plumbing, on the other hand, provides minimal support within
1236the application, offloading most of the message handling and all the
1237command execution to the central plumber.
1238.LP
1239The most obvious relative to plumbing is perhaps the hypertext links of a web browser.
1240Plumbing differs by synthesizing
1241the links on demand.
1242Rather than constructing links within a document as in HTML,
1243plumbing uses the context of a button click to derive what it should link to.
1244That the rules for this decision can be modified dynamically gives it a more
1245fluid feel than a standard web browsing world.
1246One possibility for future work is to adapt a web browser to use
1247plumbing as its link-following engine, much as Acme used plumbing to offload
1248its acquisition rules.
1249This would connect the web browser to the existing tools, rather than the
1250current trend in most systems of replacing the tools by a browser.
1251.LP
1252Each of these prior systems\(emand there are others, e.g. [Pasa93, Free93]\(emaddresses
1253a particular need or subset of the
1254issues of system integration.
1255Plumbing differs because its particular choices were different.
1256It focuses on two key issues:
1257centralizing and automating the handling of interprocess communication
1258among interactive programs,
1259and maximizing the convenience (or minimizing the trouble) for the human user
1260of its services.
1261Moreover, the plumber's implementation as a file server, with messages
1262passed over files it controls,
1263permits the architecture to work transparently across a network.
1264None of the other systems discussed here integrates distributed systems
1265as smoothly as local ones without the addition of significant extra technology.
1266.SH
1267Discussion
1268.LP
1269There were a few surprises during the development of plumbing.
1270The first version of plumbing was done for the Inferno system [Dorw97a,Dorw97b],
1271using its file-to-channel mechanism to mediate the IPC.
1272Although it was very simple to build, it encountered difficulties because
1273the plumber was too disconnected from its clients; in particular, there was
1274no way to discover whether a port was in use.
1275When plumbing was implemented afresh for Plan 9, it was provided through a true file server.
1276Although this was much more work, it paid off handsomely.
1277The plumber now knows whether a port is open, which makes it easy to decide whether
1278a new program must be started to handle a message,
1279and the ability to edit the rules file dynamically is a major advantage.
1280Other advantages arise from the file-server design,
1281such as
1282the ease of exporting plumbing ports across the network to remote machines
1283and the implicit security model a file-based interface provides: no one has
1284permission to open my private plumbing files.
1285.LP
1286On the other hand, Inferno was an all-new environment and the user interface for plumbing was
1287able to be made uniform for all applications.
1288This was impractical for Plan 9, so more
1289.I "ad hoc
1290interfaces had to be provided for that environment.
1291Yet even in Plan 9 the advantages of efficient,
1292convenient, dynamic interprocess communication outweigh the variability of
1293the user interface.
1294In fact, it is perhaps a telling point that the system works well for a variety of interfaces;
1295the provision of a central, convenient message-passing
1296service is a good idea regardless of how the programs use it.
1297.LP
1298Plumbing's rule language uses only regular expressions and a few special
1299rules such as
1300.CW isfile
1301for matching text.
1302There is much more that could be done.  For example, in the current system a JPEG
1303file can be recognized by a
1304.CW .jpg
1305suffix but not by its contents, since the plumbing language has no facility
1306for examining the
1307.I contents
1308of files named in its messages.
1309To address this issue without adding more special rules requires rethinking
1310the language itself.
1311Although the current system seems a good balance of complexity
1312and functionality,
1313perhaps a richer, more general-purpose language would
1314permit more exotic applications of the plumbing model.
1315.LP
1316In conclusion, plumbing adds an effective, easy-to-use inter-application
1317communication mechanism to the Plan 9
1318user interface.
1319Its unusual design as a language-driven file server makes it easy to add
1320context-dependent, dynamically interpreted, general-purpose hyperlinks
1321to the desktop, for both existing tools and new ones.
1322.SH
1323Acknowledgements
1324.LP
1325Dave Presotto wrote the mail file system and
1326.CW edmail .
1327He, Russ Cox, Sape Mullender, and Cliff Young influenced the design, offered useful suggestions,
1328and suffered early versions of the software.
1329They also made helpful comments on this paper, as did Dennis Ritchie and Brian Kernighan.
1330.SH
1331References
1332.LP
1333[Dorw97a]
1334Sean Dorward, Rob Pike, David Leo Presotto, Dennis M. Ritchie,
1335Howard W. Trickey, and Philip Winterbottom,
1336``Inferno'',
1337.I "Proceedings of the IEEE Compcon 97 Conference" ,
1338San Jose, 1997, pp. 241-244.
1339.LP
1340[Dorw97b]
1341Sean Dorward, Rob Pike, David Leo Presotto, Dennis M. Ritchie,
1342Howard W. Trickey, and Philip Winterbottom,
1343``The Inferno Operating System'',
1344.I "Bell Labs Technical Journal" ,
1345.B 2 ,
13461, Winter, 1997.
1347.LP
1348[Free93]
1349FreeBSD,
1350Syslog configuration file manual
1351.I syslog.conf (0).
1352.LP
1353[Kill84]
1354T. J. Killian,
1355``Processes as Files'',
1356.I "Proceedings of the Summer 1984 USENIX Conference" ,
1357Salt Lake City, 1984, pp. 203-207.
1358.LP
1359[Oust90]
1360John K. Ousterhout,
1361``Tcl: An Embeddable Command Languages'',
1362.I "Proceedings of the Winter 1990 USENIX Conference" ,
1363Washington, 1990, pp. 133-146.
1364.LP
1365[Pasa93]
1366Vern Paxson and Chris Saltmarsh,
1367"Glish: A User-Level Software Bus for Loosely-Coupled Distributed Systems" ,
1368.I "Proceedings of the Winter 1993 USENIX Conference" ,
1369San Diego, 1993, pp. 141-155.
1370.LP
1371[Pike87a]
1372Rob Pike,
1373``Structural Regular Expressions'',
1374.I "EUUG Spring 1987 Conference Proceedings" ,
1375Helsinki, May 1987, pp. 21-28.
1376.LP
1377[Pike87b]
1378Rob Pike,
1379``The Text Editor sam'',
1380.I "Software - Practice and Experience" ,
1381.B 17 ,
13825, Nov. 1987, pp. 813-845.
1383.LP
1384[Pike91]
1385Rob Pike,
1386``8½, the Plan 9 Window System'',
1387.I "Proceedings of the Summer 1991 USENIX Conference" ,
1388Nashville, 1991, pp. 257-265.
1389.LP
1390[Pike93]
1391Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom,
1392``The Use of Name Spaces in Plan 9'',
1393.I "Operating Systems Review" ,
1394.B 27 ,
13952, April 1993, pp. 72-76.
1396.LP
1397[Pike94]
1398Rob Pike,
1399``Acme: A User Interface for Programmers'',
1400.I "Proceedings of the Winter 1994 USENIX Conference",
1401San Francisco, 1994, pp. 223-234.
1402.LP
1403[PiPr85]
1404Rob Pike and Dave Presotto,
1405``Face the Nation'',
1406.I "Proceedings of the USENIX Summer 1985 Conference" ,
1407Portland, 1985, pg. 81.
1408.LP
1409[Reis95]
1410Steven P. Reiss,
1411.I "The FIELD Programming Environment: A Friendly Integrated Environment for Learning and Development" ,
1412Kluwer, Boston, 1995.
1413.LP
1414[Wein]
1415Bob Weiner,
1416.I "Hyperbole User Manual" ,
1417.CW http://www.cs.indiana.edu/elisp/hyperbole/hyperbole_1.html
1418.LP
1419[Wint94]
1420Philip Winterbottom,
1421``ACID: A Debugger based on a Language'',
1422.I "Proceedings of the USENIX Winter Conference" ,
1423San Francisco, CA, 1994.
1424.LP
1425[WiGu92]
1426Niklaus Wirth and Jurg Gutknecht,
1427.I "Project Oberon: The Design of an Operating System and Compilers" ,
1428Addison-Wesley, Reading, 1992.
1429
1430