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