1 % The Muddle Programming Language
7 MIT Technical Report 293
9 Laboratory for Computer Science\
10 Massachusetts Institute of Technology\
11 545 Technology Square\
12 Cambridge, Massachusetts 02139
17 This document is free of known copyright restrictions.
22 The Muddle programming language began existence in late 1970 as a
23 successor to Lisp (Moon, 1974), a candidate vehicle for the Dynamic
24 Modeling System, and a possible base for implementation of Planner
25 (Hewitt, 1969). The original design goals included an interactive
26 integrated environment for programming, debugging, loading, and
27 editing: ease in learning and use; facilities for structured, modular,
28 shared programs; extensibility of syntax, data types and operators:
29 data-type checking for debugging and optional data-type declarations
30 for compiled efficiency; associative storage, coroutining, and
31 graphics. Along the way to reaching those goals, it developed flexible
32 input/output (including the ARPA Network), and flexible interrupt and
33 signal handling. It now serves as a base for software prototyping,
34 research, development, education, and implementation of the majority
35 of programs at MIT-DMS: a library of sharable modules, a coherent user
36 interface, special research projects, autonomous daemons, etc.
38 This document was originally intended to be a simple low-level
39 introduction to Muddle. It has, however, acquired a case of
40 elephantiasis and now amounts to a discursive description of the whole
41 interpreter, as realized in Muddle release numbers 55 (ITS version)
42 and 105 (Tenex and Tops-20 versions). (Significant changes from the
43 previous edition are marked in the margin.) A low-level introduction
44 may still be had by restricting one's attention to specially-marked
45 sections only. The scope of the document is confined as much as
46 possible to the interpreter itself. Other adjuncts (compiler,
47 assembler, pre-loaded user programs, library) are mentioned as little
48 as possible, despite their value in promoting the language seen by a
49 user from "basic survival" to "comfortable living". Indeed, Muddle
50 could not fulfill the above design goals without the compiler,
51 assembler, structure editor, control-stack printer, context printer,
52 pretty-printer, dynamic loader, and library system -- all of which are
53 not part of the interpreter but programs written in Muddle and
54 symbiotic with one another. Further information on these adjuncts can
55 be found in Lebling's (1979) document.
60 I was not a member of the original group which labored for two years
61 in the design and initial implementation of Muddle; that group was
62 composed principally of Gerald Sussman, Carl Hewit, Chris Reeve, Dave
63 Cressey, and later Bruce Daniels. I would therefore like to take this
64 opportunity to thank my Muddle mentors, chiefly Chris Reeve and Bruce
65 Daniels, for remaining civil through several months of verbal
66 badgering. I believe that I learned more than "just another
67 programming language" in learning Muddle, and I am grateful for this
68 opportunity to pass on some of that knowledge. What I cannot pass on
69 is the knowledge gained by using Muddle as a system; that I can only
72 For editing the content of this document and correcting some
73 misconceptions, I would like to thank Chris Reeve, Bruce Daniels, and
74 especially Gerald Sussman, one of whose good ideas I finally did use.
79 Since Greg left the fold, I have taken up the banner and updated his
80 document. The main sources for small revisions have been the on-line
81 file of changes to Muddle, for which credit goes to Neal Ryan as well
82 as Reeve and Daniels, and the set of on-line abstracts for interpreter
83 Subroutines, contributed by unnamed members of the Programming
84 Technology Division. Some new sections were written almost entirely by
85 others: Dave Lebling wrote chapter 14 and appendix 3, Jim Michener
86 section 14.3, Reeve chapter 19 and appendix 1, Daniels and Reeve
87 appendix 2. Brian Berkowitz section 22.7, Tak To section 17.2.2, and
88 Ryan section 17.1.3. Sue Pitkin did the tedious task of marking
89 phrases in the manuscript for indexing. Pitts Jarvis and Jack Haverty
90 advised on the use of PUB and the XGP. Many PTD people commented
91 helpfully on a draft version.
93 My task has been to impose some uniformity and structure on these
94 diverse resources (so that the result sounds less like a dozen hackers
95 typing at a dozen terminals for a dozen days) and to enjoy some of the
96 richness of Muddle from the inside. I especially thank Chris Reeve
97 ("the oracle") for the patience to answer questions and resolve
98 doubts, as he no doubt as done innumerable times before.
103 This work was supported by the Advanced Research Projects Agency of
104 the Department of Defense and was monitored by the Office of Naval
105 Research under contract N00014-75-C-0661.
107 This document was prepared using [the PUB
108 system](http://www.nomodes.com/pub_manual.html) (originally from the
109 Stanford Artificial Intelligence Laboratory) and printed on the Xerox
110 Graphics Printer of the M.I.T. Artificial Intelligence Laboratory.
115 Trying to explain Muddle to an uninitiate is somewhat like trying to
116 untie a Gordian knot. Whatever topic one chooses to discuss first,
117 full discussion of it appears to imply discussion of everything else.
118 What follows is a discursive presentation of Muddle in an order
119 apparently requiring the fewest forward references. It is not perfect
120 in that regard; however, if you are patient and willing to accept a
121 few, stated things as "magic" until they can be explained better, you
122 will probably not have too many problems understanding what is going
125 There are no "practice problems"; you are assumed to be learning
126 Muddle for some purpose, and your work in achieving that purpose will
127 be more useful and motivated than artificial problems. In several
128 cases, the examples contain illustrations of important points which
129 are not covered in the text. Ignore examples as your peril.
131 This document does not assume knowledge of any specific programming
132 language on the \[sic\] your part. However, "computational literacy"
133 is assumed: you should have written at least one program before. Also
134 very little familiarity is assumed with the interactive time-sharing
135 operating systems under which Muddle runs -- ITS, Tenex, and Tops-20
136 -- namely just file and user naming conventions.
140 Sections marked \[1\] are recommended for any uninitiate's first
141 reading, in lieu of a separate introduction for Muddle. \[On first
142 reading, text within brackets like these should be ignored.\]
144 Most specifically indicated examples herein are composed of pairs of
145 lines. The first line of a pair, the input, always ends in `$` (which
146 is how the ASCII character ESC is represented, and which always
147 represents it). The second line is the result of Muddle's groveling
148 over the first. If you were to type all the first lines at Muddle, it
149 would respond with all the second lines. (More exactly, the "first
150 line" is one or more objects in Muddle followed by `$`, and the
151 "second line" is everything up to the next "first line".)
153 Anything which is written in the Muddle language or which is typed on
154 a computer terminal appears herein in a fixed width font, as in
155 `ROOT`. A metasyntactic variable -- something to be replaced in actual
156 use by something else -- appears as *radix:fix*, in an italic font;
157 often the variable will have both a meaning and a data type (as here),
158 but sometimes one of those will be ommitted, for obvious reasons.
160 An ellipsis (...) indicates that something uninteresting has been
161 omitted. The character `^` means that the following character is to be
162 "controllified": it is usually typed by holding down a terminal's CTRL
163 key and striking the other key.
165 Chapter 1. Basic Introduction
166 =============================
168 The purpose of this chapter is to provide you with that minimal amount
169 of information needed to experiment with Muddle while reading this
170 document. It is strongly recommended that you do experiment,
171 especially upon reaching chapter 5 (Simple Functions).
173 1.1. Loading Muddle \[1\]
174 -------------------------
176 First, catch your rabbit. Somehow get the interpreter running -- the
177 program in the file `SYS:TS.Muddle` in the ITS version or
178 `SYS:Muddle.SAV` in the Tenex version or `SYS:Muddle.EXE` in the
179 Tops-20 version. The interpreter will first type out some news
180 relating to Muddle, if any, then type
182 LISTENING-AT-LEVEL 1 PROCESS 1
184 and then wait for you to type something.
186 The program which you are now running is an interpreter for the
187 language Muddle. **All** it knows how to do is interpret Muddle
188 expressions. There is no special "command language"; you communicate
189 with the program -- make it do things for you -- by actually typing
190 legal Muddle expressions, which it then interprets. **Everything** you
191 can do at a terminal can be done in a program, and vice versa, in
192 exactly the same way.
194 The program will be referred to as just "Muddle" (or "the
195 interpreter") from here on. There is no ambiguity, since the program
196 is just an incarnation of the concept "Muddle".
201 Typing a character at Muddle normally just causes that character to be
202 echoed (printed on your terminal) and remembered in a buffer. The only
203 characters for which this is normally not true act as follows:
205 Typing `$` (ESC) causes Muddle to echo dollar-sign and causes the
206 contents of the buffer (the characters which you've typed) to be
207 interpreted as an expression(s) in Muddle. When this interpretation is
208 done, the result will be printed and Muddle will wait for more typing.
209 ESC will be represented by the glyph `$` in this document.
211 Typing the rubout character (DEL in the ITS and Top-20 versions,
212 CTRL+A in the Tenex version) causes the last character in the buffer
213 -- the one most recently typed -- to be thrown away (deleted). If you
214 now immediately type another rubout, once again the last character is
215 deleted -- namely the second most recently typed. Etc. The character
216 deleted is echoed, so you can see what you're doing. On some "display"
217 terminals, rubout will "echo" by causing the deleted character to
218 disappear. If no characters are in the buffer, rubout echoes as a
219 carriage-return line-feed.
221 Typing \^@ (CTRL+@) deletes everything you have typed since the last
222 `$`, and prints a carriage-return line-feed.
224 Typing \^D (CTRL+D) causes the current input buffer to be typed back
225 out at you. This allows you to see what you really have, without the
226 confusing re-echoed characters produced by rubout.
228 Typing \^L (CTRL+L) produces the same effect as typing \^D, except
229 that, if your terminal is a "display" terminal (for example, IMLAC,
230 ARDS, Datapoint), it firsts clears the screen.
232 Typing \^G (CTRL+G) causes Muddle to stop whatever it is doing and act
233 as if an error had occurred ([section
234 1.4](#14-errors-simple-considerations-1)). \^G is generally most
235 useful for temporary interruptions to check the progress of a
236 computation. \^G is "reversible" -- that is, it does not destroy any
237 of the "state" of the computation it interrupts. To "undo" a \^G, type
242 (This is discussed more fully far below, in section 16.4.)
244 Typing \^S (CTRL+S) causes Muddle to **throw away** what it is
245 currently doing and return a normal "listening" state. (In the Tenex
246 and Tops-20 versions, \^O also should have the same effect.) \^S is
247 generally most useful for aborting infinite loops and similar terrible
248 things. \^S **destroys** whatever is going on, and so it is **not**
251 Most expressions in Muddle include "brackets" (generically meant) that
252 must be correctly paired and nested. If you end your typing with the
253 pair of characters `!$` (!+ESC), all currently unpaired brackets (but
254 not double-quotes, which bracket strings of characters) will
255 automatically be paired and interpretation will start. Without the !,
256 Muddle will just sit there waiting for you to pair them. If you have
257 improperly nested parentheses, brackets, etc., within the expression
258 you typed, an error will occur, and Muddle will tell you what is
261 Once the brackets are properly paired, Muddle will immediately echo
262 carriage-return and line-feed, and the next thing it prints will be
263 the result of the evaluation. Thus, if a plain `$` is not so echoed,
264 you have some expression unclosed. In that case, if you have not typed
265 any characters beyond the `$`, you can usually rub out the `$` and
266 other characters back to the beginning of the unclosed expression.
267 Otherwise, what you have typed is beyond the help of rubout and \^@;
268 if you want to abort it, use \^S.
270 Muddle accepts and distinguishes between upper and lower case. All
271 "built-in functions" must be referenced in upper case.
273 1.3. Loading a File \[1\]
274 -------------------------
276 If you have a program in Muddle that you have written as an ASCII file
277 on some device, you can "load" it by typing
281 where *file* is the name of the file, in standard operating-system
282 syntax, enclosed in "s (double-quotes). Omitted parts of the file name
283 are taken by default from the file name `DSK: INPUT >` (in the ITS
284 version) or `DSK: INPUT.MUD` (in the Tenex and Tops-20 versions) in
285 the current disk directory.
287 Once you type `$`, Muddle will process the text in the file (including
288 `FLOAD`s) exactly as if you had typed it on a terminal and followed it
289 with `$`, except that "values" produced by the computations are not
290 printed. When Muddle is finished processing the file, it will print
293 When Muddle starts running, it will `FLOAD` the file `MUDDLE INIT`
294 (ITS version) or `MUDDLE.INIT` (Tenex and Tops-20 versions), if it
297 1.4. Errors — Simple Considerations \[1\]
298 -----------------------------------------
300 When Muddle decides for some reason that something is wrong, the
301 standard sequence of evaluation is interrupted and an error function
302 is called. This produces the following terminal output:
305 often-hyphenated-reason
306 function-in-which-error-occurred
307 LISTENING-AT-LEVEL integer PROCESS integer
309 You can now interact with Muddle as usual, typing expressions and
310 having them evaluated. There exist facilities (built-in functions)
311 allowing you to find out what went wrong, restart, or abandon whatever
312 was going on. In particular, you can recover from an error -- that is,
313 undo everything but side effects and return to the initial typing
314 phase -- by typing the following first line, to which Muddle will
315 respond with the second line:
318 LISTENING-AT-LEVEL 1 PROCESS 1
320 If you type the following first line while still in the error state
321 (before `<ERRET>`), Muddle will print, as shown, the arguments (or
322 "parameters or "inputs" or "independent variables") which gave
323 indigestion to the unhappy function:
325 <ARGS <FRAME <FRAME>>>$
326 [ arguments to unhappy function ]
328 This will be explained by and by.
330 Chapter 2. Read, Evaluate, and Print
331 ====================================
336 Once you type `$` and all brackets are correctly paired and nested,
337 the current contents of the input buffer go through processing by
338 three functions successively: first `READ`, which passes its output to
339 `EVAL` ("evaluate"), which passes its output to `PRINT`, whose output
340 is typed on the terminal.
342 \[Actually, the sequence is more like `READ`, `CRLF`, `EVAL`, `PRIN1`,
343 `CRLF` (explained in chapter 11); Muddle gives you a carriage-return
344 line-feed when the `READ` is complete, that is, when all brackets are
349 - `READ`: printable representations → Muddle objects
350 - `EVAL`: Muddle objects → Muddle objects
351 - `PRINT`: Muddle objects → printable representations
353 That is, `READ` takes ASCII text, such as is typed in at a terminal,
354 and creates the Muddle objects represented by that text. `PRINT` takes
355 Muddle objects, creates ASCII text representations of them, and types
356 them out. `EVAL`, which is the really important one, performs
357 transformations on Muddle objects.
359 2.2. Philosophy (TYPEs) \[1\]
360 -----------------------------
362 In a general sense, when you are interacting with Muddle, you are
363 dealing with a world inhabited only by a particular set of objects:
366 Muddle objects are best considered as abstract entities with abstract
367 properties. The properties of a particular Muddle object depend on the
368 class of Muddle objects to which it belongs. This class is the `TYPE`
369 of the Muddle object. Every Muddle object has a `TYPE`, and every
370 `TYPE` has its own peculiarities. There are many different `TYPE`s in
371 Muddle; they will gradually be introduced below, but in the meantime
372 here is a representative sample: `SUBR` (the `TYPE` of `READ`, `EVAL`,
373 and `PRINT`), `FSUBR`, `LIST`, `VECTOR`, `FORM`, `FUNCTION`, etc.
374 Since every object has a `TYPE`, one often abbreviates "an object of
375 `TYPE` *type*" by saying "a *type*".
377 The laws of the Muddle world are defined by `EVAL`. In a very real
378 sense, `EVAL` is the only Muddle object which "acts", which "does
379 something". In "acting", `EVAL` is always "following the directions"
380 of some Muddle object. Every Muddle object should be looked upon as
381 supplying a set of directions to `EVAL`; what these directions are
382 depends heavily on the `TYPE` of the Muddle object.
384 Since `EVAL` is so ever-present, an abbreviation is in order:
385 "evaluates to *something*" or "`EVAL`s to *something*" should be taken
386 as an abbreviation for "when given to `EVAL`, causes `EVAL` to return
389 As abstract entities, Muddle objects are, of course, not "visible".
390 There is, however, a standard way of representing abstract Muddle
391 objects in the real world. The standard way of representing any given
392 `TYPE` of Muddle object will be given below when the `TYPE` is
393 introduced. These standard representations are what `READ`
394 understands, and what `PRINT` produces.
396 2.3. Example (TYPE FIX) \[1\]
397 -----------------------------
402 The following has occurred:
404 First, `READ` recognized the character `1` as the representation for
405 an object of `TYPE` `FIX`, in particular the one which corresponds to
406 the integer one. (`FIX` means integer, because the decimal point is
407 understood always to be in a fixed position: at the right-hand end.)
408 `READ` built the Muddle object corresponding to the decimal
409 representation typed, and returned it.
411 Then `EVAL` noted that its input was of `TYPE` `FIX`. An object of
412 `TYPE` `FIX` evaluates to itself, so `EVAL` returned its input
415 Then `PRINT` saw that its input was of `TYPE` `FIX`, and printed on
416 the terminal the decimal character representation of the corresponding
419 2.4. Example (TYPE FLOAT) \[1\]
420 -------------------------------
425 What went on was entirely analogous to the preceding example, except
426 that the Muddle object was of `TYPE` `FLOAT`. (`FLOAT` means a real
427 number (of limited precision), because the decimal point can float
428 around to any convenient position: an internal exponent part tells
429 where it "really" belongs.)
431 2.5. Example (TYPE ATOM, PNAME) \[1\]
432 -------------------------------------
437 This time a lot more has happened.
439 `READ` noted that what was typed had no special meaning, and therefore
440 assumed that it was the representation of an identifier, that is, an
441 object of `TYPE` `ATOM`. ("Atom" means more or less *indivisible*.)
442 `READ` therefore attempted to look up the representation in a table it
443 keeps for such purposes \[a `LIST` of `OBLISTS`, available as the
444 local value of the `ATOM` `OBLIST`\]. If `READ` finds an `ATOM` in its
445 table corresponding to the representation, that `ATOM` is returned as
446 `READ`'s value. If `READ` fails in looking up, it creates a new
447 `ATOM`, puts it in the table with the representation read \[`INSERT`
448 into `<1 .OBLIST>` usually\], and returns the new `ATOM`. Nothing
449 which could in any way be referenced as a legal "value" is attached to
450 the new `ATOM`. The initially-typed representation of an `ATOM`
451 becomes its `PNAME`, meaning its name for `PRINT`. One often
452 abbreviates "object of `TYPE` `ATOM` with `PNAME` *name*" by saying
455 `EVAL`, given an `ATOM`, returned just that `ATOM`.
457 `PRINT`, given an `ATOM`, typed out its `PNAME`.
459 At the end of this chapter, the question "what is a legal `PNAME`"
460 will be considered. Further on, the methods used to attach values to
461 `ATOM`s will be described.
463 2.6. FIXes, FLOATs, and ATOMs versus READ: Specifics
464 ----------------------------------------------------
466 ### 2.6.1. READ and FIXed-point Numbers
468 `READ` considers any grouping of characters which are solely digits to
469 be a `FIX`, and the radix of the representation is decimal by default.
470 A `-` (hyphen) immediately preceding such a grouping represents a
471 negative `FIX`. The largest `FIX` representable on the PDP-10 is two
472 to the 35th power minus one, or 34,359,738,367 (decimal): the smallest
473 is one less than the negative of that number. If you attempt to type
474 in a `FIX` outside that range, `READ` converts it to a `FLOAT`; if a
475 program you write attempts to produce a `FIX` outside that range, an
476 overflow error will occur (unless it is disabled).
478 The radix used by `READ` and `PRINT` is changeable by the user;
479 however, there are two formats for representations of `FIX`es which
480 cause `READ` to use a specified radix independent of the current one.
481 These are as follows:
483 1. If a group of digits is immediately followed by a period (`.`),
484 `READ` interprets that group as the decimal representation of a
485 `FIX`. For example, `10.` is always interpreted by `READ` as the
486 decimal representation of ten.
488 2. If a group of digits is immediately enclosed on both sides with
489 asterisks (`*`), `READ` interprets that group as the octal
490 representation of a `FIX`. For example, `*10*` is always
491 interpreted by `READ` as the octal representation of eight.
493 ### 2.6.2. READ and PRINT versus FLOATing-point Numbers
495 `PRINT` can produce, and `READ` can understand, two different formats
496 for objects of `TYPE` `FLOAT`. The first is "decimal-point" notation,
497 the second is "scientific" notation. Decimal radix is always used for
498 representations of `FLOAT`s.
500 "Decimal-point" notation for a `FLOAT` consists of an arbitrarily long
501 string of digits containing one `.` (period) which is followed by at
502 least one digit. `READ` will make a `FLOAT` out of any such object,
503 with a limit of precision of one part in 2 to the 27th power.
505 "Scientific" notation consists of:
509 2. immediately followed by `E` or `e` (upper or lower case letter E),
511 3. immediately followed by an exponent,
513 where a "number" is an arbitrarily long string of digits, with or
514 without a decimal point (see following note): an an "exponent" is up
515 to two digits worth of `FIX`. This notation represents the "number" to
516 the "exponent" power of ten. Note: if the "number" as above would by
517 itself be a `FIX`, and if the "exponent" is positive, and if the
518 result is within the allowed range of `FIX`es, then the result will be
519 a `FIX`. For example, `READ` understands `10E1` as `100` (a `FIX`),
520 but `10E-1` as `1.0000000` (a `FLOAT`).
522 The largest-magnitude `FLOAT` which can be handled without overflow is
523 `1.7014118E+38` (decimal radix). The smallest-magnitude `FLOAT` which
524 can be handled without underflow is `.14693679E-38`.
526 ### 2.6.3. READ and PNAMEs
528 The question "what is a legal `PNAME`?" is actually not a reasonable
529 one to ask: **any** non-empty string of **arbitrary** characters can
530 be the `PNAME` of an `ATOM`. However, some `PNAME`s are easier to type
531 to `READ` than others. But even the question "what are easily typed
532 `PNAME`s?" is not too reasonable, because: `READ` decides that a group
533 of characters is a `PNAME` by **default**; if it can't possibly be
534 anything else, it's a `PNAME`. So, the rules governing the
535 specification of `PNAME`s are messy, and best expressed in terms of
536 what is not a `PNAME`. For simplicity, you can just consider any
537 uninterrupted group of upper- and lower-case letters and (customarily)
538 hyphens to be a `PNAME`; that will always work. If you neither a
539 perfectionist nor a masochist, skip to the next chapter.
541 #### 2.6.3.1. Non-PNAMEs
543 A group of characters is **not** a `PNAME` if:
545 1. It represents a `FLOAT` or a `FIX`, as described above -- that is,
546 it is composed wholly of digits, or digits and a single `.`
547 (period) or digits and a `.` and the letter `E` or `e` (with
548 optional minus signs in the right places).
550 2. It begins with a `.` (period).
552 3. It contains -- if typed interactively -- any of the characters
553 which have special interactive effects: `^@`, `^D`, `^L`, `^G`,
554 `^O`, `$` (`ESC`), rubout.
556 4. It contains a format character -- space, carriage-return,
557 line-feed, form-feed, horizontal tab, vertical tab.
559 5. It contains a `,` (comma) or a `#` (number sign) or a `'` (single
560 quote) or a `;` (semicolon) or a `%` (percent sign).
562 6. It contains any variety of bracket -- `(` or `)` or `[` or `]` or
563 `<` or `>` or `{` or `}` or `"`.
565 In addition, the character `\` (backslash) has a special
566 interpretation, as mentioned below. Also the pair of characters `!-`
567 (exclamation-point hyphen) has an extremely special interpretation,
568 which you will reach at chapter 15.
570 The characters mentioned in cases 4 through 6 are "separators" -- that
571 is, they signal to `READ` that whatever it was that the preceding
572 characters represented, it's done now. They can also indicate the
573 start of a new object's representation (all the opening "brackets" do
576 #### 2.6.3.2. Examples
578 The following examples are not in the "standard format" of "*line
579 typed in*`$` *result printed*", because they are not, in some cases,
580 completed objects; hence, `READ` would continue waiting for the
581 brackets to be closed. In other cases, they will produce errors during
582 `EVAL`uation if other -- currently irrelevant -- conditions are not
583 met. Instead, the right-hand column will be used to state just what
584 `READ` thought the input in the left-hand column really was.
586 --------------------------------------------------------------------------------
588 --------------------------- ----------------------------------------------------
589 `ABC$` an `ATOM` of `PNAME` `ABC`
591 `abc$` an `ATOM` of `PNAME` `abc`
593 `ARBITRARILY-LONG-PNAME$` an `ATOM` of `PNAME` `ARBITRARILY-LONG-PNAME`
595 `1.2345$` a `FLOAT`, `PRINT`ed as `1.2345000`
597 `1.2.345$` an `ATOM` of `PNAME` `1.2.345`
599 `A.or.B$` a `ATOM` of `PNAME` `A.or.B`
601 `.A.or.B$` not an `ATOM`, but (as explained later) a `FORM`
602 containing an `ATOM` of `PNAME` `A.or.B`.
604 `MORE THAN ONE$` three `ATOM`s, with `PNAME`s `MORE`, and `THAN`, and
607 `ab(cd$` an `ATOM` of `PNAME` `ab`, followed by the start of
608 something else (The something else will contain an
609 `ATOM` of `PNAME` beginning `cd.`)
611 `12345A34$` an `ATOM` of `PNAME` `12345A35` (If the A had been
612 an E, the object would have been a `FLOAT`.)
613 --------------------------------------------------------------------------------
615 #### 2.6.3.3. Â (Backslash) in ATOMs
617 If you have a strange, uncontrollable compulsion to have what were
618 referred to as "separators" above as part of the `PNAME`s of your
619 `ATOM`s, you can do so by preceding them with the character `\`
620 (backslash). `\` will also magically turn an otherwise normal `FIX` or
621 `FLOAT` into an `ATOM` if it appears amongst the digits. In fact,
622 backslash in front of **any** character changes it from something
623 special to "just another character" (including the character `\`). It
624 is an escape character.
626 When `PRINT` confronts an `ATOM` which had to be backslashed in order
627 to be an `ATOM`, it will dutifully type out the required `\`s. They
628 will not, however, necessarily be where you typed them; they will
629 instead be at those positions which will cause `READ` the least grief.
630 For example, `PRINT` will type out a `PNAME` which consists wholly of
631 digits by first typing a `\` and then typing the digits - no matter
632 where you originally typed the `\` (or `\`s).
634 #### 2.6.3.4. Examples of Awful ATOMs
636 The following examples illustrate the amount of insanity that can be
637 perpetrated by using `\`. The format of the examples is again
638 non-standard, this time not because anything is unfinished or in
639 error, but because commenting is needed: `PRINT` doesn't do it full
642 ---------------------------------------------------------------------------
644 ------------------------ --------------------------------------------------
645 `a\ one\ and\ a\ two$` one `ATOM`, whose `PNAME` has four spaces in it
647 `1234\56789$` an `ATOM` of `PNAME` `123456789`, which `PRINT`s
650 `123\ $` an `ATOM` of `PNAME` `123space`, which `PRINT`s as
651 `\123\`, with a space on the end
653 `\\$` an `ATOM` whose `PNAME` is a single backslash
654 ---------------------------------------------------------------------------
656 Chapter 3. Built-in Functions
657 =============================
659 3.1. Representation \[1\]
660 -------------------------
662 Up to this point, all the objects we have been concerned with have had
663 no internal structure discernible in Muddle. While the characteristics
664 of objects with internal structure differ greatly, the way `READ` and
665 `PRINT` handle them is uniform, to wit:
667 - `READ`, when applied to the representation of a structured object,
668 builds and returns an object of the indicated `TYPE` with elements
669 formed by applying `READ` to each of their representations in
672 - `PRINT`, when applied to a structured object, produces a
673 representation of the object, with its elements represented as
674 `PRINT` applied to each of them in turn.
676 A Muddle object which is used to represent the application of a
677 function to its arguments is an argument of `TYPE` `FORM`. Its printed
680 < func arg-1 arg-2 ... arg-N >
682 where *func* is an object which designates the function to be applied,
683 and *arg-1* through *arg-N* are object which designate the arguments
684 or "actual parameters" or "inputs". A `FORM` is just a structured
685 object which is stored and can be manipulated like a `LIST` (its
686 "primitive type" is `LIST` -- chapter 6). The application of the
687 function to the arguments is done by `EVAL`. The usual meaning of
688 "function" (uncapitalized) in this document will be anything
689 applicable to arguments.
691 3.2. Evaluation \[1\]
692 ---------------------
694 `EVAL` applied to a `FORM` acts as if following these directions:
696 First, example the *func* (first element) of the `FORM`. If it is an
697 `ATOM`, look at its "value" (global or local, in that order -- see
698 next chapter). If it is not an `ATOM`, `EVAL` it and look at the
699 result of the evaluation. If what you are looking at is not something
700 which can be applied to arguments, complain (via the `ERROR`
701 function). Otherwise, inspect what you are looking at and follow its
702 directions in evaluating or not evaluating the arguments (chapters 9
703 and 19) and then "apply the function" -- that is, `EVAL` the body of
704 the object gotten from *func*.
706 3.3. Built-in Functions (TYPE SUBR, TYPE FSUBR) \[1\]
707 -----------------------------------------------------
709 The built-in functions of Muddle come in two varieties: those which
710 have all their arguments `EVAL`ed before operating on them (`TYPE`
711 `SUBR`, for "subroutine", pronounced "subber") and those which have
712 none of their arguments `EVAL`ed (`TYPE` `FSUBR`, historically from
713 Lisp (Moon, 1974), pronounced "effsubber"). Collectively they will be
714 called `F/SUBR`s, although that term is not meaningful to the
715 interpreter. See appendix 2 for a listing of all `F/SUBR`s and short
716 descriptions. The term "Subroutine" will be used herein to mean both
717 `F/SUBR`s and compiled user programs (`RSUBR`s and `RSUBR-ENTRY`s --
720 Unless otherwise stated, **every** Muddle built-in Subroutine is of
721 `TYPE` **`SUBR`**. Also, when it is stated that an argument of a
722 `SUBR` must be of a particular `TYPE`, note that this means that
723 `EVAL` of what is there must be of the particular `TYPE`.
725 Another convenient abbreviation which will be used is "the `SUBR`
726 *pname*" in place of "the `SUBR` which is initially the 'value' of the
727 `ATOM` of `PNAME` *pname*". "The `FSUBR` *pname*" will be used with a
730 3.4. Examples (+ and FIX; Arithmetic) \[1\]
731 -------------------------------------------
736 The `SUBR` `+` adds numbers. Most of the usual arithmetic functions
737 are Muddle `SUBR`s: `+`, `-`, `*`, `/`, `MIN`, `MAX`, `MOD`, `SIN`,
738 `COS`, `ATAN`, `SQRT`, `LOG`, `EXP`, `ABS`. (See appendix 2 for short
739 descriptions of these.) All except `MOD`, which wants `FIX`es, are
740 indifferent as to whether their arguments are `FLOAT` or `FIX` or a
741 mixture. In the last case they exhibit "contagious `FLOAT`ing": one
742 argument of `TYPE` `FLOAT` forces the result to be of `TYPE` `FLOAT`.
747 The `SUBR` `FIX` explicitly returns a `FIX`ed-point number
748 corresponding to a `FLOAT`ing-point number. `FLOAT` does the opposite.
752 <SQRT <+ <* 3 3> <* 4 4>>>$
763 Note this last result: the division of two `FIX`es gives a `FIX` with
764 truncation, not rounding, of the remainder: the intermediate result
765 remains a `FIX` until a `FLOAT` argument is encountered.
767 3.5. Arithmetic Details
768 -----------------------
770 `+`, `-`, `*`, `/`, `MIN`, and `MAX` all take any number of arguments,
771 doing the operation with the first argument and the second, then with
772 that result and the third argument, etc. If called with no arguments,
773 each returns the identity for its operation (`0`, `0`, `1`, `1`, the
774 greatest `FLOAT`, and the least `FLOAT`, respectively); if called with
775 one argument, each acts as if the identity and the argument has been
776 supplied. They all will cause an overflow or underflow error if any
777 result, intermediate or final, is too large or too small for the
778 machine's capacity. (That error can be disabled if necessary --
781 One arithmetic function that always requires some discussion is the
782 pseudo-random-number generator. Muddle's is named `RANDOM`, and it
783 always returns a `FIX`, uniformly distributed over the whole range of
784 `FIX`es. If `RANDOM` is never called with arguments, it always returns
785 the exact same sequence of numbers, for convenience in debugging.
786 "Debugged" programs should give `RANDOM` two arguments on the first
787 call, which become seeds for a new sequence. Popular choices of new
788 seeds are the numbers given by `TIME` (which see), possibly with bits
789 modified (chapter 18). Example ("pick a number from one to ten"):
791 <+ 1 <MOD <RANDOM> 10>>$
794 Chapter 4. Values of Atoms
795 ==========================
800 There are two kinds of "value" which can be attached to an `ATOM`. An
801 `ATOM` can have either, both, or neither. They interact in no way
802 (except that alternately referring to one and then the other is
803 inefficient). These two values are referred to as the **local value**
804 and the **global value** of an `ATOM`. The terms "local" and "global"
805 are relative to `PROCESS`es (chapter 20), not functions or programs.
806 The `SUBR`s which reference the local and global values of an `ATOM`,
807 and some of the characteristics of local versus global values, follow.
812 ### 4.2.1. SETG \[1\]
814 A global value can be assigned to an `ATOM` by the `SUBR` `SETG` ("set
819 where *atom* must `EVAL` to an `ATOM`, and *any* can `EVAL` to
820 anything. `EVAL` of the second argument becomes the global value of
821 `EVAL` of the first argument. The value returned by the `SETG` is its
822 second argument, namely the new global value of *atom*.
826 <SETG FOO <SETG BAR 500>>$
829 The above made the global values of both the `ATOM` `FOO` and the
830 `ATOM` `BAR` equal to the `FIX`ed-point number 500.
835 That made the global value of the `ATOM` `BAR` equal to the `ATOM`
838 ### 4.2.2. GVAL \[1\]
840 The `SUBR` `GVAL` ("global value") is used to reference the global
845 returns as a value the global value of *atom*. If *atom* does not
846 evaluate to an `ATOM`, or if the `ATOM` to which it evaluates has no
847 global value, an error occurs.
849 `GVAL` applied to an `ATOM` anywhere, in any `PROCESS`, in any
850 function, will return the same value. Any `SETG` anywhere changes the
851 global value for everybody. Global values are context-independent.
853 `READ` understands the character `,` (comma) as an abbreviation for an
854 application of `GVAL` to whatever follows it. `PRINT` always
855 translates an application of `GVAL` into the comma format. The
856 following are absolutely equivalent:
860 Assuming the examples in section 4.2.1 were carried out in the order
861 given, the following will evaluate as indicated:
872 ### 4.2.3. Note on SUBRs and FSUBRs
874 The initial `GVAL`s of the `ATOM`s used to refer to Muddle "built-in"
875 Subroutines are the `SUBR`s and `FSUBR`s which actually get applied
876 when those `ATOM`s are referenced. If you don't like the way those
877 supplied routines work, you are perfectly free to `SETG` the `ATOM`s
878 to your own versions.
884 ("global unassign") causes *atom* to have no assigned global value,
885 whether or not it had one previously. The storage used for the global
886 value can become free for other uses.
893 The `SUBR` `SET` is used to assign a local value to an `ATOM`.
894 Applications of `SET` are of the form
898 `SET` returns `EVAL` of *any* just like `SETG`.
902 <SET BAR <SET FOO 100>>$
905 Both `BAR` and `FOO` have been given local values equal to the
906 `FIX`ed-point number 100.
911 `FOO` has been given the local value `BAR`.
913 Note that neither of the above did anything to any global values `FOO`
914 and `BAR` might have had.
916 ### 4.3.2. LVAL \[1\]
918 The `SUBR` used to extract the local value of an `ATOM` is named
919 `LVAL`. As with `GVAL`, `READ` understands an abbreviation for an
920 application of `LVAL`: the character `.` (period), and `PRINT`
921 produces it. The following two representations are equivalent, and
922 when `EVAL` operates on the corresponding Muddle object, it returns
923 the current local value of *atom*:
927 The local value of an `ATOM` is unique within a `PROCESS`. `SET`ting
928 an `ATOM` in one `PROCESS` has no effect on its `LVAL` in another
929 `PROCESS`, because each `PROCESS` has its own "control stack"
930 (chapters 20 and 22).
932 Assume **all** of the previous examples in this chapter have been
933 done. Then the following evaluate as indicated:
948 causes *atom* to have no assigned local value, whether or not it had
954 `VALUE` is a `SUBR` which takes an `ATOM` as an argument, and then:
956 1. if the `ATOM` has an `LVAL`, returns the `LVAL`;
957 2. if the `ATOM` has no `LVAL` but has a `GVAL`, returns the `GVAL`;
958 3. if the `ATOM` has neither a `GVAL` nor an `LVAL`, calls the
961 This order of seeking a value is the **opposite** of that used when an
962 `ATOM` is the first element of a `FORM`. The latter will be called the
963 G/LVAL, even though that name is not used in Muddle.
980 Chapter 5. Simple Functions
981 ===========================
986 The Muddle equivalent of a "program" (uncompiled) is an object of
987 `TYPE` `FUNCTION`. Actually, full-blown "programs" are usually
988 composed of sets of `FUNCTION`s, with most `FUNCTION`s in the set
989 acting as "subprograms".
991 A `FUNCTION` may be considered to be a `SUBR` or `FSUBR` which you
992 yourself define. It is "run" by using a `FORM` to apply it to
993 arguments (for example, <*function arg-1 arg-2 ...*>), and it
994 always "returns" a single object, which is used as the value of the
995 `FORM` that applied it. The single object may be ignored by whatever
996 "ran" the `FUNCTION` -- equivalent to "returning no value" -- or it
997 may be a structured object containing many objects -- equivalent to
998 "returning many values". Muddle is an "applicative" language, in
999 contrast to "imperative" languages like Fortran. In Muddle it is
1000 impossible to return values through arguments in the normal case; they
1001 can be returned only as the value of the `FORM` itself, or as side
1002 effects to structured objects or global values.
1004 In this chapter a simple subset of the `FUNCTION`s you can write is
1005 presented, namely `FUNCTION`s which "act like" `SUBR`s with a fixed
1006 number of arguments. While this class corresponds to about 90% of the
1007 `FUNCTION`s ever written, you won't be able to do very much with them
1008 until you read further and learn more about Muddle's control and
1009 manipulatory machinery. However, all that machinery is just a bunch of
1010 `SUBR`s and `FSUBR`s, and you already know how to "use" them; you just
1011 need to be told what they do. Once you have `FUNCTION`s under your
1012 belt, you can immediately make use of everything presented from this
1013 point on in the document. In fact, we recommend that you do so.
1015 5.2. Representation \[1\]
1016 -------------------------
1018 A `FUNCTION` is just another data object in Muddle, of `TYPE`
1019 `FUNCTION`. It can be manipulated like any other data object. `PRINT`
1020 represents a `FUNCTION` like this:
1022 #FUNCTION (elements)
1024 that is, a number sign, the `ATOM` `FUNCTION`, a left parenthesis,
1025 each of the elements of the `FUNCTION`, and a right parenthesis. Since
1026 `PRINT` represents `FUNCTION`s like this, you can type them in to
1027 `READ` this way. (But there are a few `TYPE`s for which that
1028 implication is false.)
1030 The elements of a `FUNCTION` can be "any number of anythings";
1031 however, when you **use** a `FUNCTION` (apply it with a `FORM`),
1032 `EVAL` will complain if the `FUNCTION` does not look like
1034 #FUNCTION (act:atom arguments:list decl body)
1036 where *act* and *decl* are optional (section 9.8 and chapter 14);
1037 *body* is **at least one** Muddle object -- any old Muddle object;
1038 and, in this simple case, *arguments* is
1040 (any number of ATOMs)
1042 that is, something `READ` and `PRINT`ed as: left parenthesis, any
1043 number -- including zero -- of `ATOM`s, right parenthesis. (This is
1044 actually a normal Muddle object of `TYPE` `LIST`, containing only
1047 Thus, these `FUNCTION`s will cause errors -- but only **when used**:
1050 --------------------------- ----------------------------------
1051 `#FUNCTION ()` -- no argument `LIST` or body
1052 `#FUNCTION ((1) 2 7.3)` -- non-`ATOM` in argument `LIST`
1053 `#FUNCTION ((A B C D))` -- no body
1054 `#FUNCTION (<+ 1 2> A C)` -- no argument `LIST`
1056 These `FUNCTION`s will never cause errors because of format:
1058 #FUNCTION (() 1 2 3 4 5)
1060 #FUNCTION (()()()()()()()())
1061 #FUNCTION ((A B C D EE F G H HIYA) <+ .A .HIYA>)
1062 #FUNCTION ((Q) <SETG C <* .Q ,C>> <+ <MOD ,C 3> .Q>)
1064 and the last two actually do something which might be useful. (The
1065 first three are rather pathological, but legal.)
1067 5.3. Application of FUNCTIONs: Binding \[1\]
1068 --------------------------------------------
1070 `FUNCTION`s, like `SUBR`s and `FSUBR`s, are applied using `FORM`s. So,
1072 <#FUNCTION ((X) <* .X .X>) 5>$
1075 applied the indicated `FUNCTION` to 5 and returned 25.
1077 What `EVAL` does when applying a `FUNCTION` is the following:
1079 1. Create a "world" in which the `ATOM`s of the argument `LIST` have
1080 been **`SET`** to the values applied to the `FUNCTION`, and all
1081 other `ATOM`s have their original values. This is called
1084 - In the above, this is a "world" in which `X` is `SET` to `5`.
1086 2. In that new "world", evaluate all the objects in the body of the
1087 `FUNCTION`, one after the other, from first to last.
1089 - In the above, this means evaluate `<* .X .X>` in a "world" where
1090 `X` is `SET` to `5`.
1092 3. Throw away the "world" created, and restore the `LVAL`s of all
1093 `ATOM`s bound in this application of the `FUNCTION` to their
1094 originals (if any). This is called "unbinding".
1096 - In the above, this simply gives `X` back the local value, if any,
1097 that it had before binding.
1099 4. Return as a value the **last value obtained** when the
1100 `FUNCTION`'s body was evaluated in step (2).
1102 - In the above, this means return `25` as the value.
1104 The "world" mentioned above is actually an object of `TYPE`
1105 `ENVIRONMENT`. The fact that such "worlds" are separate from the
1106 `FUNCTION`s which cause their generation means that **all** Muddle
1107 `FUNCTION`s can be used recursively.
1109 The only thing that is at all troublesome in this sequence is the
1110 effect of creating these new "worlds", in particular, the fact that
1111 the **previous** world is completely restored. This means that if,
1112 inside a `FUNCTION`, you `SET` one of its argument `ATOM`s to
1113 something, that new `LVAL` will **not** be remembered when `EVAL`
1114 leaves the `FUNCTION`. However, if you `SET` an `ATOM` which is
1115 **not** in the argument `LIST` (or `SETG` **any** `ATOM`) the new
1116 local (or global) value **will** be remembered. Examples:
1120 <#FUNCTION ((X) <SET X <* .X .X>>) 5>$
1129 <#FUNCTION ((X) <SET Y <* .X .X>>) 5>$
1134 By using `PRINT` as a `SUBR`, we can "see" that an argument's `LVAL`
1135 really is changed while `EVAL`uating the body of a `FUNCTION`:
1139 <#FUNCTION ((X) <PRINT .X> <+ .X 10>) 3>$
1144 The first number after the application `FORM` was typed out by the
1145 `PRINT`; the second is the value of the application.
1147 Remembering that `LVAL`s of `ATOM`s **not** in argument `LIST`s are
1148 not changed, we can reference them within `FUNCTION`s, as in
1152 <#FUNCTION ((Y) </ .Z .Y>) 5>$
1155 `ATOM`s used like `Z` or `Y` in the above examples are referred to as
1156 "free variables". The use of free variables, while often quite
1157 convenient, is rather dangerous unless you know **exactly** how a
1158 `FUNCTION` will **always** be used: if a `FUNCTION` containing free
1159 variables is used within a `FUNCTION` within a `FUNCTION` within ...,
1160 one of those `FUNCTION`s might just happen to use your free variable
1161 in its argument `LIST`, binding it to some unknown value and possibly
1162 causing your use of it to be erroneous. Please note that "dangerous",
1163 as used above, really means that it may be effectively **impossible**
1164 (1) for other people to use your `FUNCTION`s, and (2) for **you** to
1165 use your `FUNCTION`s a month (two weeks?) later.
1167 5.4. Defining FUNCTIONs (FUNCTION and DEFINE) \[1\]
1168 ---------------------------------------------------
1170 Obviously, typing `#FUNCTION (...)` all the time is neither reasonable
1171 nor adequate for many purposes. Normally, you just want a `FUNCTION`
1172 to be the `GVAL` of some `ATOM` -- the way `SUBR`s and `FSUBR`s are --
1173 so you can use it repeatedly (and recursively). Note that you
1174 generally do **not** want a `FUNCTION` to be the `LVAL` of an `ATOM`;
1175 this has the same problems as free variables. (Of course, there are
1176 always cases where you are being clever and **want** the `ATOM` to be
1179 One way to "name" a `FUNCTION` is
1181 <SETG SQUARE #FUNCTION ((X) <* .X .X>)>$
1182 #FUNCTION ((X) <* .X .X>
1191 Another way, which is somewhat cleaner in its typing:
1193 <SETG SQUARE <FUNCTION (X) <* .X .X>>>$
1194 #FUNCTION ((X) <* .X .X>
1196 `FUNCTION` is an `FSUBR` which simply makes a `FUNCTION` out of its
1197 arguments and returns the created `FUNCTION`.
1199 This, however, is generally the **best** way:
1201 <DEFINE SQUARE (X) <* .X .X>>$
1204 #FUNCTION ((X) <* .X .X>
1206 The last two lines immediately above are just to prove that `DEFINE`
1207 did the "right thing".
1209 `DEFINE` is an `FSUBR` which `SETG`s `EVAL` of its first argument to
1210 the `FUNCTION` it makes from the rest of its arguments, and then
1211 returns `EVAL` of its first argument. `DEFINE` obviously requires the
1212 least typing of the above methods, and is "best" from that standpoint.
1213 However, the real reason for using `DEFINE` is the following: If
1214 `EVAL` of `DEFINE`'s first argument **already has** a `GVAL`, `DEFINE`
1215 produces an error. This helps to keep you from accidentally redefining
1216 things -- like Muddle `SUBR`s and `FSUBR`s. The `SETG` constructions
1217 should be used only when you really do want to redefine something.
1218 `DEFINE` will be used in the rest of this document.
1220 \[Actually, if it is absolutely necessary to use `DEFINE` to
1221 "redefine" things, there is a "switch" which can be used: if the
1222 `LVAL` of the `ATOM` `REDEFINE` is `T` (or anything not of `TYPE`
1223 `FALSE`), `DEFINE` will produce no errors. The normal state can be
1224 restored by evaluating `<SET REDEFINE <>>`. See chapter 8.\]
1226 5.5. Examples (Comments) \[1\]
1227 ------------------------------
1229 Using `SQUARE` as defined above:
1231 <DEFINE HYPOT (SIDE-1 SIDE-2)
1232 ;"This is a comment. This FUNCTION finds the
1233 length of the hypotenuse of a right triangle
1234 of sides SIDE-1 and SIDE-2."
1235 <SQRT <+ <SQUARE .SIDE-1> <SQUARE .SIDE-2>>>>$
1240 Note that carriage-returns, line-feeds, tabs, etc. are just
1241 separators, like spaces. A comment is **any single** Muddle object
1242 which follows a `;` (semicolon). A comment can appear between any two
1243 Muddle objects. A comment is totally ignored by `EVAL` but remembered
1244 and associated by `READ` with the place in the `FUNCTION` (or any
1245 other structured object) where it appeared. (This will become clearer
1246 after chapter 13.) The `"`s (double-quotes) serve to make everything
1247 between them a single Muddle object, whose `TYPE` is `STRING` (chapter
1248 7). (`SQRT` is the `SUBR` which returns the square root of its
1249 argument. It always returns a `FLOAT`.)
1251 A whimsical `FUNCTION`:
1253 <DEFINE ONE (THETA) ;"This FUNCTION always returns 1."
1254 <+ <SQUARE <SIN .THETA>>
1255 <SQUARE <COS .THETA>>>>$
1262 `ONE` always returns (approximately) one, since the sum of the squares
1263 of sin(x) and cos(x) is unity for any x. (`SIN` and `COS` always
1264 return `FLOAT`s, and each takes its argument in radians. `ATAN`
1265 (arctangent) returns its value in radians. Any other trigonometric
1266 function can be compounded from these three.)
1268 Muddle doesn't have a general "to the power" `SUBR`, so let's define
1269 one using `LOG` and `EXP` (log base e, and e to a power, respectively;
1270 again, they return `FLOAT`s).
1272 <DEFINE ** (NUM PWR) <EXP <* .PWR <LOG .NUM>>>>$
1281 Two `FUNCTION`s which use a single global variable (Since the `GVAL`
1282 is used, it cannot be rebound.):
1284 <DEFINE START () <SETG GV 0>>$
1286 <DEFINE STEP () <SETG GV <+ ,GV 1>>>$
1297 `START` and `STEP` take no arguments, so their argument `LIST`s are
1300 An interesting, but pathological, `FUNCTION`:
1302 <DEFINE INC (ATM) <SET .ATM <+ ..ATM 1>>>$
1313 `INC` takes an **`ATOM`** as an argument, and `SET`s that `ATOM` to
1314 its current `LVAL` plus `1`. Note that inside `INC`, the `ATOM` `ATM`
1315 is `SET` to the `ATOM` which is its argument; thus `..ATM` returns the
1316 `LVAL` of the **argument**. However, there is a problem:
1325 LISTENING-AT-LEVEL 2 PROCESS 1
1326 <ARGS <FRAME <FRAME>>>$
1329 The error occurred because `.ATM` was `ATM`, the argument to `INC`,
1330 and thus `..ATM` was `ATM` also. We really want the outermost `.` in
1331 `..ATM` to be done in the "world" (`ENVIRONMENT`) which existed **just
1332 before** `INC` was entered -- and this definition of `INC` does both
1333 applications of `LVAL` in its own "world". Techniques for doing `INC`
1334 "correctly" will be covered below. Read on.
1336 Chapter 6. Data Types
1337 =====================
1342 A Muddle object consists of two parts: its `TYPE` and its "data part"
1343 (appendix 1). The interpretation of the "data part" of an object
1344 depends of course on its `TYPE`. The structural organization of an
1345 object, that is, the way it is organized in storage, is referred to as
1346 its "primitive type". While there are many different `TYPE`s of
1347 objects in Muddle, there are fewer primitive types.
1349 All structured objects in Muddle are ordered sequences of elements. As
1350 such, there are `SUBR`s which operate on all of them uniformly, as
1351 ordered sequences. On the other hand, the reason for having different
1352 primitive types of structured objects is that there are useful
1353 qualities of structured objects which are mutually incompatible. There
1354 are, therefore, `SUBR`s which do not work on all structured objects:
1355 these `SUBR`s exist to take full advantage of those mutually
1356 incompatible qualities. The most-commonly-used primitive types of
1357 structured objects are discussed in chapter 7, along with those
1358 special `SUBR`s operating on them.
1360 It is very easy to make a new Muddle object that differs from an old
1361 one only in `TYPE`, as long as the primitive type is unchanged. It is
1362 relatively difficult to make a new structured object that differs from
1363 an old one in primitive type, even if it has the same elements.
1365 Before talking any more about structured objects, some information
1366 needs to be given about `TYPE`s in general.
1368 6.2. Printed Representation \[1\]
1369 ---------------------------------
1371 There are many `TYPE`s for which Muddle has no specific
1372 representation. There aren't enough different kinds of brackets. The
1373 representation used for `TYPE`s without any special representation is
1375 #type representation-as-if-it-were-its-primitive-type
1377 `READ` will understand that format for **any** `TYPE`, and `PRINT`
1378 will use it by default. This representational format will be referred
1379 to below as "\# notation". It was used above to represent `FUNCTION`s.
1381 6.3. SUBRs Related to TYPEs
1382 ---------------------------
1384 ### 6.3.1. TYPE \[1\]
1388 returns an **`ATOM`** whose `PNAME` corresponds to the `TYPE` of
1389 *any*. There is no `TYPE` "TYPE". To type a `TYPE` (aren't homonyms
1390 wonderful?), just type the appropriate `ATOM`, like `FIX` or `FLOAT`
1391 or `ATOM` etc. However, in this document we will use the convention
1392 that a metasyntactic variable can have *type* for a "data type": for
1393 example, *foo:type* means that the `TYPE` of *foo* is `ATOM`, but the
1394 `ATOM` must be something that the `SUBR` `TYPE` can return.
1409 ### 6.3.2. PRIMTYPE \[1\]
1413 evaluates to the primitive type of *any*. The `PRIMTYPE` of *any* is
1414 an `ATOM` which also represents a `TYPE`. The way an object can be
1415 **manipulated** depends solely upon its `PRIMTYPE`; the way it is
1416 **evaluated** depends upon its `TYPE`.
1429 ### 6.3.3. TYPEPRIM \[1\]
1433 returns the `PRIMTYPE` of an object whose `TYPE` is *type*. *type* is,
1434 as usual, an `ATOM` used to designate a `TYPE`.
1449 ### 6.3.4. CHTYPE \[1\]
1453 ("change type") returns a new object that has `TYPE` *type* and the
1454 same "data part" as *any* (appendix 1).
1456 <CHTYPE (+ 2 2) FORM>$
1459 An error is generated if the `PRIMTYPE` of *any* is not the same as
1460 the `TYPEPRIM` of *type*. An error will also be generated if the
1461 attempted `CHTYPE` is dangerous and/or senseless, for example,
1462 `CHTYPE`ing a `FIX` to a `SUBR`. Unfortunately, there are few useful
1463 examples we can do at this point.
1465 \[`CHTYPE`ing a `FIX` to a `FLOAT` or vice versa produces, in general,
1466 nonsense, since the bit formats for `FIX`es and `FLOAT`s are
1467 different. The `SUBR`s `FIX` and `FLOAT` convert between those
1468 formats. Useful obscurity: because of their internal representations
1469 on the PDP-10, `<CHTYPE <MAX> FIX>` gives the least possible `FIX`,
1470 and analogously for `MIN`.\]
1472 Passing note: "\# notation" is just an instruction to `READ` saying
1473 "`READ` the representation of the `PRIMTYPE` normally and (literally)
1474 `CHTYPE` it to the specified `TYPE`". \[Or, if the `PRIMTYPE` is
1475 `TEMPLATE`, "apply the `GVAL` of the `TYPE` name (which should be a
1476 `TEMPLATE` constructor) to the given elements of the `PRIMTYPE`
1477 `TEMPLATE` as arguments."\]
1479 6.4. More SUBRs Related to TYPEs
1480 --------------------------------
1486 returns a `VECTOR` (chapter 7) containing just those `ATOM`s which can
1487 currently be returned by `TYPE` or `PRIMTYPE`. This is the very
1488 "`TYPE` vector" (section 22.1) that the interpreter uses: look, but
1489 don't touch. No examples: try it, or see appendix 3.
1491 ### 6.4.2. VALID-TYPE?
1495 returns `#FALSE ()` if *atom* is not the name of a `TYPE`, and the
1496 same object that `<TYPE-C atom>` (section 19.5) returns if it is.
1500 Muddle is a type-extensible language, in the sense that the programmer
1501 can invent new `TYPE`s and use them in every way that the predefined
1502 `TYPE`s can be used. A program-defined `TYPE` is called a `NEWTYPE`.
1503 New `PRIMTYPE`s cannot be invented except by changing the interpreter;
1504 thus the `TYPEPRIM` of a `NEWTYPE` must be chosen from those already
1505 available. But the name of a `NEWTYPE` (an `ATOM` of course) can be
1506 chosen freely -- so long as it does not conflict with an existing
1507 `TYPE` name. More importantly, the program that defines a `NEWTYPE`
1508 can be included in a set of programs for manipulating objects of the
1509 `NEWTYPE` in ways that are more meaningful than the predefined `SUBR`s
1512 Typically an object of a `NEWTYPE` is a structure that is a model of
1513 some entity in the real world -- or whatever world the program is
1514 concerned with -- and the elements of the structure are models of
1515 parts or aspects of the real-world entity. A `NEWTYPE` definition is a
1516 convenient way of formalizing this correspondence, of writing it down
1517 for all to see and use rather than keeping it in your head. If the
1518 defining set of programs provides functions for manipulating the
1519 `NEWTYPE` objects in all ways that are meaningful for the intended
1520 uses of the `NEWTYPE`, then any other program that wants to use the
1521 `NEWTYPE` can call the manipulation functions for all its needs, and
1522 it need never know or care about the internal details of the `NEWTYPE`
1523 objects. This technique is a standard way of providing modularity and
1526 For example, suppose you wanted to deal with airline schedules. If you
1527 were to construct a set of programs that define and manipulate a
1528 `NEWTYPE` called `FLIGHT`, then you could make that set into a
1529 standard package of programs and call on it to handle all information
1530 pertaining to scheduled airline flights. Since all `FLIGHT`s would
1531 have the same quantity of information (more or less) and you would
1532 want quick access to individual elements, you would not want the
1533 `TYPEPRIM` to be `LIST`. Since the elements would be of various
1534 `TYPE`s, you would not want the `TYPEPRIM` to be `UVECTOR` -- nor its
1535 variations `STRING` or `BYTES`. The natural choice would be a
1536 `TYPEPRIM` of `VECTOR` (although you could gain space and lose time
1537 with `TEMPLATE` instead).
1539 Now, the individual elements of a `FLIGHT` would, no doubt, have
1540 `TYPE`s and meanings that don't change. The elements of a `FLIGHT`
1541 might be airline code, flight number, originating-airport code, list
1542 of intermediate stops, destination-airport code, type of aircraft,
1543 days of operation, etc. Each and every `FLIGHT` would have the airline
1544 code for its first element (say), the flight number for its second,
1545 and so on. It is natural to invent names (`ATOM`s) for these elements
1546 and always refer to the elements by name. For example, you could
1547 `<SETG AIRLINE 1>` or `<SETG AIRLINE <OFFSET 1 FLIGHT>>` -- and in
1548 either case `<MANIFEST AIRLINE>` so the compiler can generate more
1549 efficient code. Then, if the local value of `F` were a `FLIGHT`,
1550 `<AIRLINE .F>` would return the airline code, and `<AIRLINE .F AA>`
1551 would set the airline code to `AA`. Once that is done, you can forget
1552 about which element comes first: all you need to know are the names of
1555 The next step is to notice that, outside the package of `FLIGHT`
1556 functions, no one needs to know whether `AIRLINE` is just an offset or
1557 in fact a function of some kind. For example, the scheduled duration
1558 of a flight might not be explicitly stored in a `FLIGHT`, just the
1559 scheduled times of departure and arrival. But, if the package had the
1560 proper `DURATION` function for calculating the duration, then the call
1561 `<DURATION .F>` could return the duration, no matter how it is found.
1562 In this way the internal details of the package are conveniently
1563 hidden from view and abstracted away.
1565 The form of `NEWTYPE` definition allows for the `TYPE`s of all
1566 components of a `NEWTYPE` to be declared (chapter 14), for use both by
1567 a programmer while debugging programs that use the `NEWTYPE` and by
1568 the compiler for generating faster code. It is very convenient to have
1569 the type declaration in the `NEWTYPE` definition itself, rather than
1570 replicating it everywhere the `NEWTYPE` is used. (If you think this
1571 declaration might be obtrusive while debugging the programs in the
1572 `NEWTYPE` package, when inconsistent improvements are being made to
1573 various programs, you can either dissociate any declaration from the
1574 `NEWTYPE` or turn off Muddle type-checking completely. Actually this
1575 declaration is typically more useful to a programmer during
1576 development than it is to the compiler.)
1580 returns *atom*, after causing it to become the representation of a
1581 brand-new `TYPE` whose `PRIMTYPE` is `<TYPEPRIM type>`. What `NEWTYPE`
1582 actually does is make *atom* a legal argument to `CHTYPE` and
1583 `TYPEPRIM`. (Note that names of new `TYPE`s can be blocked lexically
1584 to prevent collision with other names, just like any other `ATOM`s --
1585 chapter 15.) Objects of a `NEWTYPE`-created `TYPE` can be generated by
1586 creating an object of the appropriate `PRIMTYPE` and using `CHTYPE`.
1587 They will be `PRINT`ed (initially), and can be directly typed in, by
1588 the use of "\# notation" as described above. `EVAL` of any object
1589 whose `TYPE` was created by `NEWTYPE` is initially the object itself,
1590 and, initially, you cannot `APPLY` something of a generated `TYPE` to
1591 arguments. But see below.
1595 <NEWTYPE GARGLE FIX>$
1599 <SET A <CHTYPE 1 GARGLE>>$
1600 #GARGLE *000000000001*
1601 <SET B #GARGLE 100>$
1602 #GARGLE *000000000144*
1608 ### 6.4.4. PRINTTYPE, EVALTYPE and APPLYTYPE
1610 <PRINTTYPE type how>
1614 <APPLYTYPE type how>
1616 all return *type*, after specifying *how* Muddle is to deal with it.
1618 These three `SUBR`s can be used to make newly-generated `TYPE`s behave
1619 in arbitrary ways, or to change the characteristics of standard Muddle
1620 `TYPE`s. `PRINTTYPE` tells Muddle how to print *type*, `EVALTYPE` how
1621 to evaluate it, and `APPLYTYPE` how to apply it in a `FORM`.
1623 *how* can be either a `TYPE` or something that can be applied to
1626 If *how* is a `TYPE`, Muddle will treat *type* just like the `TYPE`
1627 given as *how*. *how* must have the same `TYPEPRIM` as *type*.
1629 If *how* is applicable, it will be used in the following way:
1631 For `PRINTTYPE`, *how* should take one argument: the object being
1632 output. *how* should output something without formatting
1633 (`PRIN1`-style); its result is ignored. (Note: *how* cannot use an
1634 output `SUBR` on *how*'s own *type*: endless recursion will result.
1635 `OUTCHAN` is bound during the application to the `CHANNEL` in use, or
1636 to a pseudo-internal channel for `FLATSIZE` -- chapter 11.) If *how*
1637 is the `SUBR` `PRINT`, *type* will receive no special treatment in
1638 printing, that is, it will be printed as it was in an initial Muddle
1639 or immediately after its defining `NEWTYPE`.
1641 For `EVALTYPE`, *how* should take one argument: the object being
1642 evaluated. The value returned by *how* will be used as `EVAL` of the
1643 object. If *how* is the `SUBR` `EVAL`, *type* will receive no special
1644 treatment in its evaluation.
1646 For `APPLYTYPE`, *how* should take at least one argument. The first
1647 argument will be the object being applied: the rest will be the
1648 objects it was given as arguments. The result returned by *how* will
1649 be used as the result of the application. If *how* is the `SUBR`
1650 `APPLY`, *type* will receive no special treatment in application to
1653 If any of these `SUBR`s is given only one argument, that is if *how*
1654 is omitted, it returns the currently active *how* (a `TYPE` or an
1655 applicable object), or else `#FALSE ()` if *type* is receiving no
1656 special treatment in that operation.
1658 Unfortunately, these examples are fully understandable only after you
1659 have read through chapter 11.
1661 <DEFINE ROMAN-PRINT (NUMB)
1662 <COND (<OR <L=? .NUMB 0> <G? .NUMB 3999>>
1663 <PRINC <CHTYPE .NUMB TIME>>)
1665 <RCPRINT </ .NUMB 1000> '![!\M]>
1666 <RCPRINT </ .NUMB 100> '![!\C !\D !\M]>
1667 <RCPRINT </ .NUMB 10> '![!\X !\L !\C]>
1668 <RCPRINT .NUMB '![!\I !\V !\X]>)>>$
1671 <DEFINE RCPRINT (MODN V)
1672 <SET MODN <MOD .MODN 10>>
1673 <COND (<==? 0 .MODN>)
1674 (<==? 1 .MODN> <PRINC <1 .V>>)
1675 (<==? 2 .MODN> <PRINC <1 .V>> <PRINC <1 .V>>)
1676 (<==? 3 .MODN> <PRINC <1 .V>> <PRINC <1 .V>> <PRINC <1 .V>>)
1677 (<==? 4 .MODN> <PRINC <1 .V>> <PRINC <2 .V>>)
1678 (<==? 5 .MODN> <PRINC <2 .V>>)
1679 (<==? 6 .MODN> <PRINC <2 .V>> <PRINC <1 .V>>)
1680 (<==? 7 .MODN> <PRINC <2 .V>> <PRINC <1 .V>> <PRINC <1 .V>>)
1686 (<==? 9 .MODN> <PRINC <1 .V>> <PRINC <3 .V>>)>>$
1689 <PRINTTYPE TIME FIX> ;"fairly harmless but necessary here"$
1691 <PRINTTYPE FIX ,ROMAN-PRINT> ;"hee hee!"$
1697 <PRINTTYPE FIX ,PRINT>$
1700 <NEWTYPE GRITCH LIST> ;"a new TYPE of PRIMTYPE LIST"$
1704 <EVALTYPE GRITCH LIST> ;"evaluated like a LIST"$
1708 #GRITCH (A <+ 1 2 3> !<SET A "ABC">) ;"Type in one."$
1709 #GRTICH (A 6 !\A !\B !\C)
1711 <NEWTYPE HARRY VECTOR> ;"a new TYPE of PRIMTYPE VECTOR"$
1713 <EVALTYPE HARRY #FUNCTION ((X) <1 .X>)>
1714 ;"When a HARRY is EVALed, return its first element."$
1719 <NEWTYPE WINNER LIST> ;"a TYPE with funny application"$
1723 <APPLYTYPE WINNER <FUNCTION (W "TUPLE" T) (!.W !.T)>>$
1726 #FUNCTION ((W "TUPLE" T (!.W !.T))
1727 <#WINNER (A B C) <+ 1 2> q>$
1730 The following sequence makes Muddle look just like Lisp. (This example
1731 is understandable only if you know Lisp (Moon, 1974); it is included
1732 only because it is so beautiful.)
1734 <EVALTYPE LIST FORM>$
1736 <EVALTYPE ATOM ,LVAL>$
1748 To complete the job, of course, we would have to do some `SETG`'s:
1749 `car` is `1`, `cdr` is `,REST`, and `lambda` is `,FUNCTION`. If you
1750 really do this example, you should "undo" it before continuing:
1752 <EVALTYPE 'ATOM ,EVAL>$
1754 <EVALTYPE LIST ,EVAL>$
1757 Chapter 7. Structured Objects
1758 =============================
1760 This chapter discusses structured objects in general and the five
1761 basic structured `PRIMTYPE`s. \[We defer detailed discussion of the
1762 structured `PRIMTYPE`s `TUPLE` (section 9.2) and `STORAGE` (section
1768 The following `SUBR`s operate uniformly on all structured objects and
1769 generate an error if not applied to a structured object. Hereafter,
1770 *structured* represents a structured object.
1772 ### 7.1.1. LENGTH \[1\]
1776 evaluates to the number of elements in *structured*.
1778 ### 7.1.2. NTH \[1\]
1780 <NTH structured fix>
1782 evaluates to the *fix*'th element of *structured*. An error occurs if
1783 *fix* is less than 1 or greater than `<LENGTH structured>`. *fix* is
1784 optional, 1 by default.
1786 ### 7.1.3. REST \[1\]
1788 <REST structured fix>
1790 evaluates to *structured* without its first *fix* elements. *fix* is
1791 optional, 1 by default.
1793 Obscure but important side effect: `REST` actually returns
1794 *structured* "`CHTYPE`d" (but not through application of `CHTYPE`) to
1795 its `PRIMTYPE`. For example, `REST` of a `FORM` is a `LIST`. `REST`
1796 with an explicit second argument of `0` has no effect except for this
1799 ### 7.1.4. PUT \[1\]
1801 <PUT structured fix anything-legal>
1803 first makes *anything-legal* the *fix*'th element of *structured*,
1804 then evaluates to *structured*. *anything-legal* is anything which can
1805 legally be an element of *structured*; often, this is synonymous with
1806 "any Muddle object", but see below. An error occurs if *fix* is less
1807 than 1 or greater than `<LENGTH structured>`. (`PUT` is actually more
1808 general than this -- chapter 13.)
1812 <GET structured fix>
1814 evaluates the same as `<NTH structured fix>`. It is more general than
1815 `NTH`, however (chapter 13), and is included here only for symmetry
1818 ### 7.1.6. APPLYing a FIX \[1\]
1820 `EVAL` understands the application of an object of `TYPE` `FIX` as a
1821 "shorthand" call to `NTH` or `PUT`, depending on whether it is given
1822 one or two arguments, respectively \[unless the `APPLYTYPE` of `FIX`
1823 is changed\]. That is, `EVAL` considers the following two to be
1827 <NTH structured fix>
1831 <fix structured object>
1832 <PUT structured fix object>
1834 \[However, the compiler (Lebling, 1979) cannot generate efficient code
1835 from the longer forms unless it is sure that *fix* is a `FIX` (section
1836 9.10). The two constructs are not identical even to `EVAL`, if the
1837 order of evaluation is significant: for example, these two:
1839 <NTH .X <LENGTH <SET X .Y>>> <<LENGTH <SET X .Y>> .X>
1841 are **not** identical.\]
1845 `SUBSTRUC` ("substructure") facilitates the construction of structures
1846 that are composed of sub-parts of existing structures. A special case
1847 of this would be a "substring" function.
1849 <SUBSTRUC from:structured rest:fix amount:fix to:structured>
1851 copies the first *amount* elements of `<REST from rest>` into another
1852 object and returns the latter. All arguments are optional except
1853 *from*, which must be of `PRIMTYPE` `LIST`, `VECTOR`, `TUPLE` (treated
1854 like a `VECTOR`), `STRING`, `BYTES`, or `UVECTOR`. *rest* is `0` by
1855 default, and *amount* is all the elements by default. *to*, if given,
1856 receives the copied elements, starting at its beginning; it must be an
1857 object whose `TYPE` is the `PRIMTYPE` of *from* (a `VECTOR` if *from*
1858 is a `TUPLE`). If *to* is not given, a new object is returned, of
1859 `TYPE` `<PRIMTYPE from>` (a `VECTOR` if *from* is a `TUPLE`), which
1860 **never** shares with *from*. The copying is done in one fell swoop,
1861 not an element at a time. Note: due to an implementation restriction,
1862 if *from* is of `PRIMTYPE` `LIST`, it must not share any elements with
1865 7.2. Representation of Basic Structures
1866 ---------------------------------------
1868 ### 7.2.1. LIST \[1\]
1870 ( element-1 element-2 ... element-N )
1872 represents a `LIST` of *N* elements.
1874 ### 7.2.2. VECTOR \[1\]
1876 [ element-1 element-2 ... element-N ]
1878 represents a `VECTOR` of *N* elements. \[A `TUPLE` is just like a
1879 `VECTOR`, but it lives on the control stack.\]
1881 ### 7.2.3. UVECTOR \[1\]
1883 ![ element-1 element-2 ... element-N !]
1885 represents a `UVECTOR` (uniform vector) of *N* elements. The second
1886 `!` (exclamation-point) is optional for input. \[A `STORAGE` is an
1887 archaic kind of `UVECTOR` that is not garbage-collected.\]
1889 ### 7.2.4. STRING \[1\]
1893 represents a `STRING` of ASCII text. A `STRING` containing the
1894 character `"` (double-quote) is represented by placing a `\`
1895 (backslash) before the double-quote inside the `STRING`. A `\` in a
1896 `STRING` is represented by two consecutive backslashes.
1900 #n {element-1 element-2 ... element-N}
1902 represents a string of *N* uniformly-sized bytes of size *n* bits.
1906 { element-1 element-2 ... element-N }
1908 represents a `TEMPLATE` of *N* elements when output, not input -- when
1909 input, a `#` and a `TYPE` must precede it.
1911 7.3. Evaluation of Basic Structures
1912 -----------------------------------
1914 This section and the next two describe how `EVAL` treats the basic
1915 structured `TYPE`s \[in the absence of any modifying `EVALTYPE` calls
1918 `EVAL` of a `STRING` \[or `BYTES` or `TEMPLATE`\] is just the original
1921 `EVAL` acts exactly the same with `LIST`s, `VECTOR`s, and `UVECTOR`s:
1922 it generates a **new** object with elements equal to `EVAL` of the
1923 elements it is given. This is one of the simplest means of
1924 constructing a structure. However, see section 7.7.
1931 <SET FOO [5 <- 3> <TYPE "ABC">]>$
1937 <SET BAR ![("meow") (.FOO)]>$
1938 ![("meow") ([5 -3 STRING])!]
1941 <REST <1 <2 .BAR>>>$
1943 [<SUBSTRUC <1 <2 .BAR>> 0 2>]$
1945 <PUT .FOO 1 SNEAKY> ;"Watch out for .BAR !"$
1948 ![("meow") ([SNEAKY -3 STRING])!]
1949 <SET FOO <REST <1 <1 .BAR>> 2>>$
1952 ![("meow") ([SNEAKY -3 STRING])!]
1954 7.5. Generation of Basic Structures
1955 -----------------------------------
1957 Since `LIST`s, `VECTOR`s, `UVECTOR`s, and `STRING`s \[and `BYTES`es\]
1958 are all generated in a fairly uniform manner, methods of generating
1959 them will be covered together here. \[`TEMPLATE`s cannot be generated
1960 by the interpreter itself: see Lebling (1979).\]
1962 ### 7.5.1. Direct Representation \[1\]
1964 Since `EVAL` of a `LIST`, `VECTOR`, or `UVECTOR` is a new `LIST`,
1965 `VECTOR`, or `UVECTOR` with elements which are `EVAL` of the original
1966 elements, simply evaluating a representation of the object you want
1967 will generate it. (Care must be taken when representing a `UVECTOR`
1968 that all elements have the same `TYPE`.) This method of generation was
1969 exclusively used in the examples of section 7.4. Note that new
1970 `STRING`s \[and `BYTES`es\] will not be generated in this manner,
1971 since the contents of a `STRING` are not interpreted or copied by
1972 `EVAL`. The same is true of any other `TYPE` whose `TYPEPRIM` happens
1973 to be `LIST`, `VECTOR`, or `UVECTOR` \[again, assuming it neither has
1974 been `EVALTYPE`d nor has a built-in `EVALTYPE`, as do `FORM` and
1977 ### 7.5.2. QUOTE \[1\]
1979 `QUOTE` is an `FSUBR` of one argument which returns its argument
1980 unevaluated. `READ` and `PRINT` understand the character `'`
1981 (single-quote) as an abbreviation for a call to `QUOTE`, the way
1982 period and comma work for `LVAL` and `GVAL`. Examples:
1989 Any `LIST`, `VECTOR`, or `UVECTOR` in a program that is constant and
1990 need not have its elements evaluated should be represented directly
1991 and **inside a call to `QUOTE`.** This technique prevents the
1992 structure from being copied each time that portion of the program is
1993 executed. Examples hereafter will adhere to this dictum. (Note: one
1994 should **never** modify a `QUOTE`d object. The compiler will one day
1995 put it in read-only (pure) storage.)
1997 ### 7.5.3. LIST, VECTOR, UVECTOR, and STRING (the SUBRs) \[1\]
1999 Each of the `SUBR`s `LIST`, `VECTOR`, `UVECTOR`, and `STRING` takes
2000 any number of arguments and returns an object of the appropriate
2001 `TYPE` whose elements are `EVAL` of its arguments. There are
2002 limitations on what the arguments to `UVECTOR` and `STRING` may `EVAL`
2003 to, due to the nature of the objects generated. See sections 7.6.5 and
2006 `LIST`, `VECTOR`, and `UVECTOR` are generally used only in special
2007 cases, since Direct Representation usually produces exactly the same
2008 effect (in the absence of errors), and the intention is more apparent.
2009 \[Note: if `.L` is a `LIST`, `<LIST !.L>` makes a copy of `.L` whereas
2010 `(!.L)` doesn't; see section 7.7.\] `STRING`, on the other hand,
2011 produces effect very different from literal `STRING`s.
2015 <LIST 1 <+ 2 3> ABC>$
2019 <STRING "A" <2 "QWERT"> <REST "ABC"> "hello">$
2024 ### 7.5.4. ILIST, IVECTOR, IUVECTOR, and ISTRING \[1\]
2026 Each of the `SUBR`s `ILIST`, `IVECTOR`, `IUVECTOR`, and `ISTRING`
2027 ("implicit" or "iterated" whatever) creates and returns an object of
2028 the obvious `TYPE`. The format of an application of any of them is
2030 < Ithing number-of-elements:fix expression:any >
2032 where *Ithing* is one of `ILIST`, `IVECTOR`, `IUVECTOR`, or `ISTRING`.
2033 An object of `LENGTH` *number-of-elements* is generated, whose
2034 elements are `EVAL` of *expression*.
2036 *expression* is optional. When it is not specified, `ILIST`,
2037 `IVECTOR`, and `IUVECTOR` return objects filled with objects of `TYPE`
2038 `LOSE` (`PRIMTYPE` `WORD`) as place holders, a `TYPE` which can be
2039 passed around and have its `TYPE` checked, but otherwise is an illegal
2040 argument. If *expression* is not specified in `ISTRING`, you get a
2041 `STRING` made up of `^@` characters.
2043 When *expression* is supplied as an argument, it is re-`EVAL`uated
2044 each time a new element is generated. (Actually, `EVAL` of
2045 *expression* is re-`EVAL`uated, since all of these are `SUBR`s.) See
2046 the last example for how this argument may be used.
2048 \[By the way, in a construct like `<IUVECTOR 9 '.X>`, even if the
2049 `LVAL` of `X` evaluates to itself, so that the `'` could be omitted
2050 without changing the result, the compiler is much happier with the `'`
2053 `IUVECTOR` and `ISTRING` again have limitations on what *expression*
2054 may `EVAL` to; again, see sections 7.6.5 and 7.6.6.
2061 [#LOSE *000000000000* #LOSE *000000000000*]
2065 <IUVECTOR 9 '<SET A <+ .A 1>>>$
2066 ![1 2 3 4 5 6 7 8 9!]
2068 ### 7.5.5. FORM and IFORM
2070 Sometimes the need arises to create a `FORM` without `EVAL`ing it or
2071 making it the body of a `FUNCTION`. In such cases the `SUBR`s `FORM`
2072 and `IFORM` ("implicit form") can be used (or `QUOTE` can be used).
2073 They are entirely analogous to `LIST` and `ILIST`. Example:
2075 <DEFINE INC-FORM (A)
2076 <FORM SET .A <FORM + 1 <FORM LVAL .A>>>>$
2079 <SET FOO <+ 1 .FOO>>
2081 7.6. Unique Properties of Primitive TYPEs
2082 -----------------------------------------
2084 ### 7.6.1. LIST (the PRIMTYPE) \[1\]
2086 An object of `PRIMTYPE` `LIST` may be considered as a "pointer chain"
2087 (appendix 1). Any Muddle object may be an element of a `PRIMTYPE`
2088 `LIST`. It is easy to add and remove elements of a `PRIMTYPE` `LIST`,
2089 but the higher N is, the longer it takes to refer to the Nth element.
2090 The `SUBR`s which work only on objects of `PRIMTYPE` `LIST` are these:
2092 #### 7.6.1.1. PUTREST \[1\]
2094 <PUTREST head:primtype-list tail:primtype-list>
2096 changes *head* so that `<REST head>` is *tail* (actually
2097 `<CHTYPE tail LIST>`), then evaluates to *head*. Note that this
2098 actually changes *head*; it also changes anything having *head* as an
2099 element or a value. For example:
2101 <SET BOW [<SET ARF (B W)>]>$
2103 <PUTREST .ARF '(3 4)>$
2108 `PUTREST` is probably most often used to splice lists together. For
2109 example, given that `.L` is of `PRIMTYPE` `LIST`, to leave the first
2110 *m* elements of it intact and take out the next *n* elements of it,
2111 `<PUTREST <REST .L <- m 1>> <REST .L <+ m n>>>`. Specifically,
2113 <SET NUMS (1 2 3 4 5 6 7 8 9)>$
2115 <PUTREST <REST .NUMS 3> <REST .NUMS 7>>$
2124 ("construct") adds *new* to the front of *list*, without copying
2125 *list*, and returns the resulting `LIST`. References to *list* are not
2128 \[Evaluating `<CONS .E .LIST>` is equivalent to evaluating
2129 `(.E !.LIST)` (section 7.7) but is less preferable to the compiler
2132 ### 7.6.2. "Array" PRIMTYPEs \[1\]
2134 `VECTORS`, `UVECTOR`s, and `STRING`s \[and `BYTES`es and `TEMPLATE`s\]
2135 may be considered as "arrays" (appendix 1). It is easy to refer to the
2136 Nth element irrespective of how large N is, and it is relatively
2137 difficult to add and delete elements. The following `SUBR`s can be
2138 used only with an object of `PRIMTYPE` `VECTOR`, `UVECTOR`, or
2139 `STRING` \[or `BYTES` or `TEMPLATE`\]. (In this section *array*
2140 represents an object of such a `PRIMTYPE`.)
2142 #### 7.6.2.1. BACK \[1\]
2146 This is the opposite of `REST`. It evaluates to *array*, with *fix*
2147 elements put back onto its front end, and changed to its `PRIMTYPE`.
2148 *fix* is optional, 1 by default. If *fix* is greater than the number
2149 of elements which have been `REST`ed off, an error occurs. Example:
2151 <SET ZOP <REST '![1 2 3 4] 3>>$
2155 <SET S <REST "Right is might." 15>>$
2160 #### 7.6.2.2. TOP \[1\]
2164 "`BACK`s up all the way" -- that is, evaluates to *array*, with all
2165 the elements which have been `REST`ed off put back onto it, and
2166 changed to its `PRIMTYPE`. Example:
2171 ### 7.6.3. "Vector" PRIMTYPEs
2175 <GROW vu end:fix beg:fix>
2177 adds/removes elements to/from either or both ends of *vu*, and returns
2178 the entire (`TOP`ped) resultant object. *vu* can be of `PRIMTYPE`
2179 `VECTOR` or `UVECTOR`. *end* specifies a lower bound for the number of
2180 elements to be added to the **end** of *vu*; *beg* specifies the same
2181 for the **beginning**. A negative *fix* specifies removal of elements.
2183 The number of elements added to each respective end is *end* or *beg*
2184 **increased** to an integral multiple of *X*, where *X* is 32 for
2185 `PRIMTYPE` `VECTOR` and 64 for `PRIMTYPE` `UVECTOR` (`1` produces 32
2186 or 64; `-1` produces 0). The elements added will be `LOSE`s if *vu* is
2187 of `PRIMTYPE` `VECTOR`, and "empty" whatever-they-are's if *vu* is of
2188 `PRIMTYPE` `UVECTOR`. An "empty" object of `PRIMTYPE` `WORD` contains
2189 zero. An "empty" object of any other `PRIMTYPE` has zero in its "value
2190 word" (appendix 1) and is not safe to play with: it should be replaced
2193 Note that, if elements are added to the beginning of *vu*,
2194 previously-existing references to *vu* will have to use `TOP` or
2195 `BACK` to get at the added elements.
2197 **Caution:** `GROW` is a **very** expensive operation; it **requires**
2198 a garbage collection (section 22.4) **every** time it is used. It
2199 should be reserved for **very special** circumstances, such as where
2200 the pattern of shared elements is terribly important.
2207 ![0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2208 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2209 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1!]
2215 This `SUBR` will sort `PRIMTYPE`s `VECTOR`, `UVECTOR` and `TUPLE`
2216 (section 9.2). It works most efficiently if the sort keys are of
2217 `PRIMTYPE` `WORD`, `ATOM` or `STRING`. However, the keys may be of any
2218 `TYPE`, and `SORT` will still work. `SORT` acts on fixed-length
2219 records which consist of one or more contiguous elements in the
2220 structure being sorted. One element in the record is declared to be
2221 the sort key. Also, any number of additional structures can be
2222 rearranged based on how the main structure is sorted.
2224 <SORT pred s1 l1 off s2 l2 s3 l3 sN lN>
2228 *pred* is either (see chapter 8 for information about predicates):
2230 1. `TYPE` `FALSE`, in which case the `TYPE`s of all the sort keys
2231 must be the same; they must be of `PRIMTYPE` `WORD`, `STRING` or
2232 `ATOM`; and a radix-exchange sort is used; or
2233 2. something applicable to two sort keys which returns `TYPE` `FALSE`
2234 if the first is not bigger than the second, in which case a shell
2235 sort is used. For example, `,G?` sorts numbers in ascending order,
2236 `,L?` in descending order. Note: if your *pred* is buggy, the
2237 `SORT` may never terminate.
2239 *s1* ... *sN* are the (`PRIMTYPE`) `VECTOR`s, `UVECTOR`s or `TUPLE`s
2240 being sorted, and *s1* contains the sort keys;
2242 *l1* ... *lN* are the corresponding lengths of sort records (optional,
2243 one by default); and
2245 *off* is the offset from start of record to sort key (optional, zero
2248 `SORT` returns the sorted *s1* as a value.
2250 Note: the `SUBR` `SORT` calls the `RSUBR` (chapter 19) `SORTX`; if the
2251 `RSUBR` must be loaded, you may see some output from the loader on
2256 <SORT <> <SET A <IUVECTOR 500 '<RANDOM>>>>$
2259 sorts a `UVECTOR` of random integers.
2261 <SET V [1 MONEY 2 SHOW 3 READY 4 GO]>$
2264 [4 GO 1 MONEY 3 READY 2 SHOW]
2267 [4 GO 3 READY 2 SHOW 1 MONEY]
2269 [4 GO 3 READY 2 SHOW 1 MONEY]
2271 <SORT <> ![2 1 4 3 6 5 8 7] 1 0 .V>$
2274 [GO 4 READY 3 SHOW 2 MONEY 1]
2276 The first sort was based on the `ATOM`s' `PNAME`s, considering records
2277 to be two elements. The second one sorted based on the `FIX`es. The
2278 third interchanged pairs of elements of each of its structured
2281 ### 7.6.4. VECTOR (the PRIMTYPE) \[1\]
2283 Any Muddle object may be an element of a `PRIMTYPE` `VECTOR`. A
2284 `PRIMTYPE` `VECTOR` takes two words of storage more than an equivalent
2285 `PRIMTYPE` `LIST`, but takes it all in a contiguous chunk, whereas a
2286 `PRIMTYPE` `LIST` may be physically spread out in storage (appendix
2287 1). There are no `SUBR`s or `FSUBR`s which operate only on `PRIMTYPE`
2290 ### 7.6.5. UVECTOR (the PRIMTYPE) \[1\]
2292 The difference between `PRIMTYPE`s `UVECTOR` and `VECTOR` is that
2293 every element of a `PRIMTYPE` `UVECTOR` must be of the same `TYPE`. A
2294 `PRIMTYPE` `UVECTOR` takes approximately half the storage of a
2295 `PRIMTYPE` `VECTOR` or `PRIMTYPE` `LIST` and, like a `PRIMTYPE`
2296 `VECTOR`, takes it in a contiguous chunk (appendix 1).
2298 \[Note: due to an implementation restriction (appendix 1), `PRIMTYPE`
2299 `STRING`s, `BYTES`es, `LOCD`s (chapter 12), and objects on the control
2300 stack (chapter 22) may **not** be elements of `PRIMTYPE` `UVECTOR`s.\]
2302 The "same `TYPE`" restriction causes an equivalent restriction to
2303 apply to `EVAL` of the arguments to either of the `SUBR`s `UVECTOR` or
2304 `IUVECTOR`. Note that attempting to say
2308 will cause `READ` to produce an error, since you're attempting to put
2309 a `FORM` and a `FIX` into the same `UVECTOR`. On the other hand,
2313 is legal, and will `EVAL` to the appropriate `UVECTOR` without error
2314 if `.A` `EVAL`s to a `TYPE` `FIX`.
2316 The following `SUBR`s work on `PRIMTYPE` `UVECTOR`s along.
2318 #### 7.6.5.1. UTYPE \[1\]
2320 <UTYPE primtype-uvector>
2322 ("uniform type") evaluates to the `TYPE` of every element in its
2328 #### 7.6.5.2. CHUTYPE \[1\]
2330 <CHUTYPE uv:primtype-uvector type>
2332 ("change uniform type") changes the `UTYPE` of *uv* to *type*,
2333 simultaneously changing the `TYPE` of all elements of *uv*, and
2334 returns the new, changed, *uv*. This works only when the `PRIMTYPE` of
2335 the elements of *uv* can remain the same through the whole procedure.
2336 (Exception: a *uv* of `UTYPE` `LOSE` can be `CHUTYPE`d to any *type*
2337 (legal in a `UVECTOR` of course); the resulting elements are "empty",
2340 `CHUTYPE` actually changes *uv*; hence **all** references to that
2341 object will reflect the change. This is quite different from `CHTYPE`.
2345 <SET LOST <IUVECTOR 2>>$
2346 ![#LOSE *000000000000* #LOSE *000000000000*!]
2349 <CHUTYPE .LOST FORM>$
2353 <CHUTYPE .LOST LIST>$
2356 ### 7.6.6. STRING (the PRIMTYPE) and CHARACTER \[1\]
2358 The best mental image of a `PRIMTYPE` `STRING` is a `PRIMTYPE`
2359 `UVECTOR` of `CHARACTER`s -- where `CHARACTER` is the Muddle `TYPE`
2360 for a single ASCII character. The representation of a `CHARACTER`, by
2363 !\any-ASCII-character
2365 That is, the characters `!\` (exclamation-point backslash) preceding a
2366 single ASCII character represent the corresponding object of `TYPE`
2367 `CHARACTER` (`PRIMTYPE` `WORD`). (The characters `!"`
2368 (exclamation-point double-quote) preceding a character are also
2369 acceptable for inputting a `CHARACTER`, for historical reasons.)
2371 The `SUBR` `ISTRING` will produce an error if you give it an argument
2372 that produces a non-`CHARACTER`. `STRING` can take either `CHARACTER`s
2375 There are no `SUBR`s which uniquely manipulate `PRIMTYPE` `STRING`s,
2376 but some are particularly useful in connection with them:
2378 #### 7.6.6.1. ASCII \[1\]
2380 <ASCII fix-or-character>
2382 If its argument is of `TYPE` `FIX`, `ASCII` evaluates to the
2383 `CHARACTER` with the 7-bit ASCII code of its argument. Example:
2384 `<ASCII 65>` evaluates to `!\A`.
2386 If its argument is of `TYPE` `CHARACTER`, `ASCII` evaluates to the
2387 `FIX`ed-point number which is its argument's 7-bit ASCII code.
2388 Example: `<ASCII !\Z>` evaluates to `90`.
2390 \[Actually, a `FIX` can be `CHTYPE`d to a `CHARACTER` (or vice versa)
2391 directly, but `ASCII` checks in the former case that the `FIX` is
2392 within the permissible range.\]
2394 #### 7.6.6.2. PARSE \[1\]
2396 <PARSE string radix:fix>
2398 `PARSE` applies to its argument `READ`'s algorithm for converting
2399 ASCII representations to Muddle objects and returns the **first**
2400 object created. The remainder of *string*, after the first object
2401 represented, is ignored. *radix* (optional, ten by default) is used
2402 for converting any `FIX`es that occur. \[See also sections 15.7.2 and
2403 17.1.3 for additional arguments.\]
2405 #### 7.6.6.3. LPARSE \[1\]
2407 `LPARSE` ("list parse") is exactly like `PARSE` (above), except that
2408 it parses the **entire** *string* and returns a `LIST` of **all**
2409 objects created. If given an empty `STRING` or one containing only
2410 separators, `LPARSE` returns an empty `LIST`, whereas `PARSE` gets an
2413 #### 7.6.6.4. UNPARSE \[1\]
2415 <UNPARSE any radix:fix>
2417 `UNPARSE` applies to its argument `PRINT`'s algorithm for converting
2418 Muddle objects to ASCII representations and returns a `STRING` which
2419 contains the `CHARACTER`s `PRINT` would have typed out. \[However,
2420 this `STRING` will **not** contain any of the gratuitous
2421 carriage-returns `PRINT` adds to accommodate a `CHANNEL`'s finite
2422 line-width (section 11.2.8).\] *radix* (optional, ten by default) is
2423 used for converting any `FIX`es that occur.
2427 A (`PRIMTYPE`) `BYTES` is a string of uniformly-sized bytes. The bytes
2428 can be any size between 1 and 36 bits inclusive. A `BYTES` is similar
2429 in some ways to a `UVECTOR` of `FIX`es and in some ways to a `STRING`
2430 of non-seven-bit bytes. The elements of a `BYTES` are always of `TYPE`
2433 The `SUBR`s `BYTES` and `IBYTES` are similar to `STRING` and
2434 `ISTRING`, respectively, except that each of the former takes a first
2435 argument giving the size of the bytes in the generated `BYTES`.
2436 `BYTES` takes one required argument which is a `FIX` specifying a byte
2437 size and any number of `PRIMTYPE` `WORD`s. It returns an object of
2438 `TYPE` `BYTES` with that byte size containing the objects as elements.
2439 These objects will be `ANDB`ed with the appropriate mask of 1-bits to
2440 fit in the byte size. `IBYTES` takes two required `FIX`es and one
2441 optional argument. It uses the first `FIX` to specify the byte size
2442 and the second to specify the number of elements. The third argument
2443 is repeatedly evaluated to generate `FIX`es that become elements of
2444 the `BYTES` (if it is omitted, bytes filled with zeros are generated).
2445 The analog to `UTYPE` is `BYTE-SIZE`. Examples:
2447 <BYTES 3 <+ 2 2> 9 -1>$
2451 <IBYTES 3 9 '<SET A <+ .A 1>>>$
2452 #3 {1 2 3 4 5 6 7 0 1}
2455 <BYTE-SIZE <BYTES 1>>$
2460 A `TEMPLATE` is similar to a PL/I "structure" of one level: the
2461 elements are packed together and reduced in size to save storage
2462 space, while an auxiliary internal data structure describes the
2463 packing format and the elements' real `TYPE`s (appendix 1). The
2464 interpreter is not able to create objects of `PRIMTYPE` `TEMPLATE`
2465 (Lebling, 1979); however, it can apply the standard built-in
2466 Subroutines to them, with the same effects as with other "arrays".
2471 Objects of `TYPE` `SEGMENT` (whose `TYPEPRIM` is `LIST`) look very
2472 much like `FORM`s. `SEGMENT`s, however, undergo a non-standard
2473 evaluation designed to ease the construction of structured objects
2474 from elements of other structured objects.
2476 ### 7.7.1. Representation \[1\]
2478 The representation of an object of `TYPE` `SEGMENT` is the following:
2480 !< func arg-1 arg-2 ... arg-N !>
2482 where the second `!` (exclamation-point) is optional, and *fun* and
2483 *arg-1* through *arg-N* are any legal constituents of a `FORM` (that
2484 is, anything). The pointed brackets can be implicit, as in the period
2485 and comma notation for `LVAL` and `GVAL`.
2487 All of the following are `SEGMENT`s:
2489 !<3 .FOO> !.FOO !,FOO
2491 ### 7.7.2. Evaluation \[1\]
2493 A `SEGMENT` is evaluated in exactly the same manner as a `FORM`, with
2494 the following three exceptions:
2496 1. It had better be done inside an `EVAL` of a structure; otherwise
2497 an error occurs. (See special case of `FORM`s in section 7.7.5.)
2498 2. It had better `EVAL` to a structured object; otherwise an error
2500 3. What actually gets inserted into the structure being built are the
2501 elements of the structure returned by the `FORM`-like evaluation.
2503 ### 7.7.3 Examples \[1\]
2505 <SET ZOP '![2 3 4]>$
2511 ![!.ZOP !<REST .ARF>!]$
2517 (!\S !\T !\R !\U !\N !\G !\.)
2524 ### 7.7.4. Note on Efficiency \[1\]
2526 Most of the cases in which is is possible to use `SEGMENT`s require
2527 `EVAL` to generate an entire new object. Naturally, this uses up both
2528 storage and time. However, there is one case which it is possible to
2529 handle without copying, and `EVAL` uses it. When the structure being
2530 built is a `PRIMTYPE` `LIST`, and the segment value of a `PRIMTYPE`
2531 `LIST` is the last (rightmost) element being concatenated, that last
2532 `PRIMTYPE` `LIST` is not copied. This case is similar to `CONS` and is
2533 the principle reason why `PRIMTYPE` `LIST`s have their structures more
2534 easily varied than `PRIMTYPE` `VECTOR` or `UVECTOR`.
2541 This does not copy ARF:
2548 (1 !.ARF 2) ;"not last element"$
2550 [1 2 !.ARF] ;"not PRIMTYPE LIST"$
2552 (1 2 !.ARF !<REST '(1)>) ;"still not last element"$
2555 Note the following, which occurs because copying does **not** take
2558 <SET DOG (A !.ARF)>$
2560 <PUT .ARF 1 "BOWOW">$
2564 <PUT .DOG 3 "WOOF">$
2565 (A "BOWOW" "WOOF" 4)
2569 Since `ARF` was not copied, it was literally part of `DOG`. Hence,
2570 when an element of `ARF` was changed, `DOG` was changed. Similarly,
2571 when an element of `DOG` which `ARF` shared was changed, `ARF` was
2574 ### 7.7.5. SEGMENTs in FORMs \[1\]
2576 When a `SEGMENT` appears as an element of a `FORM`, the effect is
2577 approximately the same as if the elements of the `EVAL` of the
2578 `SEGMENT` were in the `FORM`. Example:
2580 <SET A '![1 2 3 4]>$
2585 Note: the elements of the structure segment-evaluated in a `FORM` are
2586 **not** re-evaluated if the thing being applied is a `SUBR`. Thus if
2587 `.A` were `(1 2 <+ 3 4> 5)`, the above example would produce an error:
2588 you can't add up `FORM`s.
2590 You could perform the same summation of `5` and the elements of `A` by
2593 <EVAL <CHTYPE (+ !.A 5) FORM>>
2595 (Note that `EVAL` must be explicitly called as a `SUBR`; if it were
2596 not so called, you would just get the `FORM` `<+ 1 2 3 4 5>` -- not
2597 its "value".) However, the latter is more expensive both in time and
2598 in storage: when you use the `SEGMENT` directly in the `FORM`, a new
2599 `FORM` is, in fact, **not** generated as it is in the latter case.
2600 (The elements are put on "the control stack" with the other
2603 7.8. Self-referencing Structures
2604 --------------------------------
2606 It is possible for a structured object to "contain" itself, either as
2607 a subset or as an element, as an element of a structured element, etc.
2608 Such an object cannot be `PRINT`ed, because recursion begins and never
2609 terminates. Warning: if you try the examples in this section with a
2610 live Muddle, be sure you know how to use `^S` (section 1.2) to save
2611 `PRINT` from endless agony. (Certain constructs with `ATOM`s can give
2612 `PRINT` similar trouble: see chapters 12 and 15.)
2614 ### 7.8.1. Self-subset
2616 <PUTREST head:primtype-list tail:primtype-list>
2618 If *head* is a subset of *tail*, that is, if `<REST tail fix>` is the
2619 same object as `<REST head 0>` for some *fix*, then both *head* and
2620 *tail* will be "circular" (and this self-referencing) after the
2623 <SET WALTZ (1 2 3)>$
2625 <PUTREST <REST .WALTZ 2> .WALTZ>$
2626 (3 1 2 3 1 2 3 1 2 3 1 2 3 ...
2628 ### 7.8.2. Self-element
2630 <PUT s1:structured fix s2:structured>
2632 If *s1* is the same object as *s2*, then it will "contain" itself (and
2633 thus be self-referencing) after the `PUT`. Examples:
2635 <SET S <LIST 1 2 3>> ;"or VECTOR"$
2638 (1 2 (1 2 (1 2 (1 2 ...
2644 Test your reaction time or your terminal's bracket-maker. Amaze your
2650 8.1. Truth Values \[1\]
2651 -----------------------
2653 Muddle represents "false" with an object of a particular `TYPE`:
2654 `TYPE` `FALSE` (unsurprisingly). `TYPE` `FALSE` is structured: its
2655 `PRIMTYPE` is `LIST`. Thus, you can give reasons or excuses by making
2656 them elements of a `FALSE`. (Again, `EVAL`ing a `FALSE` neither copies
2657 it nor `EVAL`s its elements, so it is not necessary to `QUOTE` a
2658 `FALSE` appearing in a program.) Objects of `TYPE` `FALSE` are
2659 represented in "\# notation":
2661 #FALSE list-of-its-elements
2663 The empty `FORM` evaluates to the empty `FALSE`:
2668 Anything which is not `FALSE`, is, reasonably enough, true. In this
2669 document the "data type" *false-or-any* in metasyntactic variables
2670 means that the only significant attribute of the object in that
2671 context is whether its `TYPE` is `FALSE` or not.
2673 8.2. Predicates \[1\]
2674 ---------------------
2676 There are numerous Muddle F/SUBRs which can return a `FALSE` or a
2677 true. See appendix 2 to find them all. Most return either `#FALSE ()`
2678 or the `ATOM` with `PNAME` `T`. (The latter is for historical reasons,
2679 namely Lisp (Moon, 1974).) Some predicates which are meaningful now
2682 ### 8.2.1. Arithmetic \[1\]
2686 evaluates to `T` only if its argument is identically equal to `0` or
2691 evaluates to `T` only if its argument is identically equal to `1` or
2694 <G? n:fix-or-float m:fix-or-float>
2696 evaluates to `T` only if *n* is algebraically greater than *m*. `L=?`
2697 is the Boolean complement of `G?`; that is, it is `T` only if *n* is
2698 not algebraically greater than *m*.
2700 <L? n:fix-or-float m:fix-or-float>
2702 evaluates to `T` only if *n* is algebraically less than *m*. `G=?` is
2703 the Boolean complement of `L?`.
2705 ### 8.2.2. Equality and Membership \[1\]
2709 evaluates to `T` only if *e1* is the **same object** as *e2* (appendix
2710 1). Two objects that look the same when `PRINT`ed may not be `==?`.
2711 Two `FIX`es of the same "value" are "the same object"; so are two
2712 `FLOAT`s of **exactly** the same "value". Empty objects of `PRIMTYPE`
2713 `LIST` (and no other structured `PRIMTYPE`) are `==?` if their `TYPE`s
2714 are the same. Example:
2716 <==? <SET X "RANDOM STRING"> <TOP <REST .X 6>>>$
2718 <==? .X "RANDOM STRING">$
2721 `N==?` is the Boolean complement of `==?`.
2725 evaluates to `T` if *e1* and *e2* have the same `TYPE` and are
2726 structurally equal -- that is, they "look the same", their printed
2727 representations are the same. `=?` is much slower than `==?`. `=?`
2728 should be used only when its characteristics are necessary: they are
2729 not in any comparisons of unstructured objects. `==?` and `=?` always
2730 return the same value for `FIX`es, `FLOAT`s, `ATOM`s, etc.
2731 (Mnemonically, `==?` tests for "more equality" than `=?`; in fact, it
2732 tests for actual physical identity.)
2734 Example, illustrating non-copying of a `SEGMENT` in Direct
2735 Representation of a `LIST`:
2741 <==? .A <SET B <LIST !.A>>>$
2746 `N=?` is the Boolean complement of `=?`.
2748 <MEMBER object:any structured>
2750 runs down *structured* from first to last element, comparing each
2751 element of *structured* with *object*. If it finds an element of
2752 *structured* which is `=?` to *object*, it returns
2753 `<REST structured i>` (which is of `TYPE` `<PRIMTYPE structured>`),
2754 where the (*i*+1)th element of *structured* is `=?` to *object*. That
2755 is, the first element of what it returns is the **first** element of
2756 *structured* that is `=?` to *object*.
2758 If no element of *structured* is `=?` to *object*, `MEMBER` returns
2761 The search is more efficient if *structured* is of `PRIMTYPE` `VECTOR`
2762 (or `UVECTOR`, if possible) than if it is of `PRIMTYPE` `LIST`. As
2763 usual, if *structured* is constant, it should be `QUOTE`d.
2765 If *object* and *structured* are of `PRIMTYPE` `STRING` \[or
2766 `BYTES`\], `MEMBER` does a substring search. Example:
2768 <MEMBER "PART" "SUM OF PARTS">$
2771 `<MEMQ object:any structured>` ("member quick") is exactly the same as
2772 `MEMBER`, except that the comparison test is `==?`.
2776 ("string comparison") can be given either two `STRING`s or two `ATOM`s
2777 as arguments. In the latter case the `PNAME`s are used. It actually
2778 isn't a predicate, since it can return three possible values: `0` if
2779 *s1* is `=?` to *s2*; `1` if *s1* sorts alphabetically after *s2*; and
2780 `-1` if *s1* sorts alphabetically before *s2*. "Alphabetically" means,
2781 in this case, according to the numeric order of ASCII, with the
2782 standard alphabetizing rules.
2784 \[A predicate suitable for an ascending `SORT` (which see) is
2785 `<G? <STRCOMP .ARG1 .ARG2> 0>`.\]
2787 ### 8.2.3. Boolean Operators \[1\]
2789 <NOT e:false-or-any>
2791 evaluates to `T` only if *e* evaluates to a `FALSE`, and to
2792 `#FALSE ()` otherwise.
2796 `AND` is an `FSUBR`. It evaluates its arguments from first to last as
2797 they appear in the `FORM`. As soon as one of them evaluates to a
2798 `FALSE`, it returns that `FALSE`, ignoring any remaining arguments. If
2799 none of them evaluate to `FALSE`, it returns `EVAL` of its last
2800 argument. `<AND>` returns `T`. `AND?` is the `SUBR` equivalent to
2801 `AND`, that is, all its arguments are evaluated before any of them is
2806 `OR` is an `FSUBR`. It evaluates its arguments from first to last as
2807 they appear in the `FORM`. As soon as one of them evaluates to a
2808 non-`FALSE`, it returns that non-`FALSE` value, ignoring any remaining
2809 arguments. If this never occurs, it returns the last `FALSE` it saw.
2810 `<OR>` returns `#FALSE ()`. `OR?` is the `SUBR` equivalent to `OR`.
2812 ### 8.2.4. Object Properties \[1\]
2814 <TYPE? any type-1 ... type-N>
2816 evaluates to *type-i* only if `<==? type-i <TYPE any>>` is true. It is
2817 faster and gives more information than `OR`ing tests for each `TYPE`.
2818 If the test fails for all *type-i*'s, `TYPE?` returns `#FALSE ()`.
2822 evaluates to `T` only if *e* is of a `TYPE` that can legally be
2823 applied to arguments in a `FORM`, that is, be (`EVAL` of) the first
2824 element of a `FORM` being evaluated (appendix 3).
2828 evaluates to `#FALSE ()` only if `NTH` and `REST` (with non-zero
2829 second argument) can be performed on its argument without error. An
2830 unstructured or empty structured object will cause `MONAD?` to return
2835 evaluates to `T` only if *e* is a structured object. It is **not** the
2836 inverse of `MONAD?`, since each returns `T` if its argument is an
2841 evaluates to `T` only if its argument, which must be a structured
2842 object, has no elements.
2844 <LENGTH? structured fix>
2846 evaluates to `<LENGTH structured>` only if that is less than or equal
2847 to *fix*; otherwise, it evaluates to `#FALSE ()`. Mnemonically, you
2848 can think of the first two letters of `LENGTH?` as signifying the
2849 "less than or equal to" sense of the test.
2851 This `SUBR` was invented to use on lists, because Muddle can determine
2852 their lengths only by stepping along the list, counting the elements.
2853 If a program needs to know only how the length compares with a given
2854 number, `LENGTH?` will tell without necessarily stepping all the way
2855 to the end of the list, in contrast to `LENGTH`.
2857 \[If *structured* is a circular `PRIMTYPE` `LIST`, `LENGTH?` will
2858 return a value, whereas `LENGTH` will execute forever. To see if you
2859 can do `<REST structured <+ 1 fix>>` without error, do the test
2860 `<NOT <LENGTH? structured fix>>`.\]
2865 The Muddle Subroutine which is most used for varying evaluation
2866 depending on a truth value is the `FSUBR` `COND` ("conditional"). A
2867 call to `COND` has this format:
2869 <COND clause-1:list ... clause-N:list>
2871 where *N* is at least one.
2873 `COND` always returns the result of the **last** evaluation it
2874 performs. The following rules determine the order of evaluations
2877 1. Evaluate the first element of each clause (from first to last)
2878 until either a non-`FALSE` object results or the clauses are
2880 2. If a non-`FALSE` object is found in (1), immediately evaluate the
2881 remaining elements (if any) of that clause and ignore any
2884 In other words, `COND` goes walking down its clauses, `EVAL`ing the
2885 first element of each clause, looking for a non-`FALSE` result. As
2886 soon as it finds a non-`FALSE`, it forgets about all the other clauses
2887 and evaluates, in order, the other elements of the current clause and
2888 returns the last thing it evaluates. If it can't find a non-`FALSE`,
2889 it returns the last `FALSE` it saw.
2895 <COND (<EMPTY? .F> EMP) (<1? <LENGTH .F>> ONE)>$
2899 <COND (<EMPTY? .F> EMP) (<1? <LENGTH .F>> ONE)>$
2903 <COND (<EMPTY? .F> EMP) (<1? <LENGTH .F>> ONE)>$
2905 <COND (<LENGTH? .F 2> SMALL) (BIG)>$
2908 <DEFINE FACT (N) ;"the standard recursive factorial"
2910 (ELSE <* .N <FACT <- .N 1>>>)>>$
2915 8.4. Shortcuts with Conditionals
2916 --------------------------------
2918 ### 8.4.1. AND and OR as Short CONDs
2920 Since `AND` and `OR` are `FSUBR`s, they can be used as miniature
2921 `COND`s. A construct of the form
2923 <AND pre-conditions action(s)>
2927 <OR pre-exclusions action(s)>
2929 will allow *action(s)* to be evaluated only if all the
2930 *pre-conditions* are true or only if all the *pre-exclusions* are
2931 false, respectively. By nesting and using both `AND` and `OR`, fairly
2932 powerful constructs can be made. Of course, if *action(s)* are more
2933 than one thing, you must be careful that none but the last returns
2934 false or true, respectively. Watch out especially for `TERPRI`
2935 (chapter 11). Examples:
2937 <AND <ASSIGNED? FLAG> .FLAG <FCN .ARG>>
2939 applies `FCN` only if someone else has `SET` `FLAG` to true.
2940 (`ASSIGNED?` is true if its argument `ATOM` has an `LVAL`.) No error
2941 can occur in the testing of `FLAG` because of the order of evaluation.
2943 <AND <SET C <OPEN "READ" "A FILE">> <LOAD .C> <CLOSE .C>>
2945 effectively `FLOAD`s the file (chapter 11) without the possibility of
2946 getting an error if the file cannot be opened.
2948 ### 8.4.2. Embedded Unconditionals
2950 One of the disadvantages of `COND` is that there is no straightforward
2951 way to do things unconditionally in between tests. One way around this
2952 problem is to insert a dummy clause that never succeeds, because its
2953 only `LIST` element is an `AND` that returns a `FALSE` for the test.
2956 <COND (<0? .N> <F0 .N>)
2958 (<AND <SET N <* 2 <FIX </ .N 2>>>>
2959 ;"Round .N down to even number."
2961 (<LENGTH? .VEC .N> '[])
2962 (T <REST .VEC <+ 1 .N>>)>
2964 A variation is to make the last `AND` argument into the test for the
2965 `COND` clause. (That is, the third and fourth clauses in the above
2966 example can be combined.) Of course, you must be careful that no other
2967 `AND` argument evaluates to a `FALSE`; most Subroutines do not return
2968 a `FALSE` without a very good reason for it. (A notable exception is
2969 `TERPRI` (which see).) Even safer is to use `PROG` (section 10.1)
2972 Another variation is to increase the nesting with a new `COND` after
2973 the unconditional part. At least this method does not make the code
2974 appear to a human reader as though it does something other than what
2975 it really does. The above example could be done this way:
2977 <COND (<0? .N> <F0 .N>)
2980 <SET N <* 2 <FIX </ .N 2>>>>
2981 <COND (<LENGTH? .VEC .N> '[])
2982 (T <REST .VEC <+ 1 .N>>)>)>
2984 Chapter 9. Functions
2985 ====================
2987 This chapter could be named "fun and games with argument `LIST`s". Its
2988 purpose is to explain the more complicated things which can be done
2989 with `FUNCTION`s, and this involves, basically, explaining all the
2990 various tokens which can appear in the argument `LIST` of a
2991 `FUNCTION`. Topics are covered in what is approximately an order of
2992 increasing complexity. This order has little to do with the order in
2993 which tokens can actually appear in an argument `LIST`, so what an
2994 argument `LIST` "looks like" overall gets rather lost in the shuffle.
2995 To alleviate this problem, section 9.9 is a summary of everything that
2996 can go into an argument `LIST`, in the correct order. If you find
2997 yourself getting lost, please refer to that summary.
2999 9.1. "OPTIONAL" \[1\]
3000 ---------------------
3002 Muddle provides very convenient means for allowing optional arguments.
3003 The `STRING` `"OPTIONAL"` (or `"OPT"` -- they're totally equivalent)
3004 in the argument `LIST` allows the specification of optional arguments
3005 with values to be assigned by default. The syntax of the `"OPTIONAL"`
3006 part of the argument `LIST` is as follows:
3008 "OPTIONAL" al-1 al-2 ... al-N
3010 First, there is the `STRING` `"OPTIONAL"`. Then there is any number of
3011 either `ATOM`s or two-element `LIST`s, intermixed, one per optional
3012 argument. The first element of each two-element `LIST` must be an
3013 `ATOM`; this is the dummy variable. The second element is an arbitrary
3014 Muddle expression. If there are required arguments, they must come
3015 before the `"OPTIONAL"`.
3017 When `EVAL` is binding the variables of a `FUNCTION` and sees
3018 `"OPTIONAL"`, the following happens:
3020 - If an explicit argument was given in the position of an optional
3021 one, the explicit argument is bound to the corresponding dummy
3023 - If there is no explicit argument and the `ATOM` stands alone, that
3024 is, it is not the first element of a two-element `LIST`, that
3025 `ATOM` becomes "bound", but no local value is assigned to it \[see
3026 below\]. A local value can be assigned to it by using `SET`.
3027 - If there is no explicit argument and the `ATOM` is the first
3028 element of a two-element `LIST`, the Muddle expression in the
3029 `LIST` with the `ATOM` is evaluated and bound to the `ATOM`.
3031 \[Until an `ATOM` is assigned, any attempt to reference its `LVAL`
3032 will produce an error. The predicate `SUBR`s `BOUND?` and `ASSIGNED?`
3033 can be used to check for such situations. `BOUND?` returns `T` if its
3034 argument is currently bound via an argument `LIST` or has ever been
3035 `SET` while not bound via an argument `LIST`. The latter kind of
3036 binding is called "top-level binding", because it is done outside all
3037 active argument-`LIST` binding. `ASSIGNED?` will return `#FALSE ()` if
3038 its argument is **either** unassigned **or** unbound. By the way,
3039 there are two predicates for global values similar to `BOUND?` and
3040 `ASSIGNED?`, namely `GBOUND?` and `GASSIGNED?`. Each returns `T` only
3041 if its argument, which (as in `BOUND?` and `ASSIGNED?`) must be an
3042 `ATOM`, has a global value "slot" (chapter 22) or a global value,
3047 <DEFINE INC1 (A "OPTIONAL" (N 1)) <SET .A <+ ..A .N>>>$
3056 Here we defined another (not quite working) increment `FUNCTION`. It
3057 now takes an optional argument specifying how much to increment the
3058 `ATOM` it is given. If not given, the increment is `1`. Now, `1` is a
3059 pretty simple Muddle expression: there is no reason why the optional
3060 argument cannot be complicated -- for example, a call to a `FUNCTION`
3061 which reads a file on an I/O device.
3066 ### 9.2.1. "TUPLE" and TUPLE (the TYPE) \[1\]
3068 There are also times when you want to be able to have an arbitrary
3069 number of arguments. You can always do this by defining the `FUNCTION`
3070 as having a structure as its argument, with the arbitrary number of
3071 arguments as elements of the structure. This can, however, lead to
3072 inelegant-looking `FORM`s and extra garbage to be collected. The
3073 `STRING` `"TUPLE"` appearing in the argument `LIST` allows you to
3074 avoid that. It must follow explicit and optional dummy arguments (if
3075 there are any of either) and must be followed by an `ATOM`.
3077 The effect of `"TUPLE"` appearing in an argument `LIST` is the
3078 following: any arguments left in the `FORM`, after satisfying explicit
3079 and optional arguments, are `EVAL`ed and made sequential elements of
3080 an object of `TYPE` and `PRIMTYPE` `TUPLE`. The `TUPLE` is the bound
3081 to the `ATOM` following `"TUPLE"` in the argument `LIST`. If there
3082 were no arguments left by the time the `"TUPLE"` was reached, an empty
3083 `TUPLE` is bound to the `ATOM`.
3085 An object of `TYPE` `TUPLE` is exactly the same as a `VECTOR` except
3086 that a `TUPLE` is not held in garbage-collected storage. It is instead
3087 held with `ATOM` bindings in a control stack. This does not affect
3088 manipulation of the `TUPLE` within the function generating it or any
3089 function called within that one: it can be treated just like a
3090 `VECTOR`. Note, however, that a `TUPLE` ceases to exist when the
3091 function which generated it returns. Returning a `TUPLE` as a value is
3092 a good way to generate an error. (A copy of a `TUPLE` can easily be
3093 generated by segment-evaluating the `TUPLE` into something; that copy
3094 can be returned.) The predicate `LEGAL?` returns `#FALSE ()` if it is
3095 given a `TUPLE` generated by an `APPLICABLE` object which has already
3096 returned, and `T` if it is given a `TUPLE` which is still "good".
3100 <DEFINE NTHARG (N "TUPLE" T)
3101 ;"Get all but first argument into T."
3102 <COND (<==? 1 .N> 1)
3103 ;"If N is 1, return 1st arg, i.e., .N,
3104 i.e., 1. Note that <1? .N> would be
3105 true even if .N were 1.0."
3106 (<L? <LENGTH .T> <SET N <- .N 1>>>
3108 ;"Check to see if there is an Nth arg,
3109 and make N a good index into T while
3111 If there isn't an Nth arg, complain."
3112 (ELSE <NTH .T .N>)>>
3114 `NTHARG`, above, takes any number of arguments. Its first argument
3115 must be of `TYPE` `FIX`. It returns `EVAL` of its Nth argument, if it
3116 has an Nth argument. If it doesn't, it returns `#FALSE ("DUMMY")`.
3117 (The `ELSE` is not absolutely necessary in the last clause. If the Nth
3118 argument is a `FALSE`, the `COND` will return that `FALSE`.) Exercise
3119 for the reader: `NTHARG` will generate an error if its first argument
3120 is not `FIX`. Where and why? (How about `<NTHARG 1.5 2 3>`?) Fix it.
3122 ### 9.2.2. TUPLE (the SUBR) and ITUPLE
3124 These `SUBR`s are the same as `VECTOR` and `IVECTOR`, except that they
3125 build `TUPLE`s (that is, vectors on the control stack). They can be
3126 used only at top level in an `"OPTIONAL"` list or `"AUX"` list (see
3127 below). The clear advantage of `TUPLE` and `ITUPLE` ("implicit tuple")
3128 is in storage-management efficiency. They produce no garbage, since
3129 they are flushed automatically upon function return.
3133 <DEFINE F (A B "AUX" (C <ITUPLE 10 3>)) ...>
3135 creates a 10-element `TUPLE` and `SET`s `C` to it.
3137 <DEFINE H ("OPTIONAL" (A <ITUPLE 10 '<I>>)
3138 "AUX" (B <TUPLE !.A 1 2 3>))
3141 These are valid uses of `TUPLE` and `ITUPLE`. However, the following
3142 is **not** a valid use of `TUPLE`, because it is not called at top
3143 level of the `"AUX"`:
3145 <DEFINE NO (A B "AUX" (C <REST <TUPLE !.A>>)) ...>
3147 However, the desired effect could be achieved by
3149 <DEFINE OK (A B "AUX" (D <TUPLE !.A>) (C <REST .D>)) ...>
3154 `"AUX"` (or `"EXTRA"` -- they're totally equivalent) are `STRING`s
3155 which, placed in an argument `LIST`, serve to dynamically allocate
3156 temporary variables for the use of a Function.
3158 `"AUX"` must appear in the argument `LIST` after any information about
3159 explicit arguments. It is followed by `ATOM`s or two-element `LIST`s
3160 as if it were `"OPTIONAL"`. `ATOM`s in the two-element `LIST`s are
3161 bound to `EVAL` of the second element in the `LIST`. Atoms not in such
3162 `LIST`s are initially **unassigned**: they are explicitly given "no"
3165 All binding specified in an argument `LIST` is done sequentially from
3166 first to last, so initialization expressions for `"AUX"` (or
3167 `"OPTIONAL"`) can refer to objects which have just been bound. For
3168 example, this works:
3170 <DEFINE AUXEX ("TUPLE" T
3171 "AUX" (A <LENGTH .T>) (B <* 2 .A>))
3177 9.4. QUOTEd arguments
3178 ---------------------
3180 If an `ATOM` in an argument `LIST` which is to be bound to a required
3181 or optional argument is surrounded by a call to `QUOTE`, that `ATOM`
3182 is bound to the **unevaluated** argument. Example:
3184 <DEFINE Q2 (A 'B) (.A .B)>$
3186 <Q2 <+ 1 2> <+ 1 2>>$
3189 It is not often appropriate for a function to take its arguments
3190 unevaluated, because such a practice makes it less modular and harder
3191 to maintain: it and the programs that call it tend to need to know
3192 more about each other, and a change in its argument structure would
3193 tend to require more changes in the programs that call it. And, since
3194 few functions, in practice, do take unevaluated arguments, users tend
3195 to assume that no functions do (except `FSUBR`s of course), and
3196 confusion inevitably results.
3201 The indicator `"ARGS"` can appear in an argument `LIST` with precisely
3202 the same syntax as `"TUPLE"`. However, `"ARGS"` causes the `ATOM`
3203 following it to be bound to a `LIST` of the remaining **unevaluated**
3206 `"ARGS"` does not cause any copying to take place. It simply gives you
3208 <REST application:form fix>
3210 with an appropriate *fix*. The `TYPE` change to `LIST` is a result of
3211 the `REST`. Since the `LIST` shares all its elements with the original
3212 `FORM`, `PUT`s into the `LIST` will change the calling program,
3213 however dangerous that may be.
3217 <DEFINE QIT (N "ARGS" L) <.N .L>>$
3219 <QIT 2 <+ 3 4 <LENGTH ,QALL> FOO>$
3222 <DEFINE FUNCT1 ("ARGS" ARGL-AND-BODY)
3223 <CHTYPE .ARGL-AND-BODY FUNCTION>>$
3225 <FUNCT1 (A B) <+ .A .B>>$
3226 #FUNCTION ((A B) <+ .A .B>)
3228 The last example is a perfectly valid equivalent of the `FSUBR`
3234 The indicator `"CALL"` is an ultimate `"ARGS"`. If it appears in an
3235 argument `LIST`, it must be followed by an `ATOM` and must be the only
3236 thing used to gather arguments. `"CALL"` causes the `ATOM` which
3237 follows it to become bound to the actual `FORM` that is being
3238 evaluated -- that is, you get the "function call" itself. Since
3239 `"CALL"` binds to the `FORM` itself, and not a copy, `PUT`s into that
3240 `FORM` will change the calling code.
3242 `"CALL"` exists as a Catch-22 for argument manipulation. If you can't
3243 do it with `"CALL"`, it can't be done.
3245 9.7. EVAL and "BIND"
3246 --------------------
3248 Obtaining unevaluated arguments, for example, for `QUOTE` and
3249 `"ARGS"`, very often implies that you wish to evaluate them at some
3250 point. You can do this by explicitly calling `EVAL`, which is a
3258 `EVAL` can take a second argument, of `TYPE` `ENVIRONMENT` (or others,
3259 see section 20.8). An `ENVIRONMENT` consists basically of a state of
3260 `ATOM` bindings; it is the "world" mentioned in chapter 5. Now, since
3261 binding changes the `ENVIRONMENT`, if you wish to use `EVAL` within a
3262 `FUNCTION`, you probably want to get hold of the environment which
3263 existed **before** that `FUNCTION`'s binding took place. The indicator
3264 `"BIND"`, which must, if it is used, be the first thing in an argument
3265 `LIST`, provides this information. It binds the `ATOM` immediately
3266 following it to the `ENVIRONMENT` existing "at call time" -- that is,
3267 just before any binding is done for its `FUNCTION`. Example:
3271 <DEFINE WRONG ('B "AUX" (A 1)) <EVAL .B>>$
3275 <DEFINE RIGHT ("BIND" E 'B "AUX" (A 1)) <EVAL .B .E>>$
3280 ### 9.7.1. Local Values versus ENVIRONMENTs
3282 `SET`, `LVAL`, `VALUE`, `BOUND?`, `ASSIGNED?`, and `UNASSIGN` all take
3283 a final optional argument which has not previously been mentioned: an
3284 `ENVIRONMENT` (or other `TYPE`s, see section 20.8). If this argument
3285 is given, the `SET` or `LVAL` is done in the `ENVIRONMENT` specified.
3286 `LVAL` cannot be abbreviated by `.` (period) if it is given an
3287 explicit second argument.
3289 This feature is just what is needed to cure the `INC` bug mentioned in
3290 chapter 5. A "correct" `INC` can be defined as follows:
3292 <DEFINE INC ("BIND" OUTER ATM)
3293 <SET .ATM <+ 1 <LVAL .ATM .OUTER>> .OUTER>>
3295 9.8. ACTIVATION, "NAME", "ACT", "AGAIN", and RETURN \[1\]
3296 ---------------------------------------------------------
3298 `EVAL`uation of a `FUNCTION`, after the argument `LIST` has been taken
3299 care of, normally consists of `EVAL`uating each of the objects in the
3300 body in the order given, and returning the value of the last thing
3301 `EVAL`ed. If you want to vary this sequence, you need to know, at
3302 least, where the `FUNCTION` begins. Actually, `EVAL` normally hasn't
3303 the foggiest idea of where its current `FUNCTION` began. "Where'd I
3304 start" information is bundled up with a `TYPE` called `ACTIVATION`. In
3305 "normal" `FUNCTION` `EVAL`uation, `ACTIVATION`s are not generated: one
3306 can be generated, and bound to an `ATOM`, in either of the two
3309 1. Put an `ATOM` immediately before the argument `LIST`. The
3310 `ACTIVATION` of the Function will be bound to that `ATOM`.
3311 2. As the last thing in the argument `LIST`, insert either of the
3312 `STRING`s `"NAME"` or `"ACT"` and follow it with an `ATOM`. The
3313 `ATOM` will be bound to the `ACTIVATION` of the Function.
3315 In this document "Function" (capitalized) will designate anything that
3316 can generate an `ACTIVATION`; besides `TYPE` `FUNCTION`, this class
3317 includes the `FSUBR`s `PROG`, `BIND`, and `REPEAT`, yet to be
3320 Each `ACTIVATION` refers explicitly to a particular evaluation of a
3321 Function. For example, if a recursive `FUNCTION` generates an
3322 `ACTIVATION`, a new `ACTIVATION` referring explicitly to each
3323 recursion step is generated on every recursion.
3325 Like `TUPLE`s, `ACTIVATION`s are held in a control stack. Unlike
3326 `TUPLE`s, there is **no way** to get a copy of an `ACTIVATION` which
3327 can usefully be returned as a value. (This is a consequence of the
3328 fact that `ACTIVATION`s refer to evaluations; when the evaluation is
3329 finished, the `ACTIVATION` no longer exists.) `ACTIVATION`s can be
3330 tested, like `TUPLE`s, by `LEGAL?` for legality. They are used by the
3331 `SUBR`s `AGAIN` and `RETURN`.
3333 `AGAIN` can take one argument: an `ACTIVATION`. It means "start doing
3334 this again", where "this" is specified by the `ACTIVATION`.
3335 Specifically, `AGAIN` causes `EVAL` to return to where it started
3336 working on the **body** of the Function in the evaluation specified by
3337 the `ACTIVATION`. The evaluation is not redone completely: in
3338 particular, no re-binding (of arguments, `"AUX"` variables, etc.) is
3341 `RETURN` can take two arguments: an arbitrary expression and an
3342 `ACTIVATION`, in that order. It causes the Function evaluation whose
3343 `ACTIVATION` it is given to terminate and return `EVAL` of `RETURN`'s
3344 first argument. That is, `RETURN` means "quit doing this and return
3345 that", where "this" is the `ACTIVATION` -- its second argument -- and
3346 "that" is the expression -- its first argument. Example:
3348 <DEFINE MY+ ("TUPLE" T "AUX" (M 0) "NAME" NM)
3349 <COND (<EMPTY? .T> <RETURN .M .NM>)>
3350 <SET M <+ .M <1 .T>>>
3354 <MY+ 1 3 <LENGTH "FOO">>$
3359 Note: suppose an `ACTIVATION` of one Function (call it `F1`) is passed
3360 to another Function (call it `F2`) -- for example, via an application
3361 of `F2` within `F1` with `F1`'s `ACTIVATION` as an argument. If `F2`
3362 `RETURN`s to `F1`'s `ACTIVATION`, `F2` **and** `F1` terminate
3363 immediately, and **`F1`** returns the `RETURN`'s first argument. This
3364 technique is suitable for error exits. `AGAIN` can clearly pull a
3365 similar trick. In the following example, `F1` computes the sum of `F2`
3366 applied to each of its arguments; `F2` computes the product of the
3367 elements of its structured argument, but it aborts if it finds an
3368 element that is not a number.
3370 <DEFINE F1 ACT ("TUPLE" T "AUX" (T1 .T))
3371 <COND (<NOT <EMPTY? .T1>>
3372 <PUT .T1 1 <F2 <1 .T1> .ACT>>
3377 <DEFINE F2 (S A "AUX" (S1 .S))
3378 <REPEAT MY-ACT ((PRD 1))
3379 <COND (<NOT <EMPTY? .S1>>
3380 <COND (<NOT <TYPE? 1 .S1> FIX FLOAT>>
3381 <RETURN #FALSE ("NON-NUMBER") .A>)
3382 (ELSE <SET PRD <* .PRD <1 .S1>>>)>
3383 <SET S1 <REST .S1>>)
3384 (ELSE <RETURN .PRD>)>>>$
3390 #FALSE ("NON-NUMBER")
3392 9.9. Argument List Summary
3393 --------------------------
3395 The following is a listing of all the various tokens which can appear
3396 in the argument `LIST` of a `FUNCTION`, in the order in which they can
3397 occur. Short descriptions of their effects are included. **All** of
3398 them are **optional** -- that is, any of them (in any position) can be
3399 left out or included -- but the order in which they appear **must** be
3400 that of this list. "`QUOTE`d `ATOM`", "matching object", and "2-list"
3405 must be followed by an `ATOM`. It binds that `ATOM` to the
3406 `ENVIRONMENT` which existed when the `FUNCTION` was applied.
3408 (2) `ATOM`s and `QUOTE`d `ATOM`s (any number)
3410 are required arguments. `QUOTE`d `ATOM`s are bound to the matching
3411 object. `ATOM`s are bound to `EVAL` of the matching object in the
3412 `ENVIRONMENT` existing when the `FUNCTION` was applied.
3414 (3) `"OPTIONAL"` or `"OPT"` (they're equivalent)
3416 is followed by any number of `ATOM`s, `QUOTE`d `ATOM`s, or 2-lists.
3417 These are optional arguments. If a matching object exists, an `ATOM`
3418 -- either standing alone or the first element of a 2-list -- is bound
3419 to `EVAL` of the object, performed in the `ENVIRONMENT` existing when
3420 the `FUNCTION` was applied. A `QUOTE`d `ATOM` -- alone or in a 2-list
3421 -- is bound to the matching object itself. If no such object exists,
3422 `ATOM`s and `QUOTE`d `ATOM`s are left unbound, and the first element
3423 of each 2-list is bound to `EVAL` of the corresponding second element.
3424 (This `EVAL` is done in the new `ENVIRONMENT` of the Function as it is
3427 (4) `"ARGS"` (and **not** `"TUPLE"`)
3429 must be followed by an `ATOM`. The `ATOM` is bound to a `LIST` of
3430 **all** the remaining arguments, **unevaluated**. (If there are no
3431 more arguments, the `LIST` is empty.) This `LIST` is actually a `REST`
3432 of the `FORM` applying the `FUNCTION`. If `"ARGS"` appears in the
3433 argument `LIST`, `"TUPLE"` should not appear.
3435 (4) `"TUPLE"` (and **not** `"ARGS"`)
3437 must be followed by an `ATOM`. The `ATOM` is bound to a `TUPLE`
3438 ("`VECTOR` on the control stack") of all the remaining arguments,
3439 **evaluated** in the environment existing when the `FUNCTION` was
3440 applied. (If no arguments remain, the `TUPLE` is empty.) If `"TUPLE"`
3441 appears in the argument `LIST`, `"ARGS"` should not appear.
3443 (5) `"AUX"` or `"EXTRA"` (they're equivalent)
3445 is followed by any number of `ATOM`s or 2-lists. These are auxiliary
3446 variables, bound away from the previous environment for the use of
3447 this Function. `ATOM`s are bound in the `ENVIRONMENT` of the Function,
3448 but they are unassigned; the first element of each 2-list is both
3449 bound and assigned to `EVAL` of the corresponding second element.
3450 (This `EVAL` is done in the new `ENVIRONMENT` of the Function as it is
3453 (6) `"NAME"` or `"ACT"` (they're equivalent)
3455 must be followed by an `ATOM`. The `ATOM` is bound to the `ACTIVATION`
3456 of the current evaluation of the Function.
3458 **ALSO** -- in place of sections (2) (3) **and** (4), you can have
3462 which must be followed by an `ATOM`. The `ATOM` is bound to the `FORM`
3463 which caused application of this `FUNCTION`.
3465 The special terms used above mean this:
3467 "`QUOTE`d `ATOM`" -- a two-element `FORM` whose first element is the
3468 `ATOM` `QUOTE`, and whose second element is any `ATOM`. (Can be typed
3469 -- and will be `PRINT`ed -- as `'atom`.)
3471 "Matching object" -- that element of a `FORM` whose position in the
3472 `FORM` matches the position of a required or optional argument in an
3475 "2-list" -- a two-element `LIST` whose first element is an `ATOM` (or
3476 `QUOTE`d `ATOM`: see below) and whose second element can be anything
3477 but a `SEGMENT`. `EVAL` of the second element is assigned to a new
3478 binding of the first element (the `ATOM`) as the "value by default" in
3479 `"OPTIONAL"` or the "initial value" in `"AUX"`. In the case of
3480 `"OPTIONAL"`, the first element of a 2-list can be a `QUOTE`d `ATOM`;
3481 in this case, an argument which is supplied is not `EVAL`ed, but if it
3482 is not supplied the second element of the `LIST` **is** `EVAL`ed and
3483 assigned to the `ATOM`.
3488 Occasionally there is a valid reason for the first element of a `FORM`
3489 not to be an `ATOM`. For example, the object to be applied to
3490 arguments may be chosen at run time, or it may depend on the arguments
3491 in some way. While `EVAL` is perfectly happy in this case to
3492 `EVAL`uate the first element and go on from there, the compiler
3493 (Lebling, 1979) can generate more efficient code if it knows whether
3494 the result of the evaluation will (1) always be of `TYPE` `FIX`, (2)
3495 always be an applicable non-`FIX` object that evaluates all its
3496 arguments, or (3) neither. The easiest way to tell the compiler if (1)
3497 or (2) is true is to use the `ATOM` `NTH` (section 7.1.2) or `PUT`
3498 (section 7.1.4) in case (1) or `APPLY` in case (2) as the first
3499 element of the `FORM`. (Note: case (1) can compile into in-line code,
3500 but case (2) compiles into a fully mediated call into the
3503 <APPLY object arg-1 ... arg-N>
3505 evaluates *object* and all the *arg-i*'s and then applies the former
3506 to all the latter. An error occurs if *object* evaluates to something
3507 not applicable, or to an `FSUBR`, or to a `FUNCTION` (or user
3508 Subroutine -- chapter 19) with `"ARGS"` or `"CALL"` or `QUOTE`d
3513 <APPLY <NTH .ANALYZERS
3514 <LENGTH <MEMQ <TYPE .ARG> .ARGTYPES>>>
3517 calls a function to analyze `.ARG`. Which function is called depends
3518 on the `TYPE` of the argument; this represents the idea of a dispatch
3524 <CLOSURE function a1 ... aN>
3526 where *function* is a `FUNCTION`, and *a1* through *aN* are any number
3527 of `ATOM`s, returns an object of `TYPE` `CLOSURE`. This can be applied
3528 like any other function, but, whenever it is applied, the `ATOM`s
3529 given in the call to `CLOSURE` are **first** bound to the `VALUE`s
3530 they had when the `CLOSURE` was generated, then the *function* is
3531 applied as normal. This is a "poor man's `funarg`".
3533 A `CLOSURE` is useful when a `FUNCTION` must have state information
3534 remembered between calls to it, especially in these two cases: when
3535 the `LVAL`s of external state `ATOM`s might be compromised by other
3536 programs, or when more than one distinct sequence of calls are active
3537 concurrently. Example of the latter: each object of a structured
3538 `NEWTYPE` might have an associated `CLOSURE` that coughs up one
3539 element at a time, with a value in the `CLOSURE` that is a structure
3540 containing all the relevant information.
3545 10.1. PROG and REPEAT \[1\]
3546 ---------------------------
3548 `PROG` and `REPEAT` are almost identical `FSUBR`s which make it
3549 possible to vary the order of `EVAL`uation arbitrarily -- that is, to
3550 have "jumps". The syntax of `PROG` ("program") is
3552 <PROG act:atom aux:list body>
3556 - *act* is an optional `ATOM`, which is bound to the `ACTIVATION` of
3558 - *aux* is a `LIST` which looks exactly like that part of a
3559 `FUNCTION`'s argument `LIST` which follows an `"AUX"`, and serves
3560 exactly the same purpose. It is not optional. If you need no
3561 temporary variables of `"ACT"`, make it `()`.
3562 - *body* is a non-zero number of arbitrary Muddle expressions.
3564 The syntax of `REPEAT` is identical, except that, of course, `REPEAT`
3565 is the first element of the `FORM`, not `PROG`.
3567 ### 10.1.1. Basic EVALuation \[1\]
3569 Upon entering a `PROG`, an `ACTIVATION` is **always** generated. If
3570 there is an `ATOM` in the right place, the `ACTIVATION` is also bound
3571 to that `ATOM`. The variables in the *aux* (if any) are then bound as
3572 indicated in the *aux*. All of the expressions in *body* are then
3573 `EVAL`uated in their order of occurrence. If nothing untoward happens,
3574 you leave the `PROG` upon evaluating the last expression in *body*,
3575 returning the value of that last expression.
3577 `PROG` thus provides a way to package together a group of things you
3578 wish to do, in a somewhat more limited way than can be done with a
3579 `FUNCTION`. But `PROG`s are generally used for their other properties.
3581 `REPEAT` acts in all ways **exactly** like a `PROG` whose last
3582 expression is `<AGAIN>`. The only way to leave a `REPEAT` is to
3583 explicitly use `RETURN` (or `GO` with a `TAG` -- section 10.4).
3585 ### 10.1.2. AGAIN and RETURN in PROG and REPEAT \[1\]
3587 Within a `PROG` or `REPEAT`, you always have a defined `ACTIVATION`,
3588 whether you bind it to an `ATOM` or not. \[In fact the interpreter
3589 binds it to the `ATOM` `LPROG\ !-INTERRUPTS` ("last PROG"). The
3590 `FSUBR` `BIND` is identical to `PROG` except that `BIND` does not bind
3591 that `ATOM`, so that `AGAIN` and `RETURN` with no `ACTIVATION`
3592 argument will not refer to it. This feature could be useful within
3595 If `AGAIN` is used with no arguments, it uses the `ACTIVATION` of the
3596 closest surrounding `PROG` or `REPEAT` **within the current function**
3597 (an error occurs if there is none) and re-starts the `PROG` or
3598 `REPEAT` without rebinding the *aux* variables, just the way it works
3599 in a `FUNCTION`. With an argument, it can of course re-start any
3600 Function (`PROG` or `REPEAT` or `FUNCTION`) within which it is
3601 embedded at run time.
3603 As with `AGAIN`, if `RETURN` is given no `ACTIVATION` argument, it
3604 uses the `ACTIVATION` of the closest surrounding `PROG` or `REPEAT`
3605 within the current function and causes that `PROG` or `REPEAT` to
3606 terminate and return `RETURN`'s first argument. If `RETURN` is given
3607 **no** arguments, it causes the closest surrounding `PROG` or `REPEAT`
3608 to return the `ATOM` `T`. Also like `AGAIN`, it can, with an
3609 `ACTIVATION` argument, terminate any Function within which it is
3610 embedded at run time.
3612 ### 10.1.3. Examples \[1\]
3614 Examples of the use of `PROG` are difficult to find, since it is
3615 almost never necessary, and it slows down the interpreter (chapter
3616 24). `PROG` can be useful as a point of return from the middle of a
3617 computation, or inside a `COND` (which see), but we won't exemplify
3618 those uses. Instead, what follows is an example of a typically poor
3619 use of `PROG` which has been observed among Lisp (Moon, 1974)
3620 programmers using Muddle. Then, the same thing is done using `REPEAT`.
3621 In both cases, the example `FUNCTION` just adds up all its arguments
3622 and returns the sum. (The `SUBR` `GO` is discussed in section 10.4.)
3625 <DEFINE MY+ ("TUPLE" TUP)
3628 LP <COND (<EMPTY? .TUP> <RETURN .SUM>)>
3629 <SET SUM <+ .SUM <1 .TUP>>>
3630 <SET TUP <REST .TUP>>
3634 <DEFINE MY+ ("TUPLE" TUP)
3636 <COND (<EMPTY? .TUP> <RETURN .SUM>)>
3637 <SET SUM <+ .SUM <1 .TUP>>
3638 <SET TUP <REST .TUP>>>>
3640 Of course, neither of the above is optimal Muddle code for this
3641 problem, since `MY+` can be written using `SEGMENT` evaluation as
3643 <DEFINE MY+ ("TUPLE" TUP) <+ !.TUP>>
3645 There are, of course, lots of problems which can't be handled so
3646 simply, and lots of uses for `REPEAT`.
3648 10.2. MAPF and MAPR: Basics \[1\]
3649 ---------------------------------
3651 `MAPF` ("map first") and `MAPR` ("map rest") are two `SUBR`s which
3652 take care of a majority of cases which require loops over data. The
3653 basic idea is the following:
3655 Suppose you have a `LIST` (or other structure) of data, and you want
3656 to apply a particular function to each element. That is exactly what
3657 `MAPF` does: you give it the function and the structure, and it
3658 applies the function to each element of the structure, starting with
3661 On the other hand, suppose you want to **change** each element of a
3662 structure according to a particular algorithm. This can be done only
3663 with great pain using `MAPF`, since you don't have easy access to the
3664 **structure** inside the function: you have only the structure's
3665 elements. `MAPR` solves the problem by applying a function to `REST`s
3666 of a structure: first to `<REST structure 0>`, then to
3667 `<REST structure 1>`, etc. Thus, the function can change the structure
3668 by changing its argument, for example, by a
3669 `<PUT argument 1 something>`. It can even `PUT` a new element farther
3670 down the structure, which will be seen by the function on subsequent
3673 Now suppose, in addition to applying a function to a structure, you
3674 want to record the results -- the values returned by the function --
3675 in another structure. Both `MAPF` and `MAPR` can do this: they both
3676 take an additional function as an argument, and, when the looping is
3677 over, apply the additional function to **all** the results, and then
3678 return the results of that application. Thus, if the additional
3679 function is `,LIST`, you get a `LIST` of the previous results; if it
3680 is `.VECTOR`, you get a `VECTOR` of results; etc.
3682 Finally, it might be the case that you really want to loop a function
3683 over more than one structure simultaneously. For instance, consider
3684 creating a `LIST` whose elements are the element-by-element sum of the
3685 contents of two other `LIST`s. Both `MAPF` and `MAPR` allow this; you
3686 can, in fact, give each of them any number of structures full of
3687 arguments for your looping function.
3689 This was all mentioned because `MAPF` and `MAPR` appear to be complex
3690 when seen baldly, due to the fact that the argument descriptions must
3691 take into account the general case. Simpler, degenerate cases are
3692 usually the ones used.
3694 ### 10.2.1. MAPF \[1\]
3696 <MAPF finalf loopf s1 s2 ... sN>
3698 where (after argument evaluation)
3700 - *finalf* is something applicable that evaluates all its arguments,
3702 - *loopf* is something applicable to *N* arguments that evaluates
3703 all its arguments; and
3704 - *s1* through *sN* are structured objects (any `TYPE`)
3708 1. First, it applies *loopf* to *N* arguments: the first element of
3709 each of the structures. Then it `REST`s each of the structures,
3710 and does the application again, looping until **any** of the
3711 structures runs out of elements. Each of the values returned by
3712 *loopf* is recorded in a `TUPLE`.
3713 2. Then, it applies *finalf* to all the recorded values
3714 simultaneously, and returns the result of that application. If
3715 *finalf* is a `FALSE`, the recorded values are "thrown away"
3716 (actually never recorded in the first place) and the `MAPF`
3717 returns only the last value returned by *loopf*. If any of the
3718 *si* structures is empty, to that *loopf* is never invoked,
3719 *finalf* is applied to **no** arguments; if *finalf* is a `FALSE`,
3720 `MAPF` returns `#FALSE ()`.
3722 ### 10.2.2 MAPR \[1\]
3724 <MAPR finalf loopf s1 s2 ... sN>
3726 acts just like `MAPF`, but, instead of applying *loopf* to `NTH`s of
3727 the structures -- that is, `<NTH si 1>`, `<NTH si 2>`, etc. -- it
3728 applies it to `REST`s of the structures -- that is, `<REST si 0>`,
3731 ### 10.2.3. Examples \[1\]
3733 Make the element-wise sum of two `LIST`s:
3735 <MAPF .LIST .+ '(1 2 3 4) '(10 11 12 13)>$
3738 Change a `UVECTOR` to contain double its values:
3740 <SET UV '![5 6 7 8 9]>$
3743 #FUNCTION ((L) <PUT .L 1 <* <1 .L> 2>>)
3749 Create a `STRING` from `CHARACTER`s:
3751 <MAPF ,STRING 1 '["MODELING" "DEVELOPMENT" "LIBRARY"]>$
3754 Sum the squares of the elements of a `UVECTOR`:
3756 <MAPF ,+ #FUNCTION ((N) <* .N .N>) '![3 4]>$
3759 A parallel assignment `FUNCTION` (Note that the arguments to `MAPF`
3760 are of different lengths.):
3762 <DEFINE PSET ("TUPLE" TUP)
3766 <REST .TUP </ <LENGTH .TUP> 2>>>>$
3777 Note: it is easy to forget that *finalf* **must** evaluate its
3778 arguments, which precludes the use of an `FSUBR`. It is primarily for
3779 this reason that the `SUBR`s `AND?` and `OR?` were invented. As an
3780 example, the predicate `=?` could have been defined this way:
3783 <COND (<MONAD? .A> <==? .A .B>)
3784 (<AND <NOT <MONAD? .B>>
3785 <==? <TYPE .A> <TYPE .B>>
3786 <==? <LENGTH .A> <LENGTH .B>>>
3787 <MAPF ,AND? ,=? .A .B>)>>
3789 \[By the way, the following shows how to construct a value that has
3790 the same `TYPE` as an argument.
3793 <COND (<MEMQ <PRIMTYPE .S> '![LIST VECTOR UVECTOR STRING]>
3794 <CHTYPE <MAPF ,<PRIMTYPE .S> ,NOT .S>
3797 It works because the `ATOM`s that name the common `STRUCTURED`
3798 `PRIMTYPS`s (`LIST`, `VECTOR`, `UVECTOR` and `STRING`) have as `GVAL`s
3799 the corresponding `SUBR`s to build objects of those `TYPE`s.\]
3801 10.3. More on MAPF and MAPR
3802 ---------------------------
3806 `MAPRET` is a `SUBR` that enables the *loopf* being used in a `MAPR`
3807 or `MAPF` (and lexically within it, that is, not separated from it by
3808 a function call) to return from zero to any number of values as
3809 opposed to just one. For example, suppose a `MAPF` of the following
3812 <MAPF ,LIST <FUNCTION (E) ...> ...>
3814 Now suppose that the programmer wants to add no elements to the final
3815 `LIST` on some calls to the `FUNCTION` and add many on other calls to
3816 the `FUNCTION`. To accomplish this, the `FUNCTION` simply calls
3817 `MAPRET` with the elements it wants added to the `LIST`. More
3818 generally, `MAPRET` causes its arguments to be added to the final
3819 `TUPLE` of arguments to which the *finalf* will be applied.
3821 Warning: `MAPRET` is guaranteed to work only if it is called from an
3822 explicit `FUNCTION` which is the second argument to a `MAPF` or
3823 `MAPR`. In other words, the second argument to `MAPF` or `MAPR` must
3824 be `#FUNCTION (...)` or `<FUNCTION ...>` if `MAPRET` is to be used.
3826 Example: the following returns a `LIST` of all the `ATOM`s in an
3827 `OBLIST` (chapter 15):
3831 <FUNCTION (BKT) <MAPRET !.BKT>>
3836 `MAPSTOP` is the same as `MAPRET`, except that, after adding its
3837 arguments, if any, to the final `TUPLE`, it forces the application of
3838 *finalf* to occur, whether or not the structured objects have run out
3839 of objects. Example: the following copies the first ten (or all)
3840 elements of its argument into a `LIST`:
3842 <DEFINE FIRST-TEN (STRUC "AUX" (I 10))
3845 <COND (<0? <SET I <- .I 1>>> <MAPSTOP .E>)>
3849 ### 10.3.3. MAPLEAVE
3851 `MAPLEAVE` is analogous to `RETURN`, except that it works in
3852 (lexically within) `MAPF` or `MAPR` instead of `PROG` or `REPEAT`. It
3853 flushes the accumulated `TUPLE` of results and returns its argument
3854 (optional, `T` by default) as the value of the `MAPF` or `MAPR`. (It
3855 finds the MAPF/R that should returns in the current binding of the
3856 `ATOM` `LMAP\ !-INTERRUPTS` ("last map").) Example: the following
3857 finds and returns the first non-zero element of its argument, or
3858 `#FALSE ()` if there is none:
3860 <DEFINE FIRST-N0 (STRUC)
3863 <COND (<N==? .X 0> <MAPLEAVE .X>)>>
3866 ### 10.3.4. Only two arguments
3868 If `MAPF` or `MAPR` is given only two arguments, the iteration
3869 function *loopf* is applied to no arguments each time, and the looping
3870 continues indefinitely until a `MAPLEAVE` or `MAPSTOP` is invoked.
3871 Example: the following returns a `LIST` of the integers from one less
3872 than its argument to zero.
3877 <COND (<=? <SET N <- .N 1>>> <MAPSTOP 0>)
3880 One principle use of this form of MAPF/R involves processing input
3881 characters, in cases where you don't know how many characters are
3882 going to arrive. The example below demonstrates this, using `SUBR`s
3883 which are more fully explained in chapter 11. Another example can be
3884 found in chapter 13.
3886 Example: the following `FUNCTION` reads characters from the current
3887 input channel until an `$` (ESC) is read, and then returns what was
3888 read as one `STRING`. (The `SUBR` `READCHR` reads one character from
3889 the input channel and returns it. `NEXTCHR` returns the next
3890 `CHARACTER` which `READCHR` will return -- chapter 11.)
3894 <FUNCTION () <COND (<NOT <==? <NEXTCHR> <ASCII 27>>>
3900 <PROG () <READCHR> ;"Flush the ESC ending this input."
3902 ABC123<+ 3 4>$"ABC123<+ 3 4>"
3904 ### 10.3.5. STACKFORM
3906 The `FSUBR` `STACKFORM` is archaic, due to improvements in the
3907 implementation of MAPF/R, and it should not be used in new programs.
3909 <STACKFORM function arg pred>
3911 is exactly equivalent to
3914 <FUNCTION () <COND (pred arg) (T <MAPSTOP>)>>>
3916 In fact MAPF/R is more powerful, because `MAPRET`, `MAPSTOP`, and
3917 `MAPLEAVE` provide flexibility not available with `STACKFORM`.
3922 `GO` is provided in Muddle for people who can't recover from a
3923 youthful experience with Basic, Fortran, PL/I, etc. The `SUBR`s
3924 previously described in this chapter are much more tasteful for making
3925 good, clean, "structured" programs. `GO` just bollixes things.
3927 `GO` is a `SUBR` which allows you to break the normal order of
3928 evaluation and re-start just before any top-level expression in a
3929 `PROG` or `REPEAT`. It can take two `TYPE`s of arguments: `ATOM` or
3932 Given an `ATOM`, `GO` searches the *body* of the immediately
3933 surrounding `PROG` or `REPEAT` within the current Function, starting
3934 after *aux*, for an occurrence of that `ATOM` at the top level of
3935 *body*. (This search is effectively a `MEMQ`.) If it doesn't find the
3936 `ATOM`, an error occurs. If it does, evaluation is resumed at the
3937 expression following the `ATOM`.
3939 The `SUBR` `TAG` generates and returns objects of `TYPE` `TAG`. This
3940 `SUBR` takes one argument: an `ATOM` which would be a legal argument
3941 for a `GO`. An object of `TYPE` `TAG` contains sufficient information
3942 to allow you to `GO` to any top-level position in a `PROG` or `REPEAT`
3943 from within any function called inside the `PROG` or `REPEAT`. `GO`
3944 with a `TAG` is vaguely like `AGAIN` with an `ACTIVATION`; it allows
3945 you to "go back" to the middle of any `PROG` or `REPEAT` which called
3946 you. Also like `ACTIVATION`s, `TAG`s into a `PROG` or `REPEAT` can no
3947 longer be used after the `PROG` or `REPEAT` has returned. `LEGAL?` can
3948 be used to see if a `TAG` is still valid.
3950 10.5. Looping versus Recursion
3951 ------------------------------
3953 Since any program in Muddle can be called recursively, champions of
3954 "pure Lisp" (Moon, 1974) or somesuch may be tempted to implement any
3955 repetitive algorithm using recursion. The advantage of the looping
3956 techniques described in this chapter over recursion is that the
3957 overhead of calls is eliminated. However, a long program (say, bigger
3958 than half a printed page) may be more difficult to write iteratively
3959 than recursively and hence more difficult to maintain. A program whose
3960 repetition is controlled by a structured object (for example, "walking
3961 a tree" to visit each monad in the object) often should use looping
3962 for covering one "level" of the structure and recursion to change
3965 Chapter 11. Input/Output
3966 ========================
3968 The Muddle interpreter can transmit information between an object in
3969 Muddle and an external device in three ways. Historically, the first
3970 way was to **convert** an object into a string of characters, or vice
3971 versa. The transformation is nearly one-to-one (although some Muddle
3972 objects, for example `TUPLE`s, cannot be input in this way) and is
3973 similar in style to Fortran's formatted I/O. It is what `READ` and
3974 `PRINT` do, and it is the normal method for terminal I/O.
3976 The second way is used for the contents of Muddle objects rather than
3977 the objects themselves. Here an **image** of numbers or characters
3978 within an object is transmitted, similar in style to Fortran's
3981 The third way is to **dump** an object in a clever format so that it
3982 can be reproduced exactly when input the next time. Exact reproduction
3983 means that any sharing between structures or self-reference is
3984 preserved: only the garbage collector itself can do I/O in this way.
3986 11.1. Conversion I/O
3987 --------------------
3989 All conversion-I/O `SUBR`s in Muddle take an optional argument which
3990 directs their attention to a specific I/O channel. This section will
3991 describe `SUBR`s without their optional arguments. In this situation,
3992 they all refer to a particular channel by default, initially the
3993 terminal running the Muddle. When given an optional argument, that
3994 argument follows any arguments indicated here. Some of these `SUBR`s
3995 also have additional optional arguments, relevant to conversion,
3996 discussion of which will be deferred until later.
4000 All of the following input Subroutines, when directed at a terminal,
4001 hang until `$` (ESC) is typed and allow normal use of rubout, \^D, \^L
4008 This returns the entire Muddle object whose character representation
4009 is next in the input stream. Successive `<READ>`s return successive
4010 objects. This is precisely the `SUBR` `READ` mentioned in chapter 2.
4011 See also sections 11.3, 15.7.1, and 17.1.3 for optional arguments.
4013 #### 11.1.1.2. READCHR
4017 ("read character") returns the next `CHARACTER` in the input stream.
4018 Successive `<READCHR>`s return successive `CHARACTER`s.
4020 #### 11.1.1.3. NEXTCHR
4024 ("next character") returns the `CHARACTER` which `READCHR` will return
4025 the next time `READCHR` is called. Multiple `<NEXTCHR>`s, with no
4026 input operations between them, all return the same thing.
4030 If an object to be output requires (or can tolerate) separators within
4031 it (for example, between the elements in a structured object or after
4032 the `TYPE` name in "\# notation"), these conversion-output `SUBR`s
4033 will use a carriage-return/line-feed separator to prevent overflowing
4034 a line. Overflow is detected in advance from elements of the `CHANNEL`
4035 in use (section 11.2.8).
4037 #### 11.1.2.1. PRINT
4041 This outputs, in order,
4043 1. a carriage-return line-feed,
4044 2. the character representation of `EVAL` of its argument (`PRINT` is
4048 and then returns `EVAL` of its argument. This is precisely the `SUBR`
4049 `PRINT` mentioned in chapter 2.
4051 #### 11.1.2.2. PRIN1
4055 outputs just the representation of, and returns, `EVAL` of *any*.
4057 #### 11.1.2.3. PRINC
4061 ("print characters") acts exactly like `PRIN1`, except that
4063 1. if its argument is a `STRING` or a `CHARACTER`, it suppresses the
4064 surrounding `"`s or initial `!\` respectively; or
4065 2. if its argument is an `ATOM`, it suppresses any `\`s or `OBLIST`
4066 trailers (chapter 15) which would otherwise be necessary.
4068 If `PRINC`'s argument is a structure containing `STRING`s,
4069 `CHARACTER`s, or `ATOM`s, the service mentioned will be done for all
4070 of them. Ditto for the `ATOM` used to name the `TYPE` in "\#
4073 #### 11.1.2.4. TERPRI
4077 ("terminate printing") outputs a carriage-return line-feed and then
4078 returns `# FALSE ()`!
4082 ("carriage-return line-feed") outputs a carriage-return line-feed and
4085 #### 11.1.2.6. FLATSIZE
4087 <FLATSIZE any max:fix radix:fix>
4089 does not actually cause any output to occur and does not take a
4090 `CHANNEL` argument. Instead, or compares *max* with the number of
4091 characters `PRIN1` would take to print *any*. If *max* is less than
4092 the number of characters needed (including the case where *any* is
4093 self-referencing, `FLATSIZE` returns `#FALSE ()`; otherwise, it
4094 returns the number of characters needed by `PRIN1` *any*. *radix*
4095 (optional, ten by default) is used for converting any `FIX`es that
4098 This `SUBR` is especially useful in conjunction with (section 11.2.8)
4099 those elements of a `CHANNEL` which specify the number of characters
4100 per output line and the current position on an input line.
4105 I/O channels are dynamically assigned in Muddle, and are represented
4106 by an object of `TYPE` `CHANNEL`, which is of `PRIMTYPE` `VECTOR`. The
4107 format of a `CHANNEL` will be explained later, in section 11.2.8.
4108 First, how to generate and use them.
4112 <OPEN mode file-spec>
4116 <OPEN mode name1 name2 device dir>
4118 `OPEN` is a `SUBR` which creates and returns a `CHANNEL`. All its
4119 arguments must be of `TYPE` `STRING`, and **all** are optional. The
4120 preceding statement is false when the *device* is `"INT"` or `"NET"`;
4121 see sections 11.9 and 11.10. If the attempted opening of an
4122 operating-system I/O channel fails, `OPEN` returns
4123 `#FALSE (reason:string file-spec:string status:fix)`, where the
4124 *reason* and the *status* are supplied by the operating system, and
4125 the `file-spec` is the standard name of the file (after any name
4126 transformations by the operating system) that Muddle was trying to
4129 The choice of *mode* is usually determined by which `SUBR`s will be
4130 used on the `CHANNEL`, and whether or not the *device* is a terminal.
4131 The following table tells which `SUBR`s can be used with which modes,
4132 where `OK` indicates an allowed use:
4134 -------------------------------------------------------------------------------------------------------------------------------------------
4135 "READ" "PRINT" "READB" "PRINTB", "PRINTO" mode / SUBRs
4136 -------------------- -------------------- -------------------- ------------------------------------------ ---------------------------------
4137 OK OK `READ` `READCHR` `NEXTCHR`
4138 `READSTRING` `FILECOPY`
4141 OK OK\* `PRINT` `PRIN1` `PRINC` `IMAGE`
4142 `CRLF` `TERPRI` `FILECOPY`
4143 `PRINTSTRING` `BUFOUT` `NETS`
4146 OK `READB` `GC-READ`
4148 OK `PRINTB` `GC-DUMP`
4157 -------------------------------------------------------------------------------------------------------------------------------------------
4159 `*` PRINTing (or `PRIN1`ing) an `RSUBR` (chapter 19) on a `"PRINTB"`
4160 or `"PRINTO"` `CHANNEL` has special effects.
4162 `"PRINTB"` differs from `"PRINTO"` in that the latter mode is used to
4163 update a `"DSK"` file without copying it. `"READB"` and `"PRINTB"` are
4164 not used with terminals. `"READ"` is the mode used by default.
4166 The next one to four arguments to `OPEN` specify the file involved. If
4167 only one `STRING` is used, it can contain the entire specification,
4168 according to standard operating-system syntax. Otherwise, the
4169 string(s) are interpreted as follows:
4171 *name1* is the first file name, that part to the left of the space (in
4172 the ITS version) or period (in the Tenex and Tops-20 versions). The
4173 name used by default is `<VALUE NM1>`, if any, otherwise `"INPUT"`.
4175 *name2* is the second fail name, that part to the right of the space
4176 (ITS) or period (Tenex and Tops-20). The name used by default is
4177 `<VALUE NM2>`, if any, otherwise `">"` or `"MUD"` and highest version
4178 number (Tenex) or generation number (Tops-20).
4180 *device* is the device name. The name used by default is
4181 `<VALUE DEV>`, if any, otherwise `"DSK"`. (Devices about which Muddle
4182 has no special knowledge are assumed to behave like `"DSK"`.)
4184 *dir* is the disk-directory name. The name used by default is
4185 `<VALUE SNM>`, if any, otherwise the "working-directory" name as
4186 defined by her operating system.
4190 `<OPEN "PRINT" "TPL:">` opens a conversion-output channel to the TPL
4193 `<OPEN "PRINT" "DUMMY" "NAMES" "IPL">` does the same.
4195 `<OPEN "PRINT" "TPL">` opens a `CHANNEL` to the file `DSK:TPL >` (ITS
4196 version) or `DSK:TPL.MUD` (Tenex and Tops-20 versions).
4198 `<OPEN "READ" "FOO" ">" "DSK" "GUEST">` opens up a conversion-input
4199 `CHANNEL` to the given file.
4201 `<OPEN "READ" "GUEST;FOO">` does the same in the ITS version.
4205 `OPEN-NR` is the same as `OPEN`, except that the date and time of last
4206 reference of the opened file are not changes.
4208 ### 11.2.3. CHANNEL (the SUBR)
4210 `CHANNEL` is called exactly like `OPEN`, but it **always** return an
4211 unopened `CHANNEL`, which can later be opened by `RESET` (below) just
4212 as if it had once been open.
4214 ### 11.2.4. FILE-EXISTS?
4216 `FILE-EXISTS?` tests for the existence of a file without creating a
4217 `CHANNEL`, which occupies about a hundred machine words of storage. It
4218 takes file-name arguments just like `OPEN` (but no *mode* argument)
4219 and returns either T, \`\#FALSE (reason:string status:fix),
4225 closes *channel* and returns its argument, with its "state" changed to
4226 "closed". If *channel* is for output, all buffered output is written
4227 out first. No harm is done if *channel* is already `CLOSE`d.
4229 ### 11.2.6. CHANLIST
4233 returns a `LIST` whose elements are all the currently open `CHANNEL`s.
4234 The first two elements are usually `.INCHAN` and `.OUTCHAN` (see
4235 below). A `CHANNEL` not referenced by anything except `<CHANLIST>`
4236 will be `CLOSEd` during garbage collection.
4238 ### 11.2.7. INCHAN and OUTCHAN
4240 The channel used by default for input `SUBR`s is the local value of
4241 the `ATOM` `INCHAN`. The channel used by default for output SUBRs is
4242 the local value of the `ATOM` `OUTCHAN`.
4244 You can direct I/O to a `CHANNEL` by `SET`ting `INCHAN` or `OUTCHAN`
4245 (remembering their old values somewhere), or by giving the `SUBR` you
4246 with to use an argument of `TYPE` `CHANNEL`. (These actually have the
4247 same effect, because `READ` binds `INCHAN` to an explicit argument,
4248 and `PRINT` binds `OUTCHAN` similarly. Thus the `CHANNEL` being used
4249 is available for `READ` macros (section 17.1), or by giving the `SUBR`
4250 you wish to use an argument of `TYPE` `CHANNEL`. Thus the `CHANNEL`
4251 being used is available for `READ` macros (section 17.1) and
4252 `PRINTTYPE`s (section 6.4.4).)
4254 By the way, a good trick for playing with `INCHAN` and `OUTCHAN`
4255 values within a function is to use the `ATOM`s `INCHAN` and `OUTCHAN`
4256 as `"AUX"` variables, re-binding their local values to the `CHANNEL`
4257 you want. When you leave , of course, the old `LVAL`s are expanded
4258 (which is the whole point). The `ATOM`s must be declared `SPECIAL`
4259 (chapter 14) for this trick to compile correctly.
4261 `INCHAN` and `OUTCHAN` also have global values, initially the
4262 `CHANNEL`s directed at the terminal running `Muddle`. Initially,
4263 `INCHAN`'s and `OUTCHAN`s local and global values are the same.
4265 ### 11.2.8. Contents of CHANNELs
4267 The contents of an object of `TYPE` `CHANNEL` are referred to by the
4268 I/O `SUBR`s each time such a `SUBR` is used. If you change the
4269 contents of a `CHANNEL` (for example, with `PUT`), the next use of
4270 that `CHANNEL` will be changed accordingly. Some elements of
4271 `CHANNEL`s, however, should be played with seldom, if ever, and only
4272 at your own peril. These are marked below with an `*` (asterisk).
4275 There follows a table of the contents of a `CHANNEL`, the `TYPE` of
4276 each element, and an interpretation. The format used is the following:
4278 *element-number: type interpretation*
4280 ------------------------------------------------------------------------------------------------
4281 element-number type interpretation
4282 ------------------------- ------------------ ---------------------------------------------------
4283 -1 `LIST` transcript channel(s) (see below)
4285 \* 0 varies device-dependent information
4287 \* 1 `FIX` channel number (ITS) or JFN (Tenex and Tops-20),
4288 `0` for internal or closed
4292 \* 3 `STRING` first file name argument
4294 \* 4 `STRING` second file name argument
4296 \* 5 `STRING` device name argument
4298 \* 6 `STRING` directory name argument
4300 \* 7 `STRING` real first file name
4302 \* 8 `STRING` real second file name
4304 \* 9 `STRING` real device name
4306 \* 10 `STRING` real directory name
4308 \* 11 `FIX` various status bits
4310 \* 12 `FIX` PDP-10 instruction used to do one I/O operation
4312 13 `FIX` number of characters per line of output
4314 14 `FIX` current character position on a line
4316 15 `FIX` number of lines per page
4318 16 `FIX` current line number on a page
4320 17 `FIX` access pointer for file-oriented devices
4322 18 `FIX` radix for `FIX` conversion
4324 19 `FIX` sink for an internal `CHANNEL`
4325 ------------------------------------------------------------------------------------------------
4327 N.B.: The elements of a `CHANNEL` below number 1 are usually invisible
4328 but are obtainable via `<NTH <TOP channel> fix>`, for some appropriate
4331 The transcript-channels slot has this meaning: if this slot contains a
4332 `LIST` of `CHANNEL`s, then anything input or output on the original
4333 `CHANNEL` is output on these `CHANNEL`s. Caution: do not use a
4334 `CHANNEL` as its own transcript channel; you probably won't live to
4337 #### 11.2.8.2. Input CHANNELs
4339 The contents of the elements up to number 12 of a `CHANNEL` used for
4340 input are the same as that for output. The remaining elements are as
4341 follows ((same) indicates that the use is the same as that for
4344 element-number type interpretation
4345 ---------------- ---------- ---------------------------------------------------
4346 13 varies object evaluated when end of file is reached
4347 \* 14 `FIX` one "look-ahead" character, used by `READ`
4348 \* 15 `FIX` PDP-10 instruction executed waiting for input
4349 16 `LIST` queue of buffers for input from a terminal
4350 17 `FIX` access pointer for file-oriented devices (same)
4351 18 `FIX` radix for `FIX` conversion (same)
4352 19 `STRING` buffer for input or source for internal `CHANNEL`
4354 11.3. End-of-File "Routine"
4355 ---------------------------
4357 As mentioned above, an explicit `CHANNEL` is the first optional
4358 argument of all `SUBR`s used for conversion I/O. The second optional
4359 argument for conversion-**input** `SUBR`s is an "end-of-file routine"
4360 -- that is, something for the input `SUBR` to `EVAL` and return, if it
4361 reaches the end of the file it is reading. A typical end-of-file
4362 argument is a `QUOTE`d `FORM` which applies a function of yours. The
4363 value of this argument used by default is a call to `ERROR`. Note: the
4364 `CHANNEL` has been `CLOSE`d by the time this argument is evaluated.
4366 Example: the following `FUNCTION` counts the occurrences of a
4367 character in a file, according to its arguments. The file names,
4368 device, and directory are optional, with the usual names used by
4372 (CHAR "TUPLE" FILE "AUX" (CNT 0) (CHN <OPEN "READ" !.FILE>))
4373 <COND (.CHN ;"If CHN is FALSE, bad OPEN: return the FALSE
4374 so result can be tested by another FUNCTION."
4376 <AND <==? .CHAR <READCHR .CHN '<RETURN>>>
4377 <SET CNT <+ 1 .CNT>>>>
4378 ;"Until EOF, keep reading and testing a character at a time."
4379 .CNT ;"Then return the count.")>>
4386 #### 11.4.1.1. READB
4388 <READB buffer:uvector-or-storage channel eof:any>
4390 The *channel* must be open in `"READB"` mode. `READB` will read as
4391 many 36-bit binary words as necessary to fill the *buffer* (whose
4392 `UTYPE` must be of `PRIMTYPE` `WORD`), unless it hits the end of the
4393 file. `READB` returns the number of words actually read, as a
4394 `FIX`ed-point number. This will normally be the length of the
4395 *buffer*, unless the end of file was read, in which case it will be
4396 less, and only the beginning of *buffer* will have been filled
4397 (`SUBSTRUC` may help). An attempt to `READB` again, after *buffer* is
4398 not filled, will evaluate the end-of-file routine *eof*, which is
4399 optional, a call to `ERROR` by default.
4401 #### 11.4.1.2. READSTRING
4403 <READSTRING buffer:string channel stop:fix-or-string eof>
4405 is the `STRING` analog to `READB`, where *buffer* and *eof* are as in
4406 `READB`, and *channel* is any input `CHANNEL` (`.INCHAN` by default).
4407 *stop* tells when to stop inputting: if a `FIX`, read this many
4408 `CHARACTER`s (fill up *buffer* by default); if a `STRING`, stop
4409 reading if any `CHARACTER` in this `STRING` is read (don't include
4410 this `CHARACTER` in final `STRING`).
4414 #### 11.4.2.1. PRINTB
4416 <PRINTB buffer:uvector-or-storage channel>
4418 This call writes the entire contents of the *buffer* into the
4419 specified channel open in `"PRINTB"` or `"PRINTO"` mode. It returns
4422 #### 11.4.2.2. PRINTSTRING
4424 <PRINTSTRING buffer:string channel count:fix>
4426 is analogous to `READSTRING`. It outputs *buffer* on *channel*, either
4427 the whole thing or the first *count* characters, and returns the
4428 number of characters output.
4430 #### 11.4.2.3. IMAGE
4434 is a rather special-purpose `SUBR`. When any conversion-output routine
4435 outputs an ASCII control character (with special exceptions like
4436 carriage-returns, line-feeds, etc.), it actually outputs two
4437 characters: `^` (circumflex), followed by the upper-case character
4438 which has been control-shifted. `IMAGE`, on the other hand, always
4439 outputs the real thing: that ASCII character whose ASCII 7-bit code is
4440 *fix*. It is guaranteed not to give any gratuitous linefeeds or such.
4441 *channel* is optional, `.OUTCHAN` by default, and its slots for
4442 current character position (number 14) and current line number (16)
4443 are not updated. `IMAGE` returns *fix*.
4448 ### 11.5.1. Output: GC-DUMP
4450 <GC-DUMP any printb:channel-or-false>
4452 dumps *any* on *printb* in a clever format so that `GC-READ` (below)
4453 can reproduce *any* exactly, including sharing. *any* cannot live on
4454 the control stack, not can it be of `PRIMTYPE` `PROCESS` or `LOCD` or
4455 `ASOC` (which see). *any* is returned as a value.
4457 If *printb* is a `CHANNEL`, it must be open in `"PRINTB"` or
4458 `"PRINTO"` mode. If *printb* is a `FALSE`, `GC-DUMP` instead returns a
4459 `UVECTOR` (of `UTYPE` `PRIMTYPE` `WORD`) that contains what it would
4460 have output on a `CHANNEL`. This `UVECTOR` can be `PRINTB`ed anywhere
4461 you desire, but, if it is changed **in any way**, `GC-READ` will not
4462 be able to input it. Probably the only reason to get it is to check
4463 its length before output.
4465 Except for the miniature garbage collection required, `GC-DUMP` is
4466 about twice as fast as `PRINT`, but the amount of external storage
4467 used is two or three times as much.
4469 ### 11.5.2. Input: GC-READ
4471 <GC-READ readb:channel eof:any>
4473 returns one object from the *channel*, which must be open in `"READB"`
4474 mode. The file must have been produced by `GC-DUMP`. *eof* is
4475 optional. `GC-READ` is about ten times faster than `READ`.
4480 The entire state of Muddle can be saved away in a file for later
4481 restoration: this is done with the `SUBR`s `SAVE` and `RESTORE`. This
4482 is a very different form of I/O from any mentioned up to now; the file
4483 used contains an actual image of your Muddle address space and is not,
4484 in general, "legible" to other Muddle routines. `RESTORE`ing a `SAVE`
4485 file is **much** faster than re-`READ`ing the objects it contains.
4487 Since a `SAVE` file does not contain all extant Muddle objects, only
4488 the impure and `PURIFY`ed (section 22.9.2) ones, a change to the
4489 interpreter has the result of making all previous `SAVE` files
4490 unusable. To prevent errors from arising from this, the interpreter
4491 has a release number, which is incremented whenever changes are
4492 installed. The current release number is printed out on initially
4493 starting up the program and is available as the `GVAL` of the `ATOM`
4494 `MUDDLE`. This release number is written out as the very first part of
4495 each `SAVE` file. If `RESTORE` attempts to re-load a `SAVE` file whose
4496 release number is not the same as the interpreter being used, an error
4497 is produced. If desired, the release number of a `SAVE` file can be
4498 obtained by doing a `READ` of that file. Only that initial `READ` will
4499 work; the rest of the file is not ASCII.
4503 <SAVE file-spec:string gc?:false-or-any>
4507 <SAVE name1 name2 device dir gc?:false-or-any>
4509 saves the entire state of your Muddle away in the file specified by
4510 its arguments, and then returns `"SAVED"`. All `STRING` arguments are
4511 optional, with `"MUDDLE"`, `"SAVE"`, `"DSK"`, and `<VALUE SNM>` used
4512 by default. *gc?* is optional and, if supplied and of `TYPE` `FALSE`,
4513 causes no garbage collection to occur before `SAVE`ing. (`FSAVE` is an
4514 alias for `SAVE` that may be seen in old programs.)
4516 If, after restoring, `RESTORE` finds that `<VALUE SNM>` is the null
4517 `STRING` (`""`), it will ask the operating system for the name of the
4518 "working directory" and call `SNAME` with the result. This mechanism
4519 is handy for "public" `SAVE` files, which should not point the user at
4520 a particular disk directory.
4522 In the ITS version, the file is actually written with the name
4523 `_MUDS_ >` and renamed to the argument(s) only when complete, to
4524 prevent losing a previous `SAVE` file if a crash occurs. In the Tenex
4525 and Tops-20 versions, version/generation numbers provide the same
4530 <DEFINE SAVE-IT ("OPTIONAL"
4531 (FILE '("PUBLIC" "SAVE" "DSK" "GUEST"))
4534 <COND (<=? "SAVED" <SAVE !.FILE>> ;"See below."
4539 <PRINC "Amazing program at your service.">
4549 <RESTORE name1 name2 device dir>
4551 **replaces** the entire current state of your Muddle with that `SAVE`d
4552 in the file specified. All arguments are optional, with the same
4553 values used by default as by `SAVE`.
4555 `RESTORE` completely replaces the contents of the Muddle, including
4556 the state of execution existing when the `SAVE` was done and the state
4557 of all open I/O `CHANNEL`s. If a file which was open when the `SAVE`
4558 was done does not exist when the `RESTORE` is done, a message to that
4559 effect will appear on the terminal.
4561 A `RESTORE` **never** returns (unless it gets an error): it causes a
4562 `SAVE` done some time ago to return **again** (this time with the
4563 value `"RESTORED"`), even if the `SAVE` was done in the midst of
4564 running a program. In the latter case, the program will continue its
4565 execution upon `RESTORE`ation.
4567 11.7. Other I/O Functions
4568 -------------------------
4572 <LOAD input:channel look-up>
4574 eventually returns `"DONE"`. First, however, it `READ`s and `EVAL`s
4575 every Muddle object in the file pointed to by *input*, and then
4576 `CLOSE`s *input*. Any occurrences of rubout, ^@, ^D, \^L, etc., in the
4577 file are given no special meaning; they are simply `ATOM`
4580 *look-up* is optional, used to specify a `LIST` of `OBLIST`s for the
4581 `READ`. `.OBLIST` is used by default (chapter 15).
4585 <FLOAD file-spec look-up>
4589 <FLOAD name1 name2 device dir look-up>
4591 ("file load") acts just like `LOAD`, except that it takes arguments
4592 (with values used by default) like `OPEN`, `OPEN`s the `CHANNEL`
4593 itself for reading, and `CLOSE`s the `CHANNEL` when done. *look-up* is
4594 optional, as in `LOAD`. If the `OPEN` fails, an error occurs, giving
4595 the reason for failure.
4599 `<SNAME string>` ("system name", a hangover from ITS) is identical in
4600 effect with `<SETG SNM string>`, that is, it causes *string* to become
4601 the *dir* argument used by default by all `SUBR`s which want file
4602 specifications (in the absence of a local value for `SNM`). `SNAME`
4603 returns its argument.
4605 `<SNAME>` is identical in effect with `<GVAL SNM>`, that is, it
4606 returns the current *dir* used by default.
4610 <ACCESS channel fix>
4612 returns *channel*, after making the next character or binary word
4613 (depending on the mode of *channel*, which should not be `"PRINT"`)
4614 which will be input from or output to *channel* the (*fix*+1)st one
4615 from the beginning of the file. *channel* must be open to a randomly
4616 accessible device (`"DSK"`, `"USR"`, etc.). A *fix* of `0` positions
4617 *channel* at the beginning of the file.
4619 ### 11.7.5. FILE-LENGTH
4621 <FILE-LENGTH input:channel>
4623 returns a `FIX`, the length of the file open on *input*. This
4624 information is supplied by the operating system, and it may not be
4625 available, for example, with the `"NET"` device (section 11.10). If
4626 *input*'s mode is `"READ"`, the length is in characters (rounded up to
4627 a multiple of five); if `"READB"`, in binary words. If `ACCESS` is
4628 applied to *input* and this length or more, then the next input
4629 operation will detect the end of file.
4631 ### 11.7.6. FILECOPY
4633 <FILECOPY input:channel output:channel>
4635 copies characters from *input* to *output* until the end of file on
4636 *input* (thus closing *input*) and returns the number of characters
4637 copied. Both arguments are optional, with `.INCHAN` and `.OUTCHAN`
4638 used by default, respectively. The operation is essentially a
4639 `READSTRING` -- `PRINTSTRING` loop. Neither `CHANNEL` need be freshly
4640 `OPEN`ed, and *output* need not be immediately `CLOSE`d. Restriction:
4641 internally a `<FILE-LENGTH input>` is done, which must succeed; thus
4642 `FILECOPY` might lose if *input* is a `"NET"` `CHANNEL`.
4648 returns *channel*, after "resetting" it. Resetting a `CHANNEL` is like
4649 `OPEN`ing it afresh, with only the file-name slots preserved. For an
4650 input `CHANNEL`, this means emptying all input buffers and, if it is a
4651 `CHANNEL` to a file, doing an `ACCESS` to `0` on it. For an output
4652 `CHANNEL`, this means returning to the beginning of the file -- which
4653 implies, if the mode is not `"PRINTO"`, destroying any output done to
4654 it so far. If the opening fails (for example, if the mode slot of
4655 *channel* says input, and if the file specified in its real-name slots
4656 does not exist), `RESET` (like `OPEN`) returns
4657 `#FALSE (reason:string file-spec:string status:fix)`.
4661 <BUFOUT output:channel>
4663 causes all internal Muddle buffers for *output* to be written out and
4664 returns its argument. This is helpful if the operating system or
4665 Muddle is flaky and you want to attempt to minimize your losses. The
4666 output may be padded with up to four extra spaces, if *output*'s mode
4671 `RENAME` is for renaming and deleting files. It takes three kinds of
4674 - (a) two file names, in either single- or multi-`STRING` format,
4675 separated by the `ATOM` `TO`,
4677 - (b) one file name in either format, or
4679 - (c) a `CHANNEL` and a file name in either format (only in the ITS
4682 Omitted file-name parts use the same values by default as does `OPEN`.
4683 If the operation is successful, `RENAME` returns `T`, otherwise
4684 `#FALSE (reason:string status:fix)`.
4686 In case (a) the file specified by the first argument is renamed to the
4687 second argument. For example:
4689 <RENAME "FOO 3" TO "BAR"> ;"Rename FOO 3 to BAR >."
4691 In case (b) the single file name specifies a file to be deleted. For
4694 <RENAME "FOO FOO DSK:HARRY;"> ;"Rename FOO 3 to BAR >."
4696 In case (c) the `CHANNEL` must be open in either `"PRINT"` or
4697 `"PRINTB"` mode, and a rename while open for writing is attempted. The
4698 real-name slots in the `CHANNEL` are updated to reflect any successful
4701 11.8. Terminal CHANNELs
4702 -----------------------
4704 Muddle behaves like the ITS version of the text editor Teco with
4705 respect to typing in carriage-return, in that it automatically adds a
4706 line-feed. In order to type in a lone carriage-return, a
4707 carriage-return followed by a rubout must be typed. Also `PRINT`,
4708 `PRINT1` and `PRINC` do not automatically add a line-feed when a
4709 carriage-return is output. This enables overstriking on a terminal
4710 that lacks backspacing capability. It also means that what goes on a
4711 terminal and what goes in a file are more likely to look the same.
4713 In the ITS version, Muddle's primary terminal output channel (usually
4714 `,OUTCHAN`) is normally not in "display" mode, except when `PRINC`ing
4715 a `STRING`. Thus errors will rarely occur when a user is typing in
4716 text containing display-mode control codes.
4718 In the ITS version, Muddle can start up without a terminal, give
4719 control of the terminal away to an inferior operating-system process
4720 or get it back while running. Doing a `RESET` on either of the
4721 terminal channels causes Muddle to find out if it now has the
4722 terminal; if it does, the terminal is reopened and the current screen
4723 size and device parameters are updated. If it doesn't have the
4724 terminal, an internal flag is set, causing output to the terminal to
4725 be ignored and attempted input from the terminal to make the
4726 operating-system process go to sleep.
4728 In the ITS version, there are some peculiarities associated with
4729 pseudo-terminals (`"STY"` and `"STn"` devices). If the `CHANNEL` given
4730 to `READCHR` is open in `"READ"` mode to a pseudo-terminal, and if no
4731 input is available, `READCHR` returns `-1`, `TYPE` `FIX`. If the
4732 `CHANNEL` given to `READSTRING` is open in `"READ"` mode to a
4733 pseudo-terminal, reading also stops if and when no more characters are
4734 available, that is, when `READCHR` would return `-1`.
4739 <ECHOPAIR terminal-in:channel terminal-out:channel>
4741 returns its first argument, after making the two `CHANNEL`s "know
4742 about each other" so that rubout, ^@, ^D and \^L on *terminal-in* will
4743 cause the appropriate output on *terminal-out*.
4747 <TTYECHO terminal-input:channel pred>
4749 turns the echoing of typed characters on *channel* off or on,
4750 according to whether or not *pred* is `TYPE` `FALSE`, and returns
4751 *channel*. It is useful in conjunction with `TYI` (below) for a
4752 program that wants to do character input and echoing in its own
4757 <TYI terminal-input:channel>
4759 returns one `CHARACTER` from *channel* (optional, `.INCHAN` by
4760 default) when it is typed, rather than after `$` (ESC) is typed, as is
4761 the case with `READCHR`. The following example echos input characters
4762 as their ASCII values, until a carriage-return is typed:
4764 <REPEAT ((FOO <TTYECHO .INCHAN <>>))
4765 <AND <==? 13 <PRINC <ASCII <TYI .INCHAN>>>>
4766 <RETURN <TTYECHO .INCHAN T>>>>
4768 11.9. Internal CHANNELs
4769 -----------------------
4771 If the *device* specified in an `OPEN` is `"INT"`, a `CHANNEL` is
4772 created which does not refer to any I/O device outside Muddle. In this
4773 case, the mode must be `"READ"` or `"PRINT"`, and there is another
4774 argument, which must be a function.
4776 For a `"READ"` `CHANNEL`, the function must take no arguments.
4777 Whenever a `CHARACTER` is desired from this `CHANNEL`, the function
4778 will be applied to no arguments and must return a `CHARACTER`. This
4779 will occur once per call to `READCHR` using this `CHANNEL`, and
4780 several times per call to `READ`. In the ITS version, the function can
4781 signal that its "end-of-file" has been reached by returning
4782 `<CHTYPE *777777000003* CHARACTER>` (-1 in left half, control-C in
4783 right), which is the standard ITS end-of-file signal. In the Tenex and
4784 Tops-20 versions, the function should return either that or
4785 `<CHTYPE *777777000032* CHARACTER>` (-1 and control-Z), the latter
4786 being their standard end-of-file signal.
4788 For a `"PRINT"` `CHANNEL`, the function must take one argument, which
4789 will be a `CHARACTER`. It can dispose of its argument in any way it
4790 pleases. The value returned by the function is ignored.
4792 Example: `<OPEN "PRINT" "INT:" ,FCN>` opens an internal output
4793 `CHANNEL` with `,FCN` as its character-gobbler.
4795 11.10. The "NET" Device: the ARPA Network
4796 -----------------------------------------
4798 The `"NET"` device is different in many ways from conventional
4799 devices. In the ITS version, it is the only device besides `"INT"`
4800 that does not take all strings as its arguments to `OPEN`, and it must
4801 take an additional optional argument to specify the byte size of the
4802 socket. The format of a call to open a network socket is
4804 <OPEN mode:string local-socket:fix "NET" foreign-host:fix byte-size:fix>
4808 - *mode* is the mode of the desired `CHANNEL`. This must be either
4809 `"READ"`, `"PRINT"`, `"READB"` or `"PRINTB"`.
4810 - *local-socket* is the local socket number. If it is `-1`, the
4811 operating system will generate a unique local socket number. If it
4812 is not, in the Tenex and Tops-20 versions, the socket number is
4814 - *foreign-socket* is the foreign socket number. If it is `-1`, this
4815 is an `OPEN` for "listening".
4816 - *foreign-host* is the foreign host number. If it is an `OPEN` for
4817 listening, this argument is ignored.
4818 - *byte-size* is the optional byte size. For `"READ"` or `"PRINT"`
4819 this must be either `7` (used by default) or `8`. For `"READB"` or
4820 `"PRINTB"`, it can be any integer from `1` to `36` (used by
4823 In the Tenex and Tops-20 versions, `OPEN` can instead be given a
4824 `STRING` argument of the form `"NET:..."`. In this case the local
4825 socket number can be "directory-relative".
4827 Like any other `OPEN`, either a `CHANNEL` or a `FALSE` is returned.
4828 Once open, a network `CHANNEL` can be used like any other `CHANNEL`,
4829 except that `FILE-LENGTH`, `ACCESS`, `RENAME`, etc., cannot be done.
4830 The "argument" first-name, second-name, and directory-name slots in
4831 the `CHANNEL` are used for local socket, foreign socket, and foreign
4832 host (as specified in the call to `OPEN`), respectively. The
4833 corresponding "real" slots are used somewhat differently. If a channel
4834 is `OPEN`ed with local socket `-1`, the "real" first-name slot will
4835 contain the unique socket number generated by the operating system. If
4836 a listening socket is `OPEN`ed, the foreign socket and host numbers of
4837 the answering host are stored in the "real" second-name and
4838 directory-name slots of the `CHANNEL` when the Request For Connection
4841 An interrupt (chapter 21) can be associated with a `"NET"`-device
4842 `CHANNEL`, so that a program will know that the `CHANNEL` has or needs
4843 data, according to its *mode*.
4845 There also exist several special-purpose `SUBR`s for the `"NET"`
4846 device. These are described next.
4848 ### 11.10.1. NETSTATE
4850 <NETSTATE network:channel>
4852 returns a `UVECTOR` of three `FIX`es. The first is the state of the
4853 connection, the second is a code specifying why a connection was
4854 closed, and the last is the number of bits available on the connection
4855 for input. The meaning of the state and close codes are
4856 installation-dependent and so are not included here.
4860 <NETACC network:channel>
4862 accepts a connection to a socket that is open for listening and
4863 returns its argument. It will return a `FALSE` if the connection is in
4868 <NETS network:channel>
4870 returns its argument, after forcing any system-buffered network output
4871 to be sent. ITS normally does this every half second anyway. Tenex and
4872 Tops-20 do not do it unless and until `NETS` is called. `NETS` is
4873 similar to `BUFOUT` for normal `CHANNEL`s, except that even
4874 operating-system buffers are emptied **now**.
4876 Chapter 12. Locatives
4877 =====================
4879 There is in Muddle a facility for obtaining and working directly with
4880 objects which roughly correspond to "pointers" in assembly language or
4881 "lvals" in BCPL or PAL. In Muddle, these are generically known as
4882 **locatives** (from "location") and are of several `TYPE`s, as
4883 mentioned below. Locatives exist to provide efficient means for
4884 altering structures: direct replacement as opposed to re-copying.
4886 Locatives **always** refer to elements in structures. It is not
4887 possible to obtain a locative to something (for example, an `ATOM`)
4888 which is not part of any structured. It is possible to obtain a
4889 locative to any element in any structured object in Muddle -- even to
4890 associations (chapter 13) and to the values of `ATOM`s, structurings
4891 which are normally "hidden".
4893 In the following, the object occupying the structured position to
4894 which you have obtained a locative will be referred to as the object
4895 **pointed to** by the locative.
4897 12.1. Obtaining Locatives
4898 -------------------------
4904 returns a locative (`TYPE` `LOCD`, "locative to iDentifier") to the
4905 `LVAL` of *atom* in *env*. If *atom* is not bound in *env*, an error
4906 occurs. *env* is optional, with the current `ENVIRONMENT` used by
4907 default. The locative returned by `LLOC` is **independent of future
4908 re-bindings** of *atom*. That is, `IN` (see below) of that locative
4909 will return the same thing even if *atom* is re-bound to something
4910 else; `SETLOC` (see below) will affect only that particular binding of
4913 Since bindings are kept on a stack (tra la), any attempt to use a
4914 locative to an `LVAL` which has become unbound will fetch up an error.
4915 (It breaks just like a `TUPLE`....) `LEGAL?` can, once again, be used
4916 to see if a `LOCD` is valid. Caution: `<SET A <LLOC A>>` creates a
4917 self-reference and can make `PRINT` very unhappy.
4923 returns a locative (`TYPE` `LOCD`) to the `GVAL` of *atom*. If *atom*
4924 has no `GVAL` **slot**, an error occurs, unless *pred* (optional) is
4925 given and not `FALSE`, in which case a slot is created (chapter 22).
4926 Caution: `<SETG A <GLOC A>>` creates a self-reference and can make
4927 `PRINT` very unhappy.
4931 <AT structured N:fix-or-offset>
4933 returns a locative to the <em>N</em>th element in *structured*. *N* is
4934 optional, `1` by default. The exact `TYPE` of the locative returned
4935 depends on the `PRIMTYPE` of *structured*: `LOCL` for `LIST`, `LOCV`
4936 for `VECTOR`, `LOCU` for `UVECTOR`, `LOCS` for `STRING`, `LOCB` for
4937 `BYTES`, `LOCT` for `TEMPLATE`, and `LOCA` for `TUPLE`. If *N* is
4938 greater than `<LENGTH structured>` or less than `1`, or an `OFFSET`
4939 with a Pattern that doesn't match *structured*, an error occurs. The
4940 locative is unaffected by applications of `REST`, `BACK`, `TOP`,
4941 `GROW`, etc. to *structured*.
4943 ### 12.1.4. GETPL and GETL
4945 <GETPL item:any indicator:any default:any>
4947 returns a locative (`TYPE` `LOCAS`) to the association of *item* under
4948 *indicator*. (See chapter 13 for information about associations.) If
4949 no such association exists, `GETPL` returns `EVAL` of *default*.
4950 *default* is optional, `#FALSE ()` by default.
4952 `GETPL` corresponds to `GETPROP` amongst the association machinery.
4953 There also exists `GETL`, which corresponds to `GET`, returning either
4954 a `LOCAS` or a locative to the *indicator*th element of a structured
4955 *item*. `GETL` is like `AT` if *item* is a structure and *indicator*
4956 is a `FIX` or `OFFSET`, and like `GETPL` if not.
4961 This `SUBR` is a predicate that tells whether or not is argument is a
4962 locative. It is cheaper than
4963 `<MEMQ <PRIMTYPE arg> '![LOCD LOCL ...]>`.
4965 12.3. Using Locatives
4966 ---------------------
4968 The following two `SUBR`s provide the means for working with
4969 locatives. They are independent of the specific `TYPE` of the
4970 locative. The notation *locative* indicates anything which could be
4971 returned by `LLOC`, `GLOC`, `AT`, `GETPL` or `GETL`.
4977 returns the object to which *locative* points. The only way you can
4978 get an error using `IN` is when *locative* points to an `LVAL` which
4979 has become unbound from an `ATOM`. This is the same as the problem in
4980 referencing `TUPLE`s as mentioned in section 9.2, and it can be
4981 avoided by first testing `<LEGAL? locd>`.
4992 <SETLOC locative any>
4994 returns *any*, after having made *any* the contents of that position
4995 in a structure pointed to by *locative*. The structure itself is not
4996 otherwise disturbed. An error occurs if *locative* is to a
4997 non-`LEGAL?` `LVAL` or if you try to put an object of the wrong `TYPE`
4998 into a `PRIMTYPE` `UVECTOR`, `STRING`, `BYTES`, or `TEMPLATE`.
5004 <SETLOC <AT .A 2> HI>$
5009 12.4. Note on Locatives
5010 -----------------------
5012 You may have noticed that locatives are, strictly speaking,
5013 unnecessary; you can do everything locatives allow by appropriate use
5014 of, for example, `SET`, `LVAL`, `PUT`, `NTH`, etc. What locatives
5015 provide is generality.
5017 Basically, how you obtained a locative is irrelevant to `SETLOC` and
5018 `IN`; thus the same program can play with `GVAL`s, `LVAL`s, object in
5019 explicit structures, etc., without being bothered by what function it
5020 should use to do so. This is particularly true with respect to
5021 locatives to `LVAL`s; the fact that they are independent of changes in
5022 binding can save a lot of fooling around with `EVAL` and
5023 `ENVIRONMENT`s. \# Chapter 13. Association (Properties)
5025 There is an "associative" data storage and retrieval system embedded
5026 in Muddle which allows the construction of data structures with
5027 arbitrary selectors. It is used via the `SUBR`s described in this
5030 13.1. Associative Storage
5031 -------------------------
5035 <PUTPROP item:any indicator:any value:any>
5037 ("put property") returns *item*, having associated *value* with *item*
5038 under the indicator *indicator*.
5042 <PUT item:any indicator:any value:any>
5044 is identical to `PUTPROP`, except that, if *item* is structured
5045 **and** *indicator* is of `TYPE` `FIX` or `OFFSET`, it does
5046 `<SETLOC <AT item indicator> value>`. In other words, an element with
5047 an integral selector is stored in the structure itself, instead of in
5048 association space. `PUT` (like `AT`) will get an error if *indicator*
5049 is out of range; `PUTPROP` will not.
5051 ### 13.1.3. Removing Associations
5053 If `PUTPROP` is used **without** its *value* argument, it removes any
5054 association existing between its *item* argument and its *indicator*
5055 argument. If an association did exist, using `PUTPROP` in this way
5056 returns the *value* which was associated. If no association existed,
5057 it returns `#FALSE ()`.
5059 `PUT`, with arguments which refer to association, can be used in the
5062 If either *item* or *indicator* cease to exist (that is, no one was
5063 pointing to them, so they were garbage-collected), and no locatives to
5064 the association exist, then the association between them ceases to
5065 exist (is garbage-collected).
5067 13.2. Associative Retrieval
5068 ---------------------------
5072 <GETPROP item:any indicator:any exp:any>
5074 ("get property") returns the *value* associated with *item* under
5075 *indicator*, if any. If there is no such association, `GETPROP`
5076 returns `EVAL` of *exp* (that is, *exp* gets `EVAL`ed both at call
5079 *exp* is optional. If not given, `GETPROP` returns `#FALSE ()` if it
5080 cannot return a *value*.
5082 Note: *item* and *indicator* in `GETPROP` must be the **same Muddle
5083 objects** used to establish the association; that is, they must be
5084 `==?` to the objects used by `PUTPROP` or `PUT`.
5088 <GET item:any indicator:any exp:any>
5090 is the inverse of `PUT`, using `NTH` or `GETPROP` depending on the
5091 test outlined in section 13.1.2. *exp* is optional and used as in
5094 13.3. Examples of Association
5095 -----------------------------
5099 <PUT .L FOO "L is a list.">$
5103 <PUTPROP .L 3 '![4]>$
5111 <PUT .N .L "list on a zero">$
5113 <GET .N '(1 2 3 4)>$
5116 The last example failed because `READ` generated a new `LIST` -- not
5117 the one which is `L`'s `LVAL`. However,
5122 works because `<==? .N 0>` is true.
5124 To associate something with the Nth **position** in a structure, as
5125 opposed to its Nth **element**, associate it with
5126 `<REST structure N-1>`, as in the following:
5128 <PUT <REST .L 3> PERCENT 0.3>$
5130 <GET <2 .L> PERCENT>$
5132 <GET <REST .L 2> PERCENT>$
5137 <SET N '![A B C ;"third element" D E]>$
5139 <GET <REST .N 2> COMMENT>$
5142 The `'` in the `<SET N ... >` is to keep `EVAL` from generating a new
5143 `UVECTOR` ("Direct Representation"), which would not have the comment
5144 on it (and which would be a needless duplicate). A "top-level" comment
5145 -- one attached to the entire object returned by `READ` -- is `PUT` on
5146 the `CHANNEL` in use, since there is no position in any structure for
5147 it. If no top-level comment follows the object, `READ` removes the
5148 value (`<PUT channel COMMENT>`); so anybody that wants to see a
5149 top-level comment must look for it after each `READ`.
5151 If you need to have a structure with selectors in more than one
5152 dimension (for example, a sparse matrix that does not deserve to be
5153 linearized), associations can be cascaded to achieve the desired
5154 result. In effect an extra level of indirection maps two indicators
5155 into one. For example, to associate *value* with *item* under
5156 *indicator-1* and *indicator-2* simultaneously:
5158 <PUTPROP indicator-1 indicator-2 T>
5159 <PUTPROP item <GETPL indicator-1 indicator-2> value>
5161 13.4. Examining Associations
5162 ----------------------------
5164 Associations (created by `PUT` and `PUTPROP`) are chained together in
5165 a doubly-linked list, internal to Muddle. The order of associations in
5166 the chain is their order of creation, newest first. There are several
5167 `SUBR`s for examining the chain of associations. `ASSOCIATIONS`
5168 returns the first association in the chain, or `#FALSE ()` if there
5169 are none. `NEXT` takes an association as an argument and returns the
5170 next association in the chain, or `#FALSE ()` if there are no more.
5171 `ITEM`, `INDICATOR` and `AVALUE` all take an association as an
5172 argument and return the item, indicator and value, respectively.
5173 Associations print as:
5175 #ASOC (item indicator value)
5177 (sic: only one `S`). Example: the following gathers all the existing
5178 associations into a `LIST`.
5180 <PROG ((A <ASSOCIATIONS>))
5181 <COND (<NOT .A> '())
5183 <FUNCTION () <COND (<SET A <NEXT .A>> .A)
5184 (T <MAPSTOP>)>>>))>>
5186 Chapter 14. Data-type Declarations
5187 ==================================
5189 In Muddle, it is possible to declare the permissible range of "types"
5190 and/or structures that an `ATOM`'s values or a function's arguments or
5191 value may have. This is done using a special `TYPE`, the `DECL`
5192 ("declaration"). A `DECL` is of `PRIMTYPE` `LIST` but has a
5193 complicated internal structure. `DECL`s are used by the interpreter to
5194 find `TYPE` errors in function calling and by the compiler to generate
5195 more efficient code.
5197 There are two kinds of `DECL`s. The first kind of `DECL` is the most
5198 common. It is called the `ATOM` `DECL` and is used most commonly to
5199 specify the type/structure of the `LVAL`s of the `ATOM`s in the
5200 argument `LIST` of a `FUNCTION` or *aux* `LIST` of a `PROG` or
5201 `REPEAT`. This `DECL` has the form:
5203 #DECL (atoms:list Pattern ...)
5205 where the pairing of a `LIST` of `ATOM`s and a "Pattern" can be
5206 repeated indefinitely. This declares the `ATOM`s in a *list* to be of
5207 the type/structure specified in the following *Pattern*. The special
5208 `ATOM` `VALUE`, if it appears, declares the result of a `FUNCTION`
5209 call or `PROG` or `REPEAT` evaluation to satisfy the Pattern
5210 specified. An `ATOM` `DECL` is useful in only one place: immediately
5211 following the argument `LIST` of a `FUNCTION`, `PROG`, or `REPEAT`. It
5212 normally includes `ATOM`s in the argument `LIST` and `ATOM`s whose
5213 `LVAL`s are otherwise used in the Function body.
5215 The second kind of `DECL` is rarely seen by the casual Muddle user,
5216 except in appendix 2. It is called the `RSUBR` `DECL`. It is used to
5217 specify the type/structure of the arguments and result of an `RSUBR`
5218 or `RSUBR-ENTRY` (chapter 19). It is of the following form:
5220 #DECL ("VALUE" Pattern Pattern ...)
5222 where the `STRING` `"VALUE"` precedes the specification of the
5223 type/structure of the value of the call to the `RSUBR`, and the
5224 remaining *Patterns* specify the arguments to the `RSUBR` in order.
5225 The full specification of the `RSUBR` `DECL` will be given in section
5226 14.9. The `RSUBR` `DECL` is useful in only one place: as an element of
5227 an `RSUBR` or `RSUBR-ENTRY`.
5232 The simplest possible Pattern is to say that a value is exactly some
5233 other object, by giving that object, `QUOTE`d. For example, to declare
5234 that a variable is a particular `ATOM`:
5238 declares that `.X` is always the `ATOM` `T`. When variables are
5239 `DECL`ed as "being" some other object in this way, the test used is
5240 `=?`, not `==?`. The distinction is usually not important, since
5241 `ATOM`s, which are most commonly used in this construction, are `==?`
5242 to each other is `=?` anyway.
5244 It is more common to want to specify that a value must be of a given
5245 `TYPE`. This is done with the simplest non-specific Pattern, a `TYPE`
5248 #DECL ((X) FIX (Y) FLOAT)
5250 declares `.X` to be of `TYPE` `FIX`, and `.Y` of `TYPE` `FLOAT`. In
5251 addition to the names of all of the built-in and created `TYPE`s, such
5252 as `FIX`, `FLOAT` and `LIST`, a few "compound" type names are allowed:
5254 - `ANY` allows any `TYPE`.
5255 - `STRUCTURED` allows any structured `TYPE`, such as `LIST`,
5256 `VECTOR`, `FALSE`, `CHANNEL`, etc. (appendix 3).
5257 - `LOCATIVE` allows any locative `TYPE`, such as are returned by
5258 `LLOC`, `GLOC`, `AT`, and so on (chapter 12).
5259 - `APPLICABLE` allows any applicable `TYPE`, such as `FUNCTION`,
5260 `SUBR`, `FIX` (!), etc. (appendix 3).
5261 - Any other `ATOM` can be used to stand for a more complex
5262 construct, if an association is established on that `ATOM` and the
5263 `ATOM` `DECL`. A common example is to
5264 `<PUT NUMBER DECL '<OR FIX FLOAT>>` (see below), so that `NUMBER`
5265 can be used as a "compound type name".
5267 The single `TYPE` name can be generalized slightly, allowing anything
5268 of a given `PRIMTYPE`, using the following construction:
5270 #DECL ((X) <PRIMTYPE WORD> (Y) <PRIMTYPE LIST>)
5272 This construction consists of a two-element `FORM`, where the first
5273 element is the `ATOM` `PRIMTYPE`, and the second the name of a
5276 The next step is to specify the elements of a structure. This is done
5277 in the simplest way as follows:
5279 < structured:type Pattern Pattern ...>
5281 where there is a one-to-one correspondence between the *Pattern* and
5282 the elements of the structure. For example:
5284 #DECL ((X) <VECTOR FIX FLOAT>)
5286 declares `.X` to be a `VECTOR` having **at least** two elements, the
5287 first of which is a `FIX` and the second a `FLOAT`. It is often
5288 convenient to allow additional elements, so that only the elements
5289 being used in the local neighborhood of the `DECL` need to be
5290 declared. To disallow additional elements, a `SEGMENT` is used instead
5291 of a `FORM` (the "excl-ed" brackets make it look more emphatic). For
5294 #DECL ((X) !<VECTOR FIX FLOAT>)
5296 declares `.X` to be a `VECTOR` having **exactly** two elements, the
5297 first of which is a `FIX` and the second a `FLOAT`. Note that the
5298 *Patterns* given for elements can be any legal Pattern:
5300 #DECL ((X) <VECTOR <VECTOR FIX FLOAT>> (Y) <<PRIMTYPE LIST> LIST>)
5302 declares `.X` to be a `VECTOR` containing another `VECTOR` of at least
5303 two elements, and `.Y` to be of `PRIMTYPE LIST`, containing a `LIST`.
5304 In the case of a `BYTES`, the individual elements cannot be declared
5305 (they must be `FIX`es anyway), only the size and number of the bytes:
5307 #DECL ((B) <BYTES 7 3>)
5309 declares `.B` to be a `BYTES` with `BYTE-SIZE` 7 and at least three
5312 It is possible to say that some number of elements of a structure
5313 satisfy a given Pattern (or sequence of Patterns). This is called an
5314 "`NTH` construction".
5316 [ number:fix Pattern Pattern ... ]
5318 states that the sequence of *Patterns* which is `REST` of the `VECTOR`
5319 is repeated the *number* of times given. For example:
5321 #DECL ((X) <VECTOR [3 FIX] FLOAT> (Y) <LIST [3 FIX FLOAT]>)
5323 `.X` is declared to contain three `FIX`es and a `FLOAT`, perhaps
5324 followed by other elements. `.Y` is declared to repeat the sequence
5325 `FIX`-`FLOAT` three times. Note that there may be more repetitions of
5326 the sequence in `.Y` (but not in `.X`): the `DECL` specifies only the
5329 For indefinite repetition, the same construction is used, but, instead
5330 of the number of repetitions of the sequence of Patterns, the `ATOM`
5331 `REST` is given. This allows any number of repetitions, from zero on
5334 #DECL ((X) <VECTOR [REST FIX]> (Y) <LIST [3 FIX] [REST FIX]>)
5336 A "`REST` construction" can contain any number of Patterns, just like
5337 an `NTH` construction:
5339 #DECL ((X) <VECTOR [REST FIX FLOAT LIST]>)
5341 declares that `.X` is a `VECTOR` wherein the sequence
5342 `FIX`-`FLOAT`-`LIST` repeats indefinitely. It does not declare that
5343 `<LENGTH .X>` is an even multiple of three: the `VECTOR` can end at
5346 A variation on `REST` is `OPT` (or `OPTIONAL`), which is similar to
5347 `REST` except that the construction is scanned once at most instead of
5348 indefinitely, and further undeclared elements can follow. For example:
5350 #DECL ((X) <VECTOR [OPT FIX]>)
5352 declares that `.X` is a `VECTOR` which is empty or whose first element
5353 is a `FIX`. Only a `REST` construction can follow an "`OPT`
5356 Note that the `REST` construction must always be the last element of
5357 the structure declaration, since it gives a Pattern for the rest of
5358 the structure. Thus, the `REST` construction is different from all
5359 others in that it has an unlimited range. No matter how many times the
5360 Pattern it gives is `REST`ed off of the structure, the remainder of
5361 the structure still has that Pattern.
5363 This exhausts the possible single Patterns that can be given in a
5364 declaration. However, there is also a compound Pattern defined. It
5365 allows specification of several possible Patterns for one value:
5367 <OR Pattern Pattern ... >
5369 Any non-compound Pattern can be included as one of the elements of the
5370 compound Pattern. Finally, compound Patterns can be used as Patterns
5371 for elements of structures, and so on.
5373 #DECL ((X) <OR FIX FLOAT>
5374 (Y) <OR FIX <UVECTOR [REST <OR FIX FLOAT>]>>)
5376 The `OR` construction can be extended to any level of ridiculousness,
5377 but the higher the level of complexity and compoundedness the less
5378 likely the compiler will find the `DECL` useful.
5380 At the highest level, any Pattern at top level in an `ATOM` `DECL` can
5381 be enclosed in the construction
5383 < specialty:atom Pattern >
5385 which explicitly declares the specialty of the `ATOM`(s) in the
5386 preceding `LIST`. *specialty* can be either `SPECIAL` or `UNSPECIAL`.
5387 Specialty is important only when the program is to be compiled. The
5388 word comes from the control stack, which is called "special" in Lisp
5389 (Moon, 1974) because the garbage collector finds objects on it and
5390 modifies their internal pointers when storage is compacted. (An
5391 internal stack is used within the interpreter and is not accessible to
5392 programs -- section 22.1) In an interpreted program all local values
5393 are inherently `SPECIAL`, because all bindings are put on the control
5394 stack (but see `SPECIAL-MODE` below). When the program is compiled,
5395 only values declared `SPECIAL` (which may or may not be the
5396 declaration used by default) remain in bindings on the control stack.
5397 All others are taken care of simply by storing objects on the control
5398 stack: the `ATOM`s involved are not needed and are not created on
5399 loading. So, a program that `SET`s an `ATOM`'s local value for another
5400 program to pick up must declare that `ATOM` to be `SPECIAL`. If it
5401 doesn't, the `ATOM`'s binding will go away during compiling, and the
5402 program that needs to refer to the `ATOM` will either get a no-value
5403 error or refer to an erroneous binding. Usually only `ATOM`s which
5404 have the opposite specialty from that of the current `SPECIAL-MODE`
5405 are explicitly declared. The usual `SPECIAL-MODE` is `UNSPECIAL`, so
5406 typically only `SPECIAL` declarations use this construction:
5408 #DECL ((ACT)) <SPECIAL ACTIVATION>)
5410 explicitly declares `ACT` to be `SPECIAL`.
5412 Most well-written, modular programs get all their information from
5413 their arguments and from `GVAL`s, and thus they rarely use `SPECIAL`
5414 `ATOM`s, except perhaps for `ACTIVATION`s and the `ATOM`s whose
5415 `LVAL`s Muddle uses by default: `INCHAN`, `OUTCHAN`, `OBLIST`, `DEV`,
5416 `SNM`, `NM1`, `NM2`. `OUTCHAN` is a special case: the compiler thinks
5417 that all conversion-output `SUBR`s are called with an explicit
5418 `CHANNEL` argument, whether or not the program being compiled thinks
5419 so. For example, `<CRLF>` is compiled as though it were
5420 `<CRLF .OUTCHAN>`. So you may use (or see) the binding
5421 `(OUTCHAN .OUTCHAN)` in an argument `LIST`, however odd that may
5422 appear, because that -- coupled with the usual `UNSPECIAL` declaration
5423 by default -- makes only one reference to the current binding of
5424 `OUTCHAN` and stuffs the result in a slot on the stack for use within
5430 #DECL ((Q) <OR VECTOR CHANNEL>)
5432 declares .Q to be either a `VECTOR` or a `CHANNEL`.
5434 #DECL ((P Q R S) <PRIMTYPE LIST>)
5436 declares `.P`, `.Q`, `.R`, and `.S` all to be of `PRIMTYPE` `LIST`.
5438 #DECL ((F) <FORM [3 ANY]>)
5440 declares `.F` to be a `FORM` whose length is at least three,
5441 containing objects of any old `TYPE`.
5443 #DECL ((LL) <<PRIMTYPE LIST> [4 <LIST [REST FIX]>]>)
5445 declares `.LL` to be of `PRIMTYPE` `LIST`, and to have at least four
5446 elements, each of which are `LIST`s of unspecified length (possibly
5447 empty) containing `FIX`es.
5449 #DECL ((VV) <VECTOR FIX ATOM CHARACTER>)
5451 declares `.VV` to be a `VECTOR` with at least three elements. Those
5452 elements are, in order, of `TYPE` `FIX`, `ATOM`, and `CHARACTER`.
5454 #DECL ((EH) <LIST ATOM [REST FLOAT]>)
5456 declares `.EH` to be a `LIST` whose first element is an `ATOM` and the
5457 rest of whose elements are `FLOAT`s. It also says that `.EH` is at
5458 least one element long.
5460 #DECL ((FOO) <LIST [REST 'T FIX]>)
5462 declares `.FOO` to be a `LIST` whose odd-positioned elements are the
5463 `ATOM` `T` and whose even-positioned elements are `FIX`es.
5467 #DECL ((X) <VECTOR [1 FIX]>)
5471 declares `.X` to be a `VECTOR` containing at least one `FIX`. The more
5472 restrictive `[REST FIX]` would take excessive checking time by the
5473 interpreter, because the `REST` of the `VECTOR` would be checked on
5474 each iteration of the `MAPR`. In this case both `DECL`s are equally
5475 powerful, because checking the first element of all the `REST`s of a
5476 structure eventually checks all the elements. Also, since the
5477 `FUNCTION` refers only to the first element of `X`, this is as much
5478 declaration as the compiler can effectively use. (If this `VECTOR`
5479 always contains only `FIX`es, it should be a `UVECTOR` instead, for
5480 space efficiency. Then a `[REST FIX]` `DECL` would make the
5481 interpreter check only the `UTYPE`. If the `FIX`es cover a small
5482 non-negative range, then a `BYTES` might be even better, with a `DECL`
5486 #DECL ((N) <UNSPECIAL FIX>)
5487 <COND (<0? .N> 1) (ELSE <* .N <FACT <- .N 1>>>)>>
5489 declares `.N` to be of `TYPE` `FIX` and `UNSPECIAL`. This specialty
5490 declaration ensures that, independent of `SPECIAL-MODE` during
5491 compiling, `.N` gets compiled into a fast control-stack reference.
5494 #DECL ((L VALUE) <UNSPECIAL <LIST [REST FIX]>>
5495 (N <UNSPECIAL FIX>))
5496 <COND (<0? .N> <RETURN .L>)>
5497 <SET L (<+ .N <1 .L>> !.L)>
5500 The above declares `L` and `N` to be `UNSPECIAL`, says that `.N` is a
5501 `FIX`, and says that `.L`, along with the value returned, is a `LIST`
5502 of any length composed entirely of `FIX`es.
5504 14.3. The DECL Syntax
5505 ---------------------
5507 This section gives quasi-BNF productions for the Muddle `DECL` syntax.
5508 In the following table Muddle type-specifiers are distinguished *in
5511 decl ::= #DECL (declprs)
5513 declprs ::= (atlist) pattern | declprs declprs
5515 atlist ::= atom | atom atlist
5517 pattern ::= pat | <UNSPECIAL pat> | <SPECIAL pat>
5519 pat ::= unit | <OR unit ... unit>
5521 unit ::= type | <PRIMTYPE type> | atom | 'any
5522 | ANY | STRUCTURED | LOCATIVE |APPLICABLE
5523 | <struc elts> | <<OR struc ... struc> elts>
5524 | !<struc elts> | !<<OR struc ... struc> elts>
5525 | <bstruc fix> | <bstruc fix fix>
5528 struc ::= structured-type | <PRIMTYPE structured-type>
5530 bstruc ::= BYTES | <PRIMTYPE BYTES>
5532 elts ::= pat | pat elts
5534 | [fix pat ... pat] elts
5535 | [opt pat ... pat] | [REST pat ... pat]
5536 | [opt pat ... pat] [REST pat ... pat]
5538 opt ::= OPT | OPTIONAL
5543 There are some rules of thumb concerning "good" `DECL`s. A "good"
5544 `DECL` is one that is minimally offensive to the `DECL`-checking
5545 mechanism as the compiler, but that gives the maximum amount of
5546 information. It is simple to state what gives offense to the compiler
5547 and `DECL`-checking mechanism: complexity. For example, a large
5548 compound `DECL` like:
5550 #DECL ((X) <OR FIX LIST UVECTOR FALSE>)
5552 is a `DECL` that the compiler will find totally useless. It might as
5553 well be `ANY`. The more involved the `OR`, the less information the
5554 compiler will find useful in it. For example, if the function takes
5555 `<OR LIST VECTOR UVECTOR>`, maybe you should really say `STRUCTURED`.
5556 Also, a very general `DECL` indicates a very general program, which is
5557 not likely to be efficient when compiled (of course there is a
5558 trade-off here). Narrowing the `DECL` to one `PRIMTYPE` gives a great
5559 gain in compiled efficiency, to one `TYPE` still more.
5561 Another situation to be avoided is the ordinary large `DECL`, even if
5562 it is perfectly straightforward. If you have created a structure which
5563 has a very specific `DECL` and is used all over your code, it might be
5564 better as a `NEWTYPE` (see below). The advantage of a `NEWTYPE` over a
5565 large explicit `DECL` is twofold. First, the entire structure must be
5566 checked only when it is created, that is, `CHTYPE`d from its
5567 `PRIMTYPE`. As a full `DECL`, it is checked completely on entering
5568 each function and on each reassignment of `ATOM`s `DECL`ed to be it.
5569 Second, the amount of storage saved in the `DECL`s of `FUNCTION`s and
5570 so on is large, not to mention the effort of typing in and keeping up
5571 to date several instances of the full `DECL`.
5576 ### 15.4.1. GDECL and MANIFEST
5578 There are two ways to declare `GVAL`s for the `DECL`-checking
5579 mechanism. These are through the `FSUBR` `GDECL` ("global
5580 declaration") and the `SUBR` `MANIFEST`.
5582 <GDECL atoms:list Pattern ...>
5584 `GDECL` allows the type/structure of global values to be declared in
5585 much the same way as local values. Example:
5587 <GDECL (X) FIX (Y) <LIST FIX>>
5589 declares `,X` to be a `FIX`, and `,Y` to be a `LIST` containing at
5592 <MANIFEST atom atom ...>
5594 `MANIFEST` takes as arguments `ATOM`s whose `GVAL`s are declared to be
5595 constants. It is used most commonly to indicate that certain `ATOM`s
5596 are the names of offsets in structures. For example:
5601 allows the compiler to confidently open-compile applications of `X`
5602 (getting the first element of a structure), knowing that `,X` will not
5603 change. Any sort of object can be a `MANIFEST` value: if it does not
5604 get embedded in the compiled code, it is included in the `RSUBR`'s
5605 "reference vector", for fast access. However, as a general rule,
5606 structured objects should not be made `MANIFEST`: the `SETG` will
5607 instead refer to a **distinct** copy of the object in **each** `RSUBR`
5608 that does a `GVAL`. A structured object should instead be `GDECL`ed.
5610 An attempt to `SETG` a `MANIFEST` atom will cause an error, unless
5613 1. the `ATOM` was previously globally unassigned;
5614 2. the old value is `==?` to the new value; or
5615 3. `.REDEFINE` is not `FALSE`.
5617 ### 14.5.2. MANIFEST? and UNMANIFEST
5621 returns `T` if *atom* is `MANIFEST`, `#FALSE ()` otherwise.
5623 <UNMANIFEST atom atom ...>
5625 removes the `MANIFEST` of the global value of each of its arguments so
5626 that the value can be changed.
5632 ("globally bound") returns `T` if *atom* has a global value slot (that
5633 is, if it has ever been `SETG`ed, `MANIFEST`, `GDECL`ed, or `GLOC`ed
5634 (chapter 12) with a true second argument), `#FALSE ()` otherwise.
5636 14.6. NEWTYPE (again)
5637 ---------------------
5639 `NEWTYPE` gives the programmer another way to `DECL` objects. The
5640 third (and optional) argument of `NEWTYPE` is a `QUOTE`d Pattern. If
5641 given, it will be saved as the value of an association (chapter 13)
5642 using the name of the `NEWTYPE` as the item and the `ATOM` `DECL` as
5643 the indicator, and it will be used to check any object that is about
5644 to be `CHTYPE`d to the `NEWTYPE`. For example:
5646 <NEWTYPE COMPLEX-NUMBER VECTOR '<<PRIMTYPE VECTOR> FLOAT FLOAT>>
5648 creates a new `TYPE`, with its first two elements declared to be
5649 `FLOAT`s. If later someone types:
5651 #COMPLEX-NUMBER [1.0 2]
5653 an error will result (the second element is not a `FLOAT`). The
5654 Pattern can be replaced by doing another `NEWTYPE` for the same
5655 `TYPE`, or by putting a new value in the association. Further
5658 <NEWTYPE FOO LIST '<<PRIMTYPE LIST> FIX FLOAT [REST ATOM]>>
5660 causes `FOO`s to contain a `FIX` and a `FLOAT` and any number of
5665 <SET A #BAR (#BAR () 1 1.2 GRITCH)>
5667 <NEWTYPE BAR LIST '<<PRIMTYPE LIST> BAR [REST FIX FLOAT ATOM]>>
5669 This is an example of a recursively `DECL`ed `TYPE`. Note that
5670 `<1 .A>` does not satisfy the `DECL`, because it is empty, but it was
5671 `CHTYPE`d before the `DECL` was associated with `BAR`. Now, even
5672 `<CHTYPE <1 .A> <TYPE <1 .A>>>` will cause an error.
5674 In each of these examples, the `<<PRIMTYPE ...> ...>` construction was
5675 used, in order to permit `CHTYPE`ing an object into itself. See what
5678 <NEWTYPE OOPS LIST '<LIST ATOM FLOAT>>$
5680 <SET A <CHTYPE (E 2.71828) OOPS>>$
5683 Now `<CHTYPE .A OOPS>` will cause an error. Unfortunately, you must
5685 <CHTYPE <CHTYPE .A LIST> OOPS>$
5688 14.7. Controlling DECL Checking
5689 -------------------------------
5691 There are several `SUBR`s and `FSUBR`s in Muddle that are used to
5692 control and interact with the `DECL`-checking mechanism.
5694 ### 14.7.1. DECL-CHECK
5696 This entire complex checking mechanism can get in the way during
5697 debugging. As a result, the most commonly used `DECL`-oriented `SUBR`
5698 is `DECL-CHECK`. It is used to enable and disable the entire
5699 `DECL`-checking mechanism.
5701 <DECL-CHECK false-or-any>
5703 If its single argument is non-`FALSE`, `DECL` checking is turned on;
5704 if it is `FALSE`, `DECL` checking is turned off. The previous state is
5705 returned as a value. If no argument is given, `DECL-CHECK` returns the
5706 current state. In an initial Muddle `DECL` checking is on.
5708 When `DECL` checking is on, the `DECL` of an `ATOM` is checked each
5709 time it is `SET`, the arguments and results of calls to `FUNCTION`s,
5710 `RSUBR`s, and `RSUBR-ENTRY`s are checked, and the values returned by
5711 `PROG` and `REPEAT` are checked. The same is done for `SETG`s and, in
5712 particular, attempts to change `MANIFEST` global values. Attempts to
5713 `CHTYPE` an object to a `NEWTYPE` (if the `NEWTYPE` has the optional
5714 `DECL`) are also checked. When `DECL` checking is off, none of these
5715 checks is performed.
5717 ### 14.7.2. SPECIAL-CHECK and SPECIAL-MODE
5719 <SPECIAL-CHECK false-or-any>
5721 controls whether or not `SPECIAL` checking is performed at run time by
5722 the interpreter. It is initially off. Failure to declare an `ATOM` to
5723 be `SPECIAL` when it should be will produce buggy compiled code.
5725 <SPECIAL-MODE specialty:atom>
5727 sets the declaration used by default (for `ATOM`s not declared either
5728 way) and returns the previous such declaration, or the current such
5729 declaration if no argument is given. The initial declaration used by
5730 default is `UNSPECIAL`.
5732 ### 14.7.3. GET-DECL and PUT-DECL
5734 `GET-DECL` and `PUT-DECL` are used to examine and change the current
5735 `DECL` (of either the global or the local value) of an `ATOM`.
5739 returns the `DECL` Pattern (if any, otherwise `#FALSE ()`) associated
5740 with the global or local value slot of an `ATOM`. For example:
5743 #DECL ((X) <OR FIX FLOAT>)
5748 would return `<OR FIX FLOAT>` as the result of the application of
5749 `GET-DECL`. Note that because of the use of `LLOC` (or `GLOC`, for
5750 global values) the `ATOM` being examined must be bound; otherwise you
5751 will get an error! This can be gotten around by testing first with
5752 `BOUND?` (or `GBOUND?`, or by giving `GLOC` a second argument which is
5755 If the slot being examined is the global slot and the value is
5756 `MANIFEST`, then the `ATOM` `MANIFEST` is returned. If the value being
5757 examined is not `DECL`ed, `#FALSE ()` is returned.
5759 <PUT-DECL locd Pattern>
5761 makes *Pattern* be the `DECL` for the value and returns *locd*. If
5762 `<DECL-CHECK>` is true, the current value must satisfy the new
5763 Pattern. `PUT-DECL` is normally used in debugging, to change the
5764 `DECL` of an object to correspond to changes in the program. Note that
5765 it is not legal to `PUT-DECL` a "Pattern" of `MANIFEST` or
5772 specifically checks *any* against *Pattern*. For example:
5774 <DECL? '[1 2 3] '<VECTOR [REST FIX]>>$
5776 <DECL? '[1 2.0 3.0] '<VECTOR [REST FIX]>>$
5782 An `OFFSET` is essentially a `FIX` with a Pattern attached, considered
5783 as an `APPLICABLE` rather than a number. An `OFFSET` allows a program
5784 to specify the type of structure that its `FIX` applies to. `OFFSET`s,
5785 like `DECL`s -- if used properly -- can make debugging considerably
5786 easier; they will eventually also help the compiler generate more
5789 The `SUBR` `OFFSET` takes two arguments, a `FIX` and a Pattern, and
5790 returns an object of `TYPE` and `PRIMTYPE` `OFFSET`. An `OFFSET`, like
5791 a `FIX`, may be given as an argument to `NTH` or `PUT` and may be
5792 applied to arguments. The only difference is that the `STRUCTURED`
5793 argument must match the Pattern contained in the `OFFSET`, or an error
5796 <SETG FOO <OFFSET 1 '<CHANNEL FIX>>>$
5797 %<OFFSET 1 '<CHANNEL FIX>>
5804 LISTENING-AT-LEVEL 2 PROCESS 1
5806 Note: when the compiler gets around to understanding `OFFSET`s, it
5807 will not do the right thing with them unless they are `MANIFEST`.
5808 Since there's no good reason not to `MANIFEST` them, this isn't a
5811 The `SUBR` `INDEX`, given an `OFFSET`, returns its `FIX`:
5816 `GET-DECL` of an `OFFSET` returns the associated Pattern; `PUT-DECL`
5817 of an `OFFSET` and a Pattern returns a new `OFFSET` with the same
5818 `INDEX` as the argument, but with a new Pattern:
5822 <PUT-DECL ,FOO OBLIST>$
5825 %<OFFSET 1 '<CHANNEL FIX>>
5827 An `OFFSET` is not a structured object, as this example should make
5830 14.9. The RSUBR DECL
5831 --------------------
5833 The `RSUBR` `DECL` is similar to the `ATOM` `DECL`, except that the
5834 declarations are of argument positions and value rather than of
5835 specific `ATOM`s. Patterns can be preceded by `STRING`s which further
5836 describe the argument (or value).
5838 The simplest `RSUBR` `DECL` is for an `RSUBR` or `RSUBR-ENTRY`
5839 (chapter 19) which has all of its arguments evaluated and returns a
5840 `DECL`ed value. For example:
5842 #DECL ("VALUE" FIX FIX FLOAT)
5844 declares that there are two arguments, a `FIX` and a `FLOAT`, and a
5845 result which is a `FIX`. While the `STRING` `"VALUE"` is not
5846 constrained to appear at the front of the `DECL`, it does appear there
5847 by custom. It need not appear at all, if the result is not to be
5848 declared, but (again by custom) in this case it is usually declared
5851 If any arguments are optional, the `STRING` `"OPTIONAL"` (or `"OPT"`)
5852 is placed before the Pattern for the first optional argument:
5854 #DECL ("VALUE" FIX FIX "OPTIONAL" FLOAT)
5856 If any of the arguments is not to be evaluated, it is preceded by the
5859 #DECL ("VALUE" FIX "QUOTE" FORM)
5861 declares one argument, which is not `EVAL`ed.
5863 If the arguments are to be evaluated and gathered into a `TUPLE`, the
5864 Pattern for it is preceded by the `STRING` `"TUPLE"`:
5866 #DECL ("VALUE" FIX "TUPLE" <TUPLE [REST FIX]>)
5868 If the arguments are to be unevaluated and gathered into a `LIST`, or
5869 if the calling `FORM` is the only "argument", the Pattern is preceded
5870 by the appropriate `STRING`:
5872 #DECL ("VALUE" FIX "ARGS" LIST)
5874 #DECL ("VALUE" FIX "CALL" <PRIMTYPE LIST>)
5876 In every case the special indicator `STRING` is followed by a Pattern
5877 which describes the argument, even though it may sometimes produce
5878 fairly ludicrous results, since the pattern for `"TUPLE"` always must
5879 be a `TUPLE`; for `"ARGS"`, a `LIST`; and for `"CALL"`, a `FORM` or
5882 Chapter 15. Lexical Blocking
5883 ============================
5885 Lexical, or static, blocking is another means of preventing identifier
5886 collisions in Muddle. (The first was dynamic blocking -- binding and
5887 `ENVIRONMENT`s.) By using a subset of the Muddle lexical blocking
5888 facilities, the "block structure" of such languages as Algol, PL/I,
5889 SAIL, etc., can be simulated, should you wish to do so.
5891 15.1. Basic Considerations
5892 --------------------------
5894 Since what follows appears to be rather complex, a short discussion of
5895 the basic problem lexical blocking solves and Muddle's basic solution
5896 will be given first.
5898 `ATOM`s are identifiers. It is thus essential that whenever you type
5899 an `ATOM`, `READ` should respond with the unique identifier you wish
5900 to designate. The problem is that it is unreasonable to expect the
5901 `PNAME`s of all `ATOM`s to be unique. When you use an `ATOM` `A` in a
5902 program, do you mean the `A` you typed two minutes ago, the `A` you
5903 used in another one of your programs, or the `A` used by some library
5906 Dynamic blocking (pushing down of `LVAL`s) solves many such problems.
5907 However, there are some which it does not solve -- such as state
5908 variables (whether they are impure or pure). Major problems with a
5909 system having only dynamic blocking usually arise only when attempts
5910 are made to share large numbers of significant programs among many
5913 The solution used in Muddle is basically as follows: `READ` must
5914 maintain at least one table of `ATOM`s to guarantee any uniqueness.
5915 So, Muddle allows many such tables and makes it easy for the user to
5916 specify which one is wanted. Such a table is an object of `TYPE`
5917 `OBLIST` ("object list"). All the complication which follows arises
5918 out of a desire to provide a powerful, easily used method of working
5919 with `OBLIST`s, with reasonable values used by default.
5924 An `OBLIST` is of `PRIMTYPE` `UVECTOR` with `UTYPE` `LIST`; the `LIST`
5925 holds `ATOM`s. The `ATOM`s are ordered by a hash coding on their
5926 `PNAME`s: each `LIST` is a hashing bucket.) What follows is
5927 information about `OBLIST`s as such.
5929 ### 15.2.1. OBLIST Names
5931 Every normally constituted `OBLIST` has a name. The name of an
5932 `OBLIST` is an `ATOM` associated with the `OBLIST` under the indicator
5935 <GETPROP oblist OBLIST>
5941 returns the name of *oblist*.
5943 Similarly, every name of an `OBLIST` is associated with its `OBLIST`,
5944 again under the indicator `OBLIST`, so that
5946 <GETPROP oblist-name:atom OBLIST>
5950 <GET oblist-name:atom OBLIST>
5952 returns the `OBLIST` whose name is *oblist-name*.
5954 Since there is nothing special about the association of `OBLIST`s and
5955 their names, the name of an `OBLIST` can be changed by the use of
5956 `PUTPROP`, both on the `OBLIST` and its name. It is not wise to change
5957 the `OBLIST` association without changing the name association, since
5958 you are likely to confuse `READ` and `PRINT` terribly.
5960 You can also use `PUT` or `PUTPROP` to remove the association between
5961 an `OBLIST` and its name completely. If you want the `OBLIST` to go
5962 away (be garbage collected), **and** you want to keep its name around,
5963 this must be done: otherwise the association will force it to stay,
5964 even if there are no other references to it. (If you have no
5965 references to either the name or the `OBLIST` (an `ATOM` -- including
5966 a `TYPE` name -- points to its `OBLIST`), both of them -- and their
5967 association -- will go away without your having to remove the
5968 association, of course.) It is not recommended that you remove the
5969 name of an `OBLIST` without having it go away, since then `ATOM`s in
5970 that `OBLIST` will `PRINT` the name as if they were in no `OBLIST` --
5971 which is defeating the purpose of this whole exercise.
5977 ("make oblist") creates and returns a new `OBLIST`, containing no
5978 `ATOM`s, whose name is *atom*, unless there already exists an `OBLIST`
5979 of that name, in which case it returns the existing `OBLIST`. *fix* is
5980 the size of the `OBLIST` created -- the number of hashing buckets.
5981 *fix* is optional (ignored if the `OBLIST` already exists), 13 by
5982 default. If specified, *fix* should be a prime number, since that
5983 allows the hashing to work better.
5989 returns `#FALSE ()` if *atom* is not in any `OBLIST`. If *atom* is in
5990 an `OBLIST`, it returns that `OBLIST`.
5992 15.3. READ and OBLISTs
5993 ----------------------
5995 `READ` can be explicitly told to look up an `ATOM` in a particular
5996 `OBLIST` by giving the `ATOM` a **trailer**. A trailer consists of the
5997 characters `!-` (exclamation-point dash) following the `ATOM`,
5998 immediately followed by the name of the `OBLIST`. For example,
6002 specifies the unique `ATOM` of `PNAME` `A` which is in the `OBLIST`
6003 whose name is the `ATOM` `OB`.
6005 Note that the name of the `OBLIST` must follow the `!-` with **no**
6006 separators (like space, tab, carriage-return, etc.). There is a name
6007 used by default (section 15.5) which types out and is typed in as
6010 Trailers can be used recursively:
6014 specified the unique `ATOM` of `PNAME` `B` which is in the `OBLIST`
6015 whose name is the unique `ATOM` of `PNAME` `A` which is in the
6016 `OBLIST` whose name is `OB`. (Whew!) The repetition is terminated by
6017 the look-up and insertion described below.
6019 If an `ATOM` with a given `PNAME` is not found in the `OBLIST`
6020 specified by a trailer, a new `ATOM` with that `PNAME` is created and
6021 inserted into that `OBLIST`.
6023 If an `OBLIST` whose name is given in a trailer does not exist, `READ`
6024 creates one, of length 13 buckets.
6026 If trailer notation is not used (the "normal" case), and for an `ATOM`
6027 that terminates a trailer, `READ` looks up the `PNAME` of the `ATOM`
6028 in a `LIST` of `OBLIST`s, the `LVAL` of the `ATOM` `OBLIST` by
6029 default. This look-up starts with `<1 .OBLIST>` and continues until
6030 `.OBLIST` is exhausted. If the `ATOM` is not found. `READ` usually
6031 inserts it into `<1 .OBLIST>`. (It is possible to force `READ` to use
6032 a different element of the `LIST` of `OBLIST`s for new insertions. If
6033 the `ATOM` `DEFAULT` is in that `LIST`, the `OBLIST` following that
6034 `ATOM` will be used.)
6036 15.4. PRIN1 and OBLISTs
6037 -----------------------
6039 When `PRINT` is given an `ATOM` to output, it outputs as little of the
6040 trailer as is necessary to specify the `ATOM` uniquely to `READ`. That
6041 is, if the `ATOM` is the **first** `ATOM` of that `PNAME` which `READ`
6042 would find in its normal look-up in the current `.OBLIST`, no trailer
6043 is output. Otherwise, `!-` is output and the name of the `OBLIST` is
6044 recursively `PRIN1`ed.
6046 Warning: there are obscure cases, which do not occur in normal
6047 practice, for which the `PRINT` trailer does not terminate. For
6048 instance, if an `ATOM` must have a trailer printed, and the name of
6049 the `OBLIST` is an `ATOM` in that very same `OBLIST`, death. Any
6050 similar case will also give `PRINT` a hernia.
6055 In an initial Muddle, `.OBLIST` contains two `OBLIST`s. `<1 .OBLIST>`
6056 initially contains no `ATOM`s, and `<2 .OBLIST>` contains all the
6057 `ATOM`s whose `GVAL` are `SUBR`s or `FSUBR`s, as well as `OBLIST`,
6058 `DEFAULT`, `T`, etc. It is difficult to lose track of the latter; the
6059 specific trailer `!-`*separator* will **always** cause references to
6060 that `OBLIST`. In addition, the `SUBR` `ROOT`, which takes no
6061 arguments, always returns that `OBLIST`.
6063 The name of `<ROOT>` is `ROOT`; this `ATOM` is in `<ROOT>` and would
6064 cause infinite recursion were it not for the use of `!-`*separator*.
6065 The name of the initial `<1 .OBLIST>` is `INITIAL` (really
6068 The `ATOM` `OBLIST` also has a `GVAL`. `,OBLIST` is initially the same
6069 as `.OBLIST`; however, `,OBLIST` is not affected by the `SUBR`s used
6070 to manipulate the `OBLIST` structure. It is instead used only when
6073 In the case of an error, the current `.OBLIST` is checked to see if it
6074 is "reasonable" -- that is, contains nothing of the wrong `TYPE`. (It
6075 is reasonable, but not standard, for `.OBLIST` to be a single `OBLIST`
6076 instead of a `LIST` of them.) If it is reasonable, that value stays
6077 current. Otherwise, `OBLIST` is `SET` to `,OBLIST`. Note that changes
6078 made to the `OBLIST`s on `,OBLIST` -- for example, new `ATOM`s added
6079 -- remain. If even `,OBLIST` is unreasonable, `OBLIST` is `SET` and
6080 `SETG`ed to its initial value. `<ERRET>` (section 16.4) always assumes
6081 that `.OBLIST` is unreasonable.
6083 Three other `OBLIST`s exist in a virgin Muddle: their names and
6084 purposes are as follows:
6086 `ERRORS!-` contains `ATOM`s whose `PNAME`s are used as error messages.
6087 It is returned by `<ERRORS>`.
6089 `INTERRUPTS!-` is used by the interrupt system (section 21.5.1). It is
6090 returned by `<INTERRUPTS>`.
6092 `MUDDLE!-` is used infrequently by the interpreter when loading
6093 compiled programs to fix up references to locations within the
6096 The pre-loading of compiled programs may create other `OBLIST`s in an
6097 initialized Muddle (Lebling, 1979).
6099 15.6. BLOCK and ENDBLOCK
6100 ------------------------
6102 These `SUBR`s are analogous to **begin** and **end** in Algol, etc.,
6103 in the way they manipulate static blocking (and in **no** other way.)
6105 <BLOCK look-up:list-of-oblists>
6107 returns its argument after "pushing" the current `LVAL` of the `ATOM`
6108 `OBLIST` and making its argument the current `LVAL`. You usually want
6109 `<ROOT>` to be an element of *look-up*, normally its last.
6113 "pops" the LVAL of the `ATOM` `OBLIST` and returns the resultant
6114 `LIST` of `OBLIST`s.
6116 Note that this "pushing" and "popping" of `.OBLIST` is entirely
6117 independent of functional application, binding, etc.
6119 15.7. SUBRs Associated with Lexical Blocking
6120 --------------------------------------------
6122 ### 15.7.1. READ (again)
6124 <READ channel eof-routine look-up>
6126 This is a fuller call to `READ`. *look-up* is an `OBLIST` or a `LIST`
6127 of them, used as stated in section 15.3 to look up `ATOM`s and insert
6128 them in `OBLIST`s. If not specified, `.OBLIST` is used. See also
6129 section 11.1.1.1, 11.3, and 17.1.3 for other arguments.
6131 ### 15.7.2. PARSE and LPARSE (again)
6133 <PARSE string radix:fix look-up>
6135 as was previously mentioned, applies `READ`'s algorithm to *string*
6136 and returns the first Muddle object resulting. This **includes**
6137 looking up prospective `ATOM`s on *look-up*, if given, or `.OBLIST`.
6138 `LPARSE` can be called in the same way. See also section 7.6.6.2 and
6139 17.1.3 for other arguments.
6143 <LOOKUP string oblist>
6145 returns the `ATOM` of `PNAME` *string* in the `OBLIST` *oblist*, if
6146 there is such an `ATOM`; otherwise, it returns `#FALSE ()`. If
6147 *string* would `PARSE` into an `ATOM` anyway, `LOOKUP` is faster,
6148 although it looks in only one `OBLIST` instead of a `LIST` of them.
6154 creates and returns a spanking new `ATOM` of `PNAME` *string* which is
6155 guaranteed not to be on **any** `OBLIST`.
6157 An `ATOM` which is not on any `OBLIST` is `PRINT`ed with a trailer of
6162 <REMOVE string oblist>
6164 removes the `ATOM` of `PNAME` *string* from *oblist* and returns that
6165 ATOM. If there is no such `ATOM`, `REMOVE` returns `#FALSE ()`. Also,
6169 removes *atom* from its `OBLIST`, if it is on one. It returns *atom*
6170 if it was on an `OBLIST`; otherwise it returns `#FALSE ()`.
6174 <INSERT string-or-atom oblist>
6176 creates an `ATOM` of `PNAME` *string*, inserts it into *oblist* and
6177 returns it. If there is already an `ATOM` with the same `PNAME` as
6178 *atom* in *oblist*, an error occurs. The standard way to avoid the
6179 error and always get your *atom* is
6181 <OR <LOOKUP string oblist> <INSERT string oblist>>
6183 As with `REMOVE`, `INSERT` can also take an `ATOM` as its first
6184 argument; this `ATOM` must not be on any `OBLIST` -- it must have been
6185 `REMOVE`d, or just created by `ATOM` -- else an error occurs. The
6186 `OBLIST` argument is **never** optional. If you would like the new
6187 `ATOM` to live in the `OBLIST` that `READ` would have chosen, you can
6188 `<PARSE string>` instead.
6194 returns a `STRING` (newly created) which is *atom*'s `PNAME` ("printed
6195 name"). If trailers are not needed, `PNAME` is much faster than
6196 `UNPARSE` on *atom*. (In fact, `UNPARSE` has to go all the way through
6197 the `PRINT` algorithm **twice**, the first time to see how long a
6198 `STRING` is needed.)
6202 `SPNAME` ("shared printed name") is identical to `PNAME`, except that
6203 the `STRING` it returns shares storage with *atom* (appendix 1), which
6204 is more efficient if the `STRING` will not be modified. `PUT`ting into
6205 such a `STRING` will cause an error.
6207 15.8. Example: Another Solution to the INC Problem
6208 --------------------------------------------------
6210 What follows is an example of the way `OBLIST`s are "normally" used to
6211 provide "externally available" `ATOM`s and "local" `ATOM`s which are
6212 not so readily available externally. Lebling (1979) describes a
6213 systematic way to accomplish the same thing and more.
6216 ;"Create an OBLIST to hold your external symbols.
6217 Its name is INCO!-INITIAL!- ."
6220 ;"Put your external symbols into that OBLIST.
6221 If you have many, just write them successively."
6223 <BLOCK (<MOBLIST INCI!-INCO 1> <GET INCO OBLIST> <ROOT>)>
6224 ;"Create a local OBLIST, naming it INCI!-INCO, and set up
6225 .OBLIST for reading in your program. The OBLIST INCO is
6226 included in the BLOCK so that as your external symbols are
6227 used, they will be found in the right place. Note that the
6228 ATOM INCO is not in any OBLIST of the BLOCK; therefore,
6229 trailer notation of !-INCO will not work within the current
6230 BLOCK-ENDBLOCK pair."
6232 <DEFINE INC ;"INC is found in the INCO OBLIST."
6233 (A) ;"A is not found and is therefore put into INCI by
6235 #DECL ((VALUE A) <OR FIX FLOAT>)
6236 <SET .A <+ ..A 1>>> ;"All other ATOMs are found in the
6240 This example is rather trivial, but it contains all of the issues, of
6241 which there are three.
6243 The first idea is that you should create two `OBLIST`s, one to hold
6244 `ATOM`s which are to be known to other users (`INCO`), and the other
6245 to hold internal `ATOM`s which are not normally of interest to other
6246 (`INCI`). The case above has one `ATOM` in each category.
6248 Second, `INCO` is explicitly used **without** trailers so that
6249 surrounding `BLOCK` and `ENDBLOCK`s will have an effect on it. Thus
6250 `INCO` will be in the `OBLIST` desired by the user; `INC` will be in
6251 `INCO`, and the user can refer to it by saying `INC!-INCO`; `INCI`
6252 will also be in `INCO`, and can be referred to in the same way;
6253 finally, `A` is really `A!-INCI!-INCO`. The point of all this is to
6254 structure the nesting of `OBLIST`s.
6256 Finally, if for some reason (like saving storage space) you wish to
6257 throw `INCI` away, you can follow the `ENDBLOCK` with
6259 <REMOVE "INCI" <GET INCO OBLIST>>
6261 and thus remove all references to it. The ability to do such pruning
6262 is one reason for structuring `OBLIST` references.
6264 Note that, even after removing `INCI`, you can "get `A` back" -- that
6265 is, be able to type it in -- by saying something of the form
6267 <INSERT <1 <1 ,INC!-INCO>> <1 .OBLIST>>
6269 thereby grabbing `A` out of the structure of `INC` and re-inserting it
6270 into an `OBLIST`. however, this resurrects the name collision caused
6273 Chapter 16. Errors, Frames, etc.
6274 ================================
6279 This `SUBR` takes any number of arguments. It first checks the `LVAL`s
6280 of `INCHAN`, `OUTCHAN`, and `OBLIST` for reasonability and terminal
6281 usability. In each case, if the value is unreasonable, the `ATOM` is
6282 rebound to the corresponding `GVAL`, if reasonable, or to an invented
6283 reasonable value. `LISTEN` then does `<TTYECHO .INCHAN T>` and
6284 `<ECHOPAIR .INCHAN .OUTCHAN>`. Next, it `PRINT`s its arguments, then
6287 LISTENING-AT-LEVEL i PROCESS p
6289 where *i* is an integer (`FIX`) which is incremented each time
6290 `LISTEN` is called recursively, and *p* is an integer identifying the
6291 `PROCESS` (chapter 20) in which the `LISTEN` was `EVAL`ed. `LISTEN`
6292 then does `<APPLY <VALUE REP>>`, if there is one, and if it is
6293 `APPLICABLE`. If not, it applies the `SUBR` `REP` (without making a
6294 new `FRAME` -- see below). This `SUBR` drops into an infinite
6295 `READ`-`EVAL`-`PRINT` loop, which can be left via `ERRET` (section
6298 The standard `LISTEN` loop has two features for getting a handle on
6299 objects that you have typed in and Muddle has typed out. If the `ATOM`
6300 `L-INS` has a local value that is a `LIST`, `LISTEN` will keep recent
6301 inputs (what `READ` returns) in it, most recent first. Similarly, if
6302 the `ATOM` `L-OUTS` has a local value that is a `LIST`, `LISTEN` will
6303 keep recent outputs (what `EVAL` returns) in it, most recent first.
6304 The keeping is done before the `PRINT`ing, so that \^S does not defeat
6305 its purpose. The user can decide how much to keep around by setting
6306 the length of each `LIST`. Even if `L-OUTS` is not used, the atom
6307 `LAST-OUT` is always `SET` to the last object returned by `EVAL` in
6308 the standard `LISTEN` loop. Example:
6310 <SET L-INS (NEWEST NEWER NEW)>$
6313 (.L-INS NEWEST NEWER)
6316 <SET FIXIT <2 .LINS>> ;"grab the last input"$
6319 (.L-INS <SET FIXIT <2 .L-INS>> <SET FOO 69>)
6325 (.L-INS <EVAL .FIXIT> <PUT .FIXIT 3 105>)
6332 This `SUBR` is the same as `LISTEN`, except that (1) it generates an
6333 interrupt (chapter 21), if enabled. and (2) it `PRINT`s `*ERROR*`
6334 before `PRINT`ing its arguments.
6336 When any `SUBR` or `FSUBR` detects an anomalous condition (for
6337 example, its arguments are of the wrong `TYPE`), it calls `ERROR` with
6338 at least two arguments, including:
6340 1. an `ATOM` whose `PNAME` describes the problem, normally from the
6341 `OBLIST` `ERRORS!-` (appendix 4),
6342 2. the `ATOM` that names the `SUBR` or `FSUBR`, and
6343 3. any other information of interest, and **then returns whatever the
6344 call to `ERROR` returns**. Exception: a few (for example `DEFINE`)
6345 will take further action that depends on the value returned. This
6346 nonstandard action is specified in the error message (first
6349 16.3. FRAME (the TYPE)
6351 A `FRAME` is the object placed on a `PROCESS`'s control stack (chapter
6352 20) whenever a `SUBR`, `FSUBR`, `RSUBR`, or `RSUBR-ENTRY` (chapter 19)
6353 is applied. (These objects are herein collectively called
6354 "Subroutines".) It contains information describing what was applied,
6355 plus a `TUPLE` whose elements are the arguments to the Subroutine
6356 applied. If any of the Subroutine's arguments are to be evaluated,
6357 they will have been by the time the `FRAME` is generated.
6359 A `FRAME` is an anomalous `TYPE` in the following ways:
6361 1. It cannot be typed in. It can be generated only by applying a
6363 2. It does not type out in any standard format, but rather as
6364 `#FRAME` followed by the `PNAME`of the Subroutine applied.
6370 ("arguments") returns the argument `TUPLE` of *frame*.
6376 ("function"} returns the `ATOM` whose `G/LVAL` is being applied in
6379 16.3.3. FRAME (the SUBR)
6383 returns the `FRAME` stacked **before** *frame* or, if there is none,
6384 it will generate an error. The oldest (lowest) `FRAME` that can be
6385 returned without error has a `FUNCT` of `TOPLEVEL`. If called with no
6386 arguments, `FRAME` returns the topmost `FRAME` used in an application
6387 of `ERROR` or `LISTEN`, which was bound by the interpreter to the
6388 `ATOM` `LERR\ I-INTERRUPTS` ("last error").
6392 Say you have gotten an error. You can now type at `ERROR`'s `LISTEN`
6393 loop and get things `EVAL`ed. For example,
6397 <FUNCT <FRAME <FRAME>>>$
6398 the-name-of-the-Subroutine-which-called-ERROR:atom
6399 <ARGS <FRAME <FRAME>>>$
6400 the-arguments-to-the-Subroutine-which-called-ERROR:tuple
6406 This `SUBR` ("error return") (1) causes the control stack to be
6407 stripped down to the level of *frame*, and (2) **then** returns *any*.
6408 The net result is that the application which generated *frame* is
6409 forced to return *any*. Additional side effects that would have
6410 happened in the absence of an error may not have happened.
6412 The second argument to `ERRET` is optional, by default the `FRAME` of
6413 the last invocation of `ERROR` or `LISTEN`.
6415 If `ERRET` is called with **no** arguments, it drops you **all** the
6416 way down to the **bottom** of the control stack -- **before** the
6417 level-1 `LISTEN` loop -- and then calls `LISTEN`. As always, `LISTEN`
6418 first ensures that Muddle is receptive.
6426 LISTENING-AT-LEVEL 2 PROCESS 1
6427 <ARGS <FRAME <FRAME>>>$
6429 <ERRET 5>$ ;"This causes the + to return 5."
6430 15 ;"finally returned by the *"
6432 Note that when you are in a call to `ERROR`, the most recent set of
6433 bindings is still in effect. This means that you can examine values of
6434 dummy variables while still in the error state. For example,
6436 <DEFINE F (A "AUX" (B "a string"))
6437 #DECL ((VALUE) LIST (A) STRUCTURED (B) STRING)
6438 (.B <REST .A 2>) ;"Return this LIST.">$
6445 LISTENING-AT-LEVEL 2 PROCESS 1
6450 <ERRET '(5)> ; "Make the REST return (5)."$
6457 causes the control stack to be stripped down just beyond *frame*, and
6458 then causes the Subroutine call that generated *frame* to be done
6459 again. *frame* is optional, by default the `FRAME` of the last
6460 invocation of `ERROR` or `LISTEN`. `RETRY` differs from `AGAIN` in
6461 that (1) it is not intended to be used in programs; (2) it can retry
6462 any old *frame* (any Subroutine call), whereas `AGAIN` requires an
6463 `ACTIVATION` (`PROG` or `REPEAT` or `"ACT"`); and (3) if it retries
6464 the `EVAL` of a `FORM` that makes an `ACTIVATION`, it will cause
6465 rebinding in the argument `LIST`, thus duplicating side effects.
6469 `UNWIND` is an `FSUBR` that takes two arguments, usually `FORM`s. It
6470 `EVAL`s the first one, and, if the `EVAL` returns normally, the value
6471 of the `EVAL` call is the value of `UNWIND`. If, however, during the
6472 `EVAL` a non-local return attempts to return below the `UNWIND`
6473 `FRAME` in the control stack, the second argument is `EVAL`ed, its
6474 value is ignored, and the non-local return is completed. The second
6475 argument is evaluated in the environment that was present when the
6476 call to `UNWIND` was made. This facility is useful for cleaning up
6477 data bases that are in inconsistent states and for closing temporary
6478 `CHANNEL`s that may be left around. `FLOAD` sets up an `UNWIND` to
6479 close its `CHANNEL` if the user attempts to `ERRET` without finishing
6480 the `FLOAD`. Example:
6482 <DEFINE CLEAN ACT ("AUX" (C <OPEN "READ" "A FILE">))
6483 #DECL ((C) <OR CHANNEL FALSE> ...)
6485 <UNWIND <PROG () ... <CLOSE .C>>
6488 16.7. Control-G (\^G)
6490 Typing control-G (\^G, `<ASCII 7>`) at Muddle causes it to act just as
6491 if an error had occurred in whatever was currently being done. You can
6492 then examine the values of variables as above, continue by applying
6493 `ERRET` to one argument (which is ignored), `RETRY` a `FRAME` lower on
6494 the control stack, or flush everything by applying `ERRET` to no
6497 16.8. Control-S (\^S)
6499 Typing control-S (\^S, `<ASCII 19>`) at Muddle causes it to stop what
6500 is happening and return to the `FRAME` `.LERR\ !-INTERRUPTS`,
6501 returning the `ATOM` `T`. (In the Tenex and Tops-20 versions, \^O also
6502 has the same effect.)
6506 <OVERFLOW false-or-any>
6508 There is one error that can be disabled: numeric overflow and
6509 underflow caused by the arithmetic `SUBR`s (`+`, `-`, `*`, `/`). The
6510 `SUBR` `OVERFLOW` takes one argument: if it is of `TYPE` `FALSE`,
6511 under/overflow errors are disabled; otherwise they are enabled. The
6512 initial state is enabled. `OVERFLOW` returns `T` or `#FALSE ()`,
6513 reflecting the previous state. Calling it with no argument returns the
6516 Chapter 17. Macro-operations
6517 ============================
6522 ### 17.1.1. % and %%
6524 The tokens `%` and `%%` are interpreted by `READ` in such a way as to
6525 give a "macro" capability to Muddle similar to PL/I's.
6527 Whenever `READ` encounters a single `%` -- anywhere, at any depth of
6528 recursion -- it **immediately**, without looking at the rest of the
6529 input, evaluates the object following the `%`. The result of that
6530 evaluation is used by `READ` in place of the object following the `%`.
6531 That is, `%` means "don't really `READ` this, use `EVAL` of it
6532 instead." `%` is often used in files in front of calls to `ASCII`,
6533 `BITS` (which see), etc., although when the `FUNCTION` is compiled the
6534 compiler will do the evaluation if the arguments are constant. Also
6535 seen is `%.INCHAN`, read as the `CHANNEL` in use during `LOAD` or
6536 `FLOAD`; for example, `<PUT %.INCHAN 18 8>` causes succeeding `FIX`es
6537 to be read as octal.
6539 Whenever `READ` encounters `%%`, it likewise immediately evaluates the
6540 object following the `%%`. However, it completely ignores the result
6541 of that evaluation. Side effects of that evaluation remain, of course.
6545 <DEFINE SETUP () <SET A 0>>$
6547 <DEFINE NXT () <SET A <+ .A 1>>>$
6549 [%%<SETUP> %<NXT> %<NXT> (%%<SETUP>) %<NXT>]$
6554 <LINK exp:any string oblist>
6556 creates an object of `TYPE` `LINK`, `PRIMTYPE` `ATOM`. A `LINK` looks
6557 vaguely like an `ATOM`; it has a `PNAME` (the *string* argument),
6558 resides in an `OBLIST` (the *oblist* argument) and has a "value" (the
6559 *exp* argument). A `LINK` has the strange property that, whenever it
6560 is encountered by `READ` (that is, its `PNAME` is read, just like an
6561 `ATOM`, possibly with `OBLIST` trailers), `READ` substitutes the
6562 `LINK`'s "value" for the `LINK` immediately. The effect of `READ`ing a
6563 `LINK`'s `PNAME` is exactly the same as the effect of reading its
6566 The *oblist* argument is optional, `<1 .OBLIST>` by default. `LINK`
6567 returns its first argument. The `LINK` is created via `INSERT`, so an
6568 error results if there is already an `ATOM` or `LINK` in *oblist* with
6571 The primary use of `LINK`s is in interactive work with Muddle:
6572 expressions which are commonly used, but annoyingly long to type, can
6573 be "linked" to `PNAME`s which are shorter. The standard example is the
6576 <LINK '<ERRET> "^E" <ROOT>>
6578 which links the `ATOM` of `PNAME` `^E` in the `ROOT` `OBLIST` to the
6579 expression `<ERRET>`.
6581 ### 17.1.3. Program-defined Macro-characters
6583 During `READ`ing from an input `CHANNEL` or `PARSE`ing a `STRING`, any
6584 character can be made to have a special meaning. A character can cause
6585 an arbitrary routine to be invoked, which can then return any number
6586 of elements to be put into the object being built by `READ`, `PARSE`,
6587 or `LPARSE`. Translation of characters is also possible. This facility
6588 was designed for those persons who want to use Muddle `READ` to do
6589 large parts of their input but have to modify its actions for some
6590 areas: for example, one might want to treat left and right parentheses
6591 as tokens, rather than as delimiters indicating a `LIST`.
6593 #### 17.1.3.1. READ (finally)
6595 Associated with `READ` is an `ATOM`, `READ-TABLE!-`, whose local
6596 value, if any, must be a `VECTOR` of elements, one for each character
6597 up to and including all characters to be treated specially. Each
6598 element indicates, if not `0`, the action to be taken upon `READ`'s
6599 encounter with that character. A similar `VECTOR`, the local value of
6600 `PARSE-TABLE!-`, if any, is used to find the action to take for
6601 characters encountered when `PARSE` or `LPARSE` is applied to a
6604 These tables can have up to 256 elements, one for each ASCII character
6605 and one for each possible exclamation-point/ASCII-character pair. In
6606 Muddle, the exclamation-point is used as a method of expanding the
6607 ASCII character set, and an exclamation-point/character pair is
6608 treated as one logical character when not reading a `STRING`.
6610 The element corresponding to a character is
6611 `<NTH table <+ 1 <ASCII char>>>`. The element corresponding to an
6612 exclamation-point/ASCII-character pair is
6613 `<NTH table <+ 129 <ASCII char>>>`. The table can be shorter than 256
6614 elements, in which case it is treated as if it were 256 long with `0`
6615 elements beyond its actual length.
6617 An element of the tables must satisfy one of the following `DECL`
6620 > `'0` indicates that no special action is to be taken when this
6621 > character is encountered.
6623 > `CHARACTER` indicates that the encountered character is to be
6624 > translated into the given `CHARACTER` whenever it appears, except
6625 > when as an object of `TYPE` `CHARACTER`, or in a `STRING`, or
6626 > immediately following a `\`.
6628 > `FIX` indicates that the character is to be given the same treatment
6629 > as the character with the ASCII value of the `FIX`. This allows you
6630 > to cause other characters to be treated in the same way as A-Z for
6631 > example. The same exceptions apply as for a `CHARACTER`.
6633 > `<LIST FIX>` indicates the same thing, except that the character
6634 > does not by itself cause a break. Therefore, if it occurs when
6635 > reading an `ATOM` or number, it will be treated as part of that
6638 > `APPLICABLE` (to one argument) indicates that the character is to be
6639 > a break character. Whenever it is encountered, the reading of the
6640 > current object is finished, and the corresponding element of the
6641 > table is `APPLY`ed to the ASCII `CHARACTER`. (If `READ` is called
6642 > during the application, the end-of-file slot of the `CHANNEL`
6643 > temporarily contains a special kind of `ACTIVATION` (`TYPE` `READA`)
6644 > so that end-of-file can be signalled properly to the original
6645 > `READ`. Isn't that wonderful?) The value returned is taken to be
6646 > what was read, unless an object of `TYPE` `SPLICE` is returned. If
6647 > so, the elements of this object, which is of `PRIMTYPE` `LIST`, are
6648 > spliced in at the point where Muddle is reading. An empty `SPLICE`
6649 > allows one to return nothing. If a structured object is not being
6650 > built, and a `SPLICE` is returned, elements after the first will be
6651 > ignored. A `SPLICE` says "expand me", whereas the structure
6652 > containing a `SEGMENT` says "I will expand you".
6654 > `<LIST APPLICABLE>` indicates the same thing, except that the
6655 > character does not by itself cause a break. Therefore, if it occurs
6656 > when reading an `ATOM` or number, it will be treated as part of that
6659 `READ` takes an additional optional argument, which is what to use
6660 instead of the local value of the `ATOM` `READ-TABLE` as the `VECTOR`
6661 of read-macro characters. If this argument is supplied, `READ-TABLE`
6662 is rebound to it within the call to `READ`. `READ` takes from zero to
6663 four arguments. The fullest call to `READ` is thus:
6665 <READ channel eof-routine look-up read-table:vector>
6667 The other arguments are explained in sections 11.1.1.1, 11.3, and
6670 `ERROR` and `LISTEN` rebind `READ-TABLE` to the `GVAL` of
6671 `READ-TABLE`, if any, else `UNASSIGN` it.
6673 #### 17.1.3.2. Examples
6675 Examples of each of the different kinds of entries in macro tables:
6677 <SET READ-TABLE <IVECTOR 256 0>>$
6680 <PUT .READ-TABLE <+ 1 <ASCII !\a>> !\A>
6681 ;"CHARACTER: translate a to A."$
6686 <PUT .READ-TABLE <+ 1 <ASCII !\%>> <ASCII !\A>>
6687 ;"FIX: make % just a normal ASCII character."$
6692 <PUT .READ-TABLE <+ 1 <ASCII !\.>> (<ASCII !\.>)>
6693 ;"<LIST FIX>: make comma no longer a break
6694 character, but still special if at a break."$
6698 ;"That was an ATOM with PNAME A,B ."
6701 ;"That was the FORM <GVAL B> ."
6703 <PUT .READ-TABLE <+ 1 <ASCII !\:>>
6704 #FUNCTION ((X) <LIST COLON <READ>>)>
6705 ;"APPLICABLE: make a new thing like ( < and [ ."$
6711 (COLON (COLON (COLON FOO)))
6713 <PUT .READ-TABLE <+ 1 <ASCII !\:>>
6714 '(#FUNCTION ((X) <LIST COLON <READ>>))>
6715 ;"<LIST APPLICABLE>: like above, but not a break
6720 ;"That was an ATOM."
6722 (COLON (COLON (COLON FOO)))
6724 #### 17.1.3.3. PARSE and LPARSE (finally)
6726 <PARSE string radix look-up parse-table:vector look-ahead:character>
6728 is the fullest call to `PARSE`. `PARSE` can take from zero to five
6729 arguments. If `PARSE` is given no arguments, it returns the first
6730 object parsed from the local value of the `STRING` `PARSE-STRING` and
6731 additionally `SET`s `PARSE-STRING` to the `STRING` having those
6732 `CHARACTER`s which were parsed `REST`ed off. If `PARSE` is given a
6733 `STRING` to parse, the `ATOM` `PARSE-STRING` is rebound to the
6734 `STRING` within that call. If the *parse-table* argument is given to
6735 `PARSE`, `PARSE-TABLE` is rebound to it within that call to `PARSE`.
6736 Finally, `PARSE` can take a *look-ahead* `CHARACTER`, which is treated
6737 as if it were logically concatenated to the front of the *string*
6738 being parsed. Other arguments are described in sections 7.6.6.2 and
6741 `LPARSE` is exactly like `PARSE`, except that it tries to parse the
6742 whole `STRING`, returning a `LIST` of the objects created.
6747 An `EVAL` macro provides the convenience of a `FUNCTION` without the
6748 overhead of calling, `SPECIAL`s, etc. in the **compiled** version. A
6749 special-purpose function that is called often by `FUNCTION`s that will
6750 be compiled is a good candidate for an `EVAL` macro.
6752 ### 17.2.1. DEFMAC and EXPAND
6754 `DEFMAC` ("define macro") is syntactically exactly the same as
6755 `DEFINE`. However, instead of creating a `FUNCTION`, `DEFMAC` creates
6756 a `MACRO`. A `MACRO` is of `PRIMTYPE` `LIST` and in fact has a
6757 `FUNCTION` (or other `APPLICABLE` `TYPE`) as its single element.
6759 A `MACRO` can itself be applied to arguments. A `MACRO` is applied in
6760 a funny way, however: it is `EVAL`ed twice. The first `EVAL` causes
6761 the `MACRO`'s element to be applied to the `MACRO`'s arguments.
6762 Whatever that application returns (usually another `FORM`) is also
6763 `EVAL`ed. The result of the second `EVAL`uation is the result of
6764 applying the `MACRO`. `EXPAND` is used to perform the first `EVAL`
6767 To avoid complications, the first `EVAL` (by `EXPAND`, to create the
6768 object to be `EVAL`ed the second time around) is done in a top-level
6769 environment. The result of this policy is that two syntactically
6770 identical invocations of a `MACRO` always return the same expansion to
6771 be `EVAL`ed in the second step. The first `EVAL` generates two extra
6772 `FRAME`s: one for a call to `EXPAND`, and one for a call to `EVAL` the
6773 `MACRO` application in a top-level environment.
6777 <DEFMAC INC (ATM "OPTIONAL" (N 1))
6778 #DECL ((VALUE) FORM (ATM) ATOM (N) <OR FIX FLOAT>)
6779 <FORM SET .ATM <FORM + <FORM LVAL .ATM> .N>>>$
6782 #MACRO (#FUNCTION ((ATM "OPTIONAL" (N 1)) ...))
6792 Perhaps the intention is clearer if `PARSE` and `%` are used:
6794 <DEFMAC INC (ATM "OPTIONAL" (N 1))
6796 <PARSE "<SET %.ATM <+ %.ATM %.N>>">>
6798 `MACRO`s really exhibit their advantages when they are compiled. The
6799 compiler will simply cause the first `EVAL`uation to occur (via
6800 `EXPAND`) and compile the result. The single element of a compiled
6801 `MACRO` is an `RSUBR` or `RSUBR-ENTRY`.
6805 Suppose you want to change the following simple `FUNCTION` to a
6808 <DEFINE DOUBLE (X) #DECL ((X) FIX) <+ .X .X>>
6810 You may be tempted to write:
6812 <DEFMAC DOUBLE (X) #DECL ((X) FIX) <FORM + .X .X>>
6814 This `MACRO` works, but only when the argument does not use temporary
6817 <DEFINE TRIPLE (Y) <+ .Y <DOUBLE .Y>>>
6819 If this `FUNCTION` is applied, the top-level binding of `Y` is used,
6820 not the binding just created by the application. Compilation of this
6821 `FUNCTION` would probably fail, because the compiler probably would
6822 have no top-level binding for `Y`. Well, how about
6824 <DEFMAC DOUBLE ('X) <FORM + .X .X>> ;"The DECL has to go."
6826 Now this is more like the original `FUNCTION`, because no longer is
6827 the argument evaluated and the result evaluated again. And `TRIPLE`
6828 works. But now consider
6830 <DEFINE INC-AND-DOUBLE (Y) <DOUBLE <SET Y <+ 1 .Y>>>>
6834 <INC-AND-DOUBLE 1> -> <DOUBLE <SET Y <+ 1 1>>>
6839 But, when `DOUBLE` is applied to that `FORM`, the argument is
6842 <INC-AND-DOUBLE 1> -> <DOUBLE <SET Y <+ 1 1>>>
6843 -> <FORM + <SET Y <+ 1 .Y>> <SET Y <1 .Y>>>
6847 So, since the evaluation of `DOUBLE`'s argument has a side effect, you
6848 should ensure that the evaluation is done exactly once, say by `FORM`:
6850 <DEFMAC DOUBLE ('ANY)
6851 <FORM PROG ((X .ANY)) #DECL ((X) FIX) '<+ .X .X>>>
6853 As a bonus, the `DECL` can once more be used.
6855 This example is intended to show that writing good `MACRO`s is a
6856 little trickier than writing good `FUNCTION`s. But the effort may be
6857 worthwhile if the compiled program must be speedy.
6859 Chapter 18. Machine Words and Bits
6860 ==================================
6862 The Muddle facility for dealing with uninterpreted machine words and
6863 bits involves two data TYPEs: WORD and BITS. A WORD is simply an
6864 uninterpreted machine word, while a BITS is a "pointer" to a set of
6865 bits within a WORD. Operating on WORDs is usually done only when
6866 compiled programs are used (chapter 19).
6871 A `WORD` in Muddle is a PDP-10 machine word of 36 bits. A `WORD`
6872 always `PRINT`s in "\# format", and its contents are always printed in
6873 octal (hence preceded and followed by `*`). Examples:
6876 #WORD *000000000000*
6878 #WORD *2000* ;"one bit 1"$
6879 #WORD *000000002000*
6881 #WORD *525252525252* ;"every other bit 1"$
6882 #WORD *525252525252*
6884 `WORD` is its own `PRIMTYPE`; it is also the `PRIMTYPE` of `FIX`,
6885 `FLOAT`, `CHARACTER`, and any other `TYPE` which can fit its data into
6888 A `WORD` cannot be an argument to `+`, `-`, or indeed any `SUBR`s
6889 except for `CHTYPE`, `GETBITS`, `PUTBITS` and several bit-manipulating
6890 functions, all to be described below. Thus any arithmetic bit
6891 manipulation must be done by `CHTYPE`ing a `WORD` to `FIX`, doing the
6892 arithmetic, and then `CHTYPE`ing back to `WORD`. However, bit
6893 manipulation can be done without `CHTYPE`ing the thing to be played
6894 with to a `WORD`, so long as it is of `PRIMTYPE` `WORD`; the result of
6895 the manipulation will be of the same `TYPE` as the original object or
6896 can be `CHTYPE`d to it.
6901 An object of `TYPE` `BITS` is of `PRIMTYPE` `WORD`, and `PRINT`s just
6902 like a `WORD`. The internal form of a `BITS` is precisely that of a
6903 PDP-10 "byte pointer", which is, in fact, just what a `BITS` is.
6905 For purposes of explaining what a `BITS` is, assume that the bits in a
6906 `WORD` are numbered from **right** to **left**, with the rightmost bit
6907 numbered 0 and the leftmost numbered 35, as in
6911 (This is not the "standard" ordering: the "standard" one goes from
6914 A `BITS` is most conveniently created via the `SUBR` `BITS`:
6916 <BITS width:fix right-edge:fix>
6918 returns a `BITS` which "points to" a set of bits *width* wide, with
6919 rightmost bit *right-edge*. Both arguments must be of `TYPE` `FIX`,
6920 and the second is optional, 0 by default.
6922 Examples: the indicated application of `BITS` returns an object of
6923 `TYPE` `BITS` which points to the indicated set of bits in a `WORD`:
6926 --------------- ------------------------------------
6927 `<BITS 7>` 35 ... 7 **6 ... 0**
6928 `<BITS 4 18>` 35 ... 22 **21 20 19 18** 17 ... 0
6929 `<BITS 36>` ***35 ... 0***
6934 <GETBITS from:primtype-word bits>
6936 where *from* is an object of `PRIMTYPE` `WORD`, returns a **new**
6937 object whose `TYPE` is `WORD`. This object is constructed in the
6938 following way: the set of bits in *from* pointed to by *bits* is
6939 copied into the new object, right-adjusted, that is, lined up against
6940 the right end (bit number 0) of the new object. All those bits of the
6941 new object which are not copied are set to zero. In other words,
6942 `GETBITS` takes bits from an arbitrary place in *from* and puts them
6943 at the right of a new object. The *from* argument to `GETBITS` is not
6948 <GETBITS #WORD *777777777777* <BITS 3>>$
6949 #WORD *000000000007*
6950 <GETBITS *012345670123* <BITS 6 18>>$
6951 #WORD *000000000045*
6956 <PUTBITS to:primtype-word bits from:primtype-word>
6958 where *to* and *from* are of `PRIMTYPE` `WORD`, returns a **copy** of
6959 *to*, modified as follows: the set of bits in *to* which are pointed
6960 to by *bits* are replaced by the appropriate number of rightmost bits
6961 copied from *from* (optional, 0 by default). In other words: `PUTBITS`
6962 takes bits from the right of *from* and stuffs them into an arbitrary
6963 position in a copy of *to*. **None** of the arguments to `PUTBITS` is
6968 <PUTBITS #WORD *777777777777* <BITS 6 3>>$
6969 #WORD *777777777007*
6970 <PUTBITS #WORD *666777000111* <BITS 5 15> #WORD *123*>$
6971 #WORD *666776300111*
6972 <PUTBITS #WORD *765432107654* <BITS 18>>$
6973 #WORD *765432000000*
6975 18.5. Bitwise Boolean Operations
6976 --------------------------------
6978 Each of the `SUBR`s `ANDB`, `ORB`, `XORB`, and `EQVB` takes arguments
6979 of `PRIMTYPE` `WORD` and returns a `WORD` which is the bitwise Boolean
6980 "and", inclusive "or", exclusive "or", or "equivalence" (inverse of
6981 exclusive "or"), respectively, of its arguments. Each takes any number
6982 of arguments. If no argument is given, a `WORD` with all bits off
6983 (`ORB` and `XORB`) or on (`ANDB` and `EQVB`) is returned. If only one
6984 argument is given, it is returned unchanged but `CHTYPE`d to a `WORD`.
6985 If more than two arguments are given, the operator is applied to the
6986 first two, then applied to that result and the third, etc. Be sure not
6987 to confuse `AND` and `OR` with `ANDB` and `ORB`.
6989 18.6. Bitwise Shifting Operations
6990 ---------------------------------
6992 <LSH from:primtype-word amount:fix>
6994 returns a **new** `WORD` containing the bits in *from*, shifted the
6995 number of bits specified by *amount* (mod 256, says the hardware).
6996 Zero bits are brought in at the end being vacated; bits shifted out at
6997 the other end are lost. If *amount* is positive, shifting is to the
6998 left; if *amount* is negative, shifting is to the right. Examples:
7001 #WORD *000000001000*
7003 #WORD *000000000000*
7005 <ROT from:primtype-word amount:fix>
7007 returns a **new** `WORD` containing the bits from *from*, rotated the
7008 number of bits specified by *amount* (mod 256, says the hardware).
7009 Rotation is a cyclic bitwise shift where bits shifted out at one end
7010 are put back in at the other. If *amount* is positive, rotation is to
7011 the left; if *amount* is negative, rotation is to the right. Examples:
7014 #WORD *000000001000*
7016 #WORD *100000000000*
7018 Chapter 19. Compiled Programs
7019 =============================
7021 19.1. RSUBR (the TYPE)
7022 ----------------------
7024 `RSUBR`s ("relocatable subroutines") are machine-language programs
7025 written to run in the Muddle environment. They are usually produced by
7026 the Muddle assembler (often from output produced by the compiler)
7027 although this is not necessary. All `RSUBR`s have two components: the
7028 "reference vector" and the "code vector". In some cases the code
7029 vector is in pure storage. There is also a set of "fixups" associated
7030 with every `RSUBR`, although it may not be available in the running
7033 19.2. The Reference Vector
7034 --------------------------
7036 An `RSUBR` is basically a `VECTOR` that has been `CHTYPE`d to `TYPE`
7037 `RSUBR` via the `SUBR` `RSUBR` (see below). This ex-`VECTOR` is the
7038 reference vector. The first three elements of the reference vector
7039 have predefined meanings:
7041 - The first element is of `TYPE` `CODE` or `PCODE` and is the impure
7042 or pure code vector respectively.
7043 - The second element is an `ATOM` and specifies the name of the
7045 - The third element is of `TYPE` `DECL` and declares the
7046 type/structure of the `RSUBR`'s arguments and result.
7048 The rest of the elements of the reference vector are objects in
7049 garbage-collected storage that the `RSUBR` needs to reference and any
7050 impure slots that the `RSUBR` needs to use.
7052 When the `RSUBR` is running, one of the PDP-10 accumulators (with
7053 symbolic name `R`) is always pointing to the reference vector, to
7054 permit rapid access to the various elements.
7059 `RSUBR`s can call any `APPLICABLE` object, all in a uniform manner. In
7060 general, a call to an F/SUBR is linked up at assembly/compile time so
7061 that the calling instruction (UUO) points directly at the code in the
7062 interpreter for the F/SUBR. However, the locations of most other
7063 `APPLICABLE`s are not known at assembly/compile time. Therefore, the
7064 calling UUO is set up to point at a slot in the reference vector (by
7065 indexing off accumulator `R`). This slot initially contains the `ATOM`
7066 whose G/LVAL is the called object. The calling mechanism (UUO handler)
7067 causes control to be transferred to the called object and, depending
7068 on the state of the `RSUBR`-link flag, the `ATOM` will be replaced by
7069 its G/LVAL. (If the call is of the "quick" variety, the called `RSUBR`
7070 or `RSUBR-ENTRY` will be `CHTYPE`d to a `QUICK-RSUBR` or
7071 `QUICK-ENTRY`, respectively, before replacement.) Regardless of the
7072 `RSUBR`-link flag's state, calls to `FUNCTION`s are never permanently
7073 linked. A call to a non-Subroutine generates an extra `FRAME`, whose
7074 `FUNCT` is the dummy `ATOM` `CALLER`.
7076 `RSUBR`s are linked together for faster execution, but linking may not
7077 be desirable if the `RSUBR`s are being debugged, and various revisions
7078 are being re-loaded. A linked call will forever after go to the same
7079 code, regardless of the current G/LVAL of the called `ATOM`. Thus,
7080 while testing `RSUBR`s, you may want to disable linking, by calling
7081 the `RSUBR-LINK` `SUBR` with a `FALSE` argument. Calling it with a
7082 non-`FALSE` argument enables linking thereafter. It returns the
7083 previous state of the link flag, either `T` or `#FALSE ()`. Calling it
7084 with no argument returns the current state.
7086 19.4. Pure and Impure Code
7087 --------------------------
7089 The first element of an `RSUBR` is the code vector, of `TYPE` `CODE`
7090 or `PCODE`. `TYPE` `CODE` is of `PRIMTYPE` `UVECTOR`, and the `UTYPE`
7091 should be of `PRIMTYPE` `WORD`. The code vector is simply a block of
7092 words that are the instructions which comprise the `RSUBR`. Since the
7093 code vector is stored just like a standard `UVECTOR`, it will be moved
7094 around by the garbage collector. Therefore, all `RSUBR` code is
7095 required to be location-insensitive. The compiler guarantees the
7096 location-insensitivity of its output. The assembler helps to make the
7097 code location-insensitive by defining all labels as offsets relative
7098 to the beginning of the code vector and causing instructions that
7099 refer to labels to index automatically off the PDP-10 accumulator
7100 symbolically named `M`. `M`, like `R`, is set up by the UUO handler,
7101 but it points to the code vector instead of the reference vector. The
7102 code vector of an `RSUBR` can be frozen (using the `FREEZE` `SUBR`) to
7103 prevent it from moving during debugging by DDT in the superior
7104 operating-system process.
7106 If the first element of an `RSUBR` is of `TYPE` `PCODE` ("pure code"),
7107 the code vector of the `RSUBR` is pure and sharable. `TYPE` `PCODE` is
7108 of `PRIMTYPE` `WORD`. The left half of the word specifies an offset
7109 into an internal table of pure `RSUBR`s, and the right half specifies
7110 an offset into the block of code where this `RSUBR` starts. The
7111 `PCODE` prints out as:
7113 %<PCODE name:string offset:fix>
7115 where *name* names the entry in the user's pure-`RSUBR` table, and
7116 *offset* is the offset. (Obviously, `PCODE` is also the name of a
7117 `SUBR`, which generates a pure code vector.) Pure `RSUBR`s may also
7118 move around, but only by being included in Muddle's page map at
7119 different places. Once again `M` can be used exactly as before to do
7120 location-independent address referencing. Individual pure code vectors
7121 can be "unmapped" (marked as being not in primary storage but in their
7122 original pure-code disk files) if the space in storage allocated for
7123 pure code is exhausted. An unmapped `RSUBR` is mapped in again
7124 whenever needed. All pure `RSUBR`s are unmapped before a `SAVE` file
7125 is written, so that the code is not duplicated on disk. A purified
7126 `RSUBR` must use `RGLOC` ("relative GLOC") instead of `GLOC`. `RGLOC`
7127 produces objects of `TYPE` `LOCR` instead of `LOCD`.
7129 19.5. TYPE-C and TYPE-W
7130 =======================
7132 In order to handle user `NEWTYPE`s reasonably, the internal `TYPE`
7133 codes for them have to be able to be different from one Muddle run to
7134 another. Therefore, references to the `TYPE` codes must be in the
7135 reference vector rather than the code vector. To help handle this
7136 problem, two `TYPE`s exist, `TYPE-C` ("type code") and `TYPE-W` ("type
7137 word"), both of `PRIMTYPE` `WORD`. They print as:
7139 %<TYPE-C type primtype:atom>
7140 %<TYPE-W type primtype:atom>
7142 The `SUBR` `TYPE-C` produces an internal `TYPE` code for the *type*,
7143 and `TYPE-W` produces a prototype "`TYPE` word" (appendix 1) for an
7144 object of that `TYPE`. The *primtype* argument is optional, included
7145 only as a check against the call to `NEWTYPE`. `TYPE-W` can also take
7146 a third argument, of `PRIMTYPE` `WORD`, whose right half is included
7147 in the generated "`TYPE` word". If *type* is not a valid `TYPE`, a
7148 `NEWTYPE` is automatically done.
7150 To be complete, a similar `SUBR` and `TYPE` should be mentioned here.
7154 produces an internal "storage allocation code" (appendix 1) for the
7155 *type*. The value is of `TYPE` `PRIMTYPE-C`, `PRIMTYPE` `WORD`. In
7156 almost all cases the `SUBR` `TYPEPRIM` gives just as much information,
7157 except in the case of `TEMPLATE`s: all `TYPE`s of `TEMPLATE`s have the
7158 same `TYPEPRIM`, but they all have different `PRIMTYPE-C`s.
7160 19.6. RSUBR (the SUBR)
7161 ----------------------
7163 <RSUBR [code name decl ref ref ...]>
7165 `CHTYPE`s its argument to an `RSUBR`, after checking it for legality.
7166 `RSUBR` is rarely called other than in the Muddle Assembler (Lebling,
7167 1979). It can be used if changes must be made to an `RSUBR` that are
7168 prohibited by Muddle's built-in safety mechanisms. For example, if the
7169 `GVAL` of *name* is an `RSUBR`:
7171 <SET FIXIT <CHTYPE ,name VECTOR>>$
7174 ...(changes to .FIXIT)...
7176 <SETG name <RSUBR .FIXIT>>$
7182 `RSUBR`s can have multiple entry points. An `RSUBR-ENTRY` can be
7183 applied to arguments exactly like an `RSUBR`.
7185 <RSUBR-ENTRY [rsubr-or-atom name:atom decl] offset:fix>
7187 returns the `VECTOR` argument `CHTYPE`d to an `RSUBR-ENTRY` into the
7188 *rsubr* at the specified *offset*. If the `RSUBR-ENTRY` is to have a
7189 `DECL` (`RSUBR` style), it should come as shown.
7191 <ENTRY-LOC rsubr-entry>
7193 ("entry location") returns the *offset* into the `RSUBR` of this
7196 19.8. RSUBRs in Files
7197 ---------------------
7199 There are three kinds of files that can contain `RSUBR`s, identified
7200 by second names `BINARY`, `NBIN` and `FBIN`. There is nothing magic
7201 about these names, but they are used by convention.
7203 A `BINARY` file is a completely ASCII file containing complete impure
7204 `RSUBR`s in character representation. Even a code vector appears as
7205 `#CODE` followed by a `UVECTOR` of `PRIMTYPE` `WORD`s. `BINARY` files
7206 are generally slow to load, because of all the parsing that must be
7209 An `NBIN` file contains a mixture of ASCII characters and binary code.
7210 The start of a binary portion is signalled to `READ` by the character
7211 control-C, so naive readers of an `NBIN` file under ITS may
7212 incorrectly assume that it ends before any binary code appears. An
7213 `NBIN` file cannot be edited with a text editor. An `RSUBR` is written
7214 in `NBIN` format by being `PRINT`ed on a `"PRINTB"` `CHANNEL`. The
7215 `RSUBR`s in `NBIN` files are not purified either.
7217 An `FBIN` file is actually part of a triad of files. The `FBIN`
7218 file(s) itself is the impure part of a collection of purified
7219 `RSUBR`s. It is simply ASCII and can be edited at will. (Exception: in
7220 the ITS and Tops-20 versions, the first object in the file should not
7221 be removed or changed in any way, lest a "grim reaper" program for
7222 `FBIN` files think that the other files in the triad are obsolete and
7223 delete them.) The pure code itself resides (in the ITS and Tops-20
7224 versions) in a special large file that contains all currently-used
7225 pure code, or (in the Tenex version) in a file in a special disk
7226 directory with first name the same as the *name* argument to `PCODE`
7227 for the `RSUBR`. The pure-code file is page-mapped directly into
7228 Muddle storage in read-only mode. It can be unmapped when the pure
7229 storage must be reclaimed, and it can be mapped at a different storage
7230 address when pure storage must be compacted. There is also a "fixup"
7231 file (see below) or portion of a file associated with the `FBIN` to
7232 round out the triad.
7234 An initial Muddle can have pure `RSUBR`s in it that were "loaded"
7235 during the initialization procedure. The files are not page-mapped in
7236 until they are actually needed. The "loading" has other side effects,
7237 such as the creation of `OBLIST`s (chapter 15). Exactly what is
7238 pre-loaded is outside the scope of this document.
7243 The purpose of "fixups" is to correct references in the `RSUBR` to
7244 parts of the interpreter that change from one release of Muddle to the
7245 next. The reason the fixups contain a release number is so that they
7246 can be completely ignored when an `RSUBR` is loaded into the same
7247 release of Muddle as that from which it was last written out.
7249 There are three forms of fixups, corresponding to the three kinds of
7250 `RSUBR` files. ASCII `RSUBR`s, found in `BINARY` files, have ASCII
7251 fixups. The fixups are contained in a `LIST` that has the following
7255 name:atom value:fix (use:fix use:fix ...)
7256 name:atom value:fix (use:fix use:fix ...)
7259 The fixups in `NBIN` files and the fixup files associated with `FBIN`
7260 files are in a fast internal format that looks like a `UVECTOR` of
7263 Fixups are usually discarded after they are used during the loading
7264 procedure. However, if, while reading a `BINARY` or `NBIN` file the
7265 `ATOM` `KEEP-FIXUPS!-` has a non-`FALSE` `LVAL`, the fixups will be
7266 kept, via an association between the `RSUBR` and the `ATOM` `RSUBR`.
7267 It should be noted that, besides correcting the code, the fixups
7268 themselves are corrected when `KEEP-FIXUPS` is bound and true. Also,
7269 the assembler and compiler make the same association when they first
7270 create an `RSUBR`, so that it can be written out with its fixups.
7272 In the case of pure `RSUBR`s (`FBIN` files), things are a little
7273 different. If a pure-code file exists for this release of Muddle, it
7274 is used immediately, and the fixups are completely ignored. If a
7275 pure-code file for this release doesn't exist, the fixup file is used
7276 to create a new copy of the file from an old one, and also a new
7277 version of the fixup file is created to go with the new pure-code
7278 file. This all goes on automatically behind the user's back.
7280 Chapter 20. Coroutines
7281 ======================
7283 This chapter purports to explain the coroutine primitives of Muddle.
7284 It does make some attempt to explain coroutines as such, but only as
7285 required to specify the primitives. If you are unfamiliar with the
7286 basic concepts, confusion will probably reign.
7288 A coroutine in Muddle is implemented by an object of `TYPE` `PROCESS`.
7289 In this manual, this use of the word "process" is distinguished by a
7290 capitalization from its normal use of denoting an operating-system
7291 process (which various systems call a process, job, fork, task, etc.).
7293 Muddle's built-in coroutine primitives do not include a "time-sharing
7294 system". Only one `PROCESS` is ever running at a time, and control is
7295 passed back and forth between `PROCESS`es on a coroutine-like basis.
7296 The primitives are sufficient, however, to allow the writing of a
7297 "time-sharing system" **in Muddle**, with the additional use of the
7298 Muddle interrupt primitives. This has, in fact, been done.
7300 20.1. PROCESS (the TYPE)
7301 ------------------------
7303 A `PROCESS` is an object which contains the "current state" of a
7304 computation. This includes the `LVAL`s of `ATOM`s ("bindings"),
7305 "depth" of functional application, and "position" within the
7306 application of each applied function. Some of the things which are
7307 **not** part of any specific `PROCESS` are the `GVAL`s of `ATOM`s,
7308 associations (`ASOC`s), and the contents of `OBLIST`s. `GVAL`s (with
7309 `OBLIST`s) are a chief means of communication and sharing between
7310 `PROCESS`es (all `PROCESS`es can refer to the `SUBR` which is the
7311 `GVAL` of `+`, for instance.) Note that an `LVAL` in one `PROCESS`
7312 cannot easily be directly referenced from another `PROCESS`.
7314 A `PROCESS` `PRINT`s as `#PROCESS` *p*, where *p* is a `FIX` which
7315 uniquely identifies the `PROCESS`; *p* is the "`PROCESS` number" typed
7316 out by `LISTEN`. A `PROCESS` cannot be read in by `READ`.
7318 The term "run a `PROCESS`" will be used below to mean "perform some
7319 computation, using the `PROCESS` to record the intermediate state of
7322 N.B.: A `PROCESS` is a rather large object; creating one will often
7323 cause a garbage collection.
7325 20.2. STATE of a PROCESS
7326 ------------------------
7330 returns an `ATOM` (in the `ROOT` `OBLIST`) which indicates the "state"
7331 of the `PROCESS` *process*. The `ATOM`s which `STATE` can return, and
7332 their meanings, are as follows:
7334 - `RUNABLE` (sic) -- *process* has never ever been run.
7335 - `RUNNING` -- *process* is currently running, that is, it did the
7336 application of `STATE`.
7337 - `RESUMABLE` -- *process* has been run, is not currently running,
7339 - `DEAD` -- *process* has been run, but it can **not** run again; it
7342 In addition, an interrupt (chapter 21) can be enabled to detect the
7343 time at which a `PROCESS` becomes "blocked" (waiting for terminal
7344 input) or "unblocked" (terminal input arrived). (The `STATE` `BLOCKED`
7345 has not been implemented.)
7347 20.3. PROCESS (the SUBR)
7348 ------------------------
7350 <PROCESS starter:applicable>
7352 creates and returns a new `PROCESS` but does **not** run it; the
7353 `STATE` of the returned `PROCESS` is `RUNABLE` (sic).
7355 *starter* is something applicable to **one** argument, which must be
7356 evaluated. *starter* is used both in starting and "terminating" a
7357 `PROCESS`. In particular, if the *starter* of a `PROCESS` **ever**
7358 returns a value, that `PROCESS` becomes `DEAD`.
7363 The `SUBR` `RESUME` is used to cause a computation to start or to
7364 continue running in another `PROCESS`. An application of `RESUME`
7367 <RESUME retval:any process>
7369 where *retval* is the "returned value" (see below) of the `PROCESS`
7370 that does the `RESUME`, and *process* is the `PROCESS` to be started
7373 The *process* argument to `RESUME` is optional, by default the last
7374 `PROCESS`, if any, to `RESUME` the `PROCESS` in which this `RESUME` is
7375 applied. If and when the current `PROCESS` is later `RESUME`d by
7376 another `PROCESS`, that `RESUME`'s *retval* is returned as the value
7379 20.5. Switching PROCESSes
7380 -------------------------
7382 ### 20.5.1. Starting Up a New PROCESS
7384 Let us say that we are running in some `PROCESS`, and that this
7385 original `PROCESS` is the `GVAL` of `P0`. Somewhere, we have evaluated
7387 <SETG P1 <PROCESS ,STARTER>>
7389 where `,STARTER` is some appropriate function. Now, **in `,P0`** we
7394 and the following happens:
7396 1. **In `,P0`** the arguments of the `RESUME` are evaluated: that is,
7397 we get that `LVAL` of `A` which is current in `,P0` and the `GVAL`
7399 2. The `STATE` of `,P0` is changed to `RESUMABLE` and `,P0` is
7400 "frozen" right where it is, in the middle of the `RESUME`.
7401 3. The `STATE` of `,P1` is changed to `RUNNING`, and `,STARTER` is
7402 applied to `,P0`'s `LVAL` of `A` **in `,P1`**. `,P1` now continues
7403 on its way, evaluating the body of `,STARTER.`
7405 The `.A` in the `RESUME` could have been anything, of course. The
7406 important point is that, whatever it is, it is evaluated in `,P0`.
7408 What happens next depends, of course, on what `,STARTER` does.
7410 ### 20.5.2. Top-level Return
7412 Let us initially assume that `,STARTER` does nothing relating to
7413 `PROCESS`es, but instead simply returns a value -- say *starval*. What
7414 happens when `,STARTER` returns is this:
7416 1. The `STATE` of `,P1` is changed to `DEAD`. `,P1` can never again
7418 2. The last `PROCESS` to `RESUME` `,P1` is found, namely `,P0`, and
7419 its `STATE` is changed to `RUNNING`.
7420 3. *starval* is returned in `,P0` as the value of the original
7421 `RESUME`, and `,P0` continues where it left off.
7423 All in all, this simple case looks just like an elaborate version of
7424 applying `,STARTER` to `.A` in `,P0`.
7426 ### 20.5.3. Symmetric RESUMEing
7428 Now suppose that while still in `,P1`, the following is evaluated,
7429 either in `,STARTER` or in something called by `,STARTER`:
7433 This is what happens:
7435 1. The arguments of the `RESUME` are evaluated **in `,P1`**.
7436 2. The `STATE` of `,P1` is changed to `RESUMABLE`, and `,P1` is
7437 "frozen" right in the middle of the `RESUME`.
7438 3. The `STATE` of `,P0` is changed to `RUNNING`, and `,P1`'s `LVAL`
7439 of `BAR` is returned as the value of **`,P0'`s** original `RESUME`
7440 `,P0` then continues right where it left off.
7442 This is **the** interesting case, because `,P0` can now do **another**
7443 `RESUME` of `,P1`; this will "turn off" `,P0`, pass a value to `,P1`
7444 and "turn on" `,P1`. `,P1` can now again `RESUME` `,P0`. which can
7445 `RESUME` `,P1` back again, etc. **ad nauseam**, with everything done
7446 in a perfectly symmetric manner. This can obviously also be done with
7447 three or more `PROCESS`es in the same manner.
7449 Note how this differs from normal functional application: you cannot
7450 "return" from a function without destroying the state that function is
7451 in. The whole point of `PROCESS`es is that you can "return"
7452 (`RESUME`), remembering your state, and later continue where you left
7458 ;"Initially, we are in LISTEN in some PROCESS.
7460 #DECL ((A) (OR FIX FLOAT>)
7462 #DECL ((S) <OR FIX FLOAT>)
7463 <SET S <+ .S <RESUME "GOT 1">>>
7464 <SET S <+ .S <RESUME "GOT 2">>>
7465 <SET S <RESUME .S>>>>$
7467 ;"SUM3, used as the startup function of another PROCESS,
7468 gets RESUMEd with numbers. It returns the sum of the last
7469 three numbers it was given every third RESUME."
7470 <SETG SUMUP <PROCESS ,SUM3>>$
7471 ;"Now we start SUMUP and give SUM3 its three numbers."
7479 Just as a note, by taking advantage of Muddle's order of evaluation,
7480 SUM3 could be have been written as:
7484 #DECL ((A S0 <OR FIX FLOAT>)
7485 <SET S <RESUME <+ .S <RESUME "GOT 1"> <RESUME "GOT
7488 20.7. Other Coroutining Features
7489 --------------------------------
7491 ### 20.7.1. BREAK-SEQ
7493 <BREAK-SEQ any process>
7495 ("break evaluation sequence") returns *process*, which must be
7496 `RESUMABLE`, after having modified it so that when it is next
7497 `RESUME`d, it will **first** evaluate *any* and **then** do an
7498 absolutely normal `RESUME`; the value returned by any is thrown away,
7499 and the value given by the `RESUME` is used normally.
7501 If a `PROCESS` is `BREAK-SEQ`ed more than once between `RESUME`s,
7502 **all** of the *any*s `BREAK-SEQ`ed onto it will be remembered and
7503 evaluated when the `RESUME` is finally done. The *any*s will be
7504 evaluated in "last-in first-out" order. The `FRAME` generated by
7505 `EVAL`ing more than one *any* will have as its `FUNCT` the dummy
7510 When you initially start up Muddle, the `PROCESS` in which you are
7511 running is slightly "special" in these two ways:
7513 1. Any attempt to cause it become `DEAD` will be met with an error.
7514 2. `<MAIN>` always returns that `PROCESS`.
7516 The `PROCESS` number of `<MAIN>` is always `1`. The initial `GVAL` of
7517 `THIS-PROCESS` is what `MAIN` always returns, `#PROCESS 1`.
7523 returns the `PROCESS` in which it is evaluated. The `LVAL` of
7524 `THIS-PROCESS` in a `RUNABLE` (new) `PROCESS` is what `ME` always
7531 returns the `PROCESS` which last `RESUME`d *process*. If no `PROCESS`
7532 has ever `RESUME`d process, it returns `#FALSE ()`. *process* is
7533 optional, `<ME>` by default. Note that `<MAIN>` does not ever have any
7536 <PROG ((R <RESUMER>)) ;"not effective in <MAIN>"
7537 #DECL ((R) <OR PROCESS FALSE>)
7539 <==? <STATE .R> RESUMABLE>
7544 <SUICIDE retval process>
7546 acts just like `RESUME`, but clobbers the `PROCESS` (which cannot be
7547 `<MAIN>`) in which it is evaluated to the `STATE` `DEAD`.
7553 returns *process*, after putting it into "single-step mode".
7555 A `PROCESS` in single-step mode, whenever `RESUME`d, runs only until
7556 an application of `EVAL` in it begins or finishes. At that point in
7557 time, the `PROCESS` that did the `1STEP` is `RESUME`d, with a *retval*
7558 which is a `TUPLE`. If an application of `EVAL` just began, the
7559 `TUPLE` contains the `ATOM` `EVLIN` and the arguments to `EVAL`. If an
7560 application of `EVAL` just finished, the `TUPLE` contains the `ATOM`
7561 `EVLOUT` and the result of the evaluation.
7563 *process* will remain in single-step mode until `FREE-RUN` (below) is
7564 applied to it. Until then, it will stop before and after each `EVAL`
7565 in it. Exception: if it is `RESUME`d from an `EVLIN` break with a
7566 *retval* of `TYPE` `DISMISS` (`PRIMTYPE` `ATOM`), it will leave
7567 single-step mode only until the current call to EVAL is about to
7568 return. Thus lower-level `EVAL`s are skipped over without leaving the
7569 mode. The usefulness of this mode in debugging is obvious.
7571 ### 20.7.7. FREE-RUN
7575 takes its argument out of single-step mode. Only the `PROCESS` that
7576 put *process* into single-step mode can take it out of the mode; if
7577 another `PROCESS` tries, `FREE-RUN` returns a `FALSE`.
7579 20.8. Sneakiness with PROCESSes
7580 -------------------------------
7582 `FRAME`s, `ENVIRONMENT`s, `TAG`s, and `ACTIVATION`s are specific to
7583 the `PROCESS` which created them, and each "knows its own father".
7584 **Any** `SUBR` which takes these objects as arguments can take one
7585 which was generated by **any** `PROCESS`, no matter where the `SUBR`
7586 is really applied. This provides a rather sneaky means of crossing
7587 between `PROCESS`es. The various cases are as follows:
7589 `GO`, `RETURN`, `AGAIN`, and `ERRET`, given arguments which lie in
7590 another `PROCESS`, each effectively "restarts" the `PROCESS` of its
7591 argument and acts as if it were evaluated over there. If the `PROCESS`
7592 in which it was executed is later `RESUME`d, it **returns** a value
7595 `SET`, `UNASSIGN`, `BOUND?`, `ASSIGNED?`, `LVAL`, `VALUE`, and `LLOC`,
7596 given optional `ENVIRONMENT` arguments which lie in another `PROCESS`,
7597 will gleefully change, or return, the local values of `ATOM`s in the
7598 other `PROCESS`. The optional argument can equally well be a
7599 `PROCESS`, `FRAME`, or `ACTIVATION` in another `PROCESS`; in those
7600 cases, each uses the `ENVIRONMENT` which is current in the place
7603 `FRAME`, `ARGS`, and `FUNCT` will be glad to return the `FRAME`s,
7604 argument `TUPLE`s, and applied Subroutine names of another `PROCESS`.
7605 If one is given a `PROCESS` (including `<ME>`) as an argument instead
7606 of a `FRAME`, it returns all or the appropriate part of the topmost
7607 `FRAME` on that `PROCESS`'s control stack.
7609 If `EVAL` is applied in `PROCESS` `P1` with an `ENVIRONMENT` argument
7610 from a `PROCESS` `P2`, it will do the evaluation **in `P1`** but with
7611 `P2`'s `ENVIRONMENT` (!). That is, the other `PROCESS`'s `LVAL`s, etc.
7612 will be used, but (1) any **new** `FRAME`s needed in the course of the
7613 evaluation will be created in `P1`; and (2) **`P1`** will be `RUNNING`
7614 -- not `P2`. Note the following: if the `EVAL` in `P1` eventually
7615 causes a `RESUME` of `P2`, `P2` could functionally return to below the
7616 point where the `ENVIRONMENT` used in `P1` is defined; a `RESUME` of
7617 `P1` at this point would cause an `ERROR` due to an invalid
7618 `ENVIRONMENT`. (Once again, `LEGAL?` can be used to forestall this.)
7623 1. A `RESUMABLE` `PROCESS` can be used in place of an `ENVIRONMENT`
7624 in any application. The "current" `ENVIRONMENT` of the `PROCESS`
7625 is effectively used.
7626 2. `FRAME`s and `ENVIRONMENT`s can be `CHTYPE`d arbitrarily to one
7627 another, or an `ACTIVATION` can be `CHTYPE`d to either of them,
7628 and the result "works". Historically, these different `TYPE`s were
7629 first used with different `SUBR`s -- `FRAME` with `ERRET`,
7630 `ENVIRONMENT` with `LVAL`, `ACTIVATION` with `RETURN` -- hence the
7631 invention of different `TYPE`s with similar properties.
7632 3. Bugs in multi-`PROCESS` programs usually exhibit a degree of
7633 subtlety and nastiness otherwise unknown to the human mind. If
7634 when attempting to work with multiple processes you begin to feel
7635 that you are rapidly going insane, you are in good company.
7637 Chapter 21. Interrupts
7638 ======================
7640 The Muddle interrupt handling facilities provide the ability to say
7641 the following: whenever "this event" occurs, stop whatever is being
7642 done at the time and perform "this action"; when "this action" is
7643 finished, continue with whatever was originally being done. "This
7644 event" can be things like the typing of a character at a terminal, a
7645 time interval ending, a `PROCESS` becoming blocked, or a
7646 program-defined and -generated "event". "This action" is the
7647 application of a specified `APPLICABLE` object to arguments provided
7648 by the Muddle interrupt system. The sets of events and actions can be
7649 changed in extremely flexible ways, which accounts for both the
7650 variety of `SUBR`s and arguments, and the rich interweaving of the
7651 topics in this chapter. Interrupt handling is a kind of parallel
7652 processing: a program can be divided into a "main-level" part and one
7653 or more interrupt handlers that execute only when conditions are ripe.
7655 21.1. Definitions of Terms
7656 --------------------------
7658 An **interrupt** is not an object in Muddle, but rather a class of
7659 events, for example, "ticks" of a clock, garbage collections, the
7660 typing of a character at a terminal, etc.
7662 An interrupt is said to **occur** when one of the events in its class
7665 An **external** interrupt is one whose occurrences are signaled to
7666 Muddle by the operating system, for example, "ticks" of a clock. An
7667 **internal** interrupt is one whose occurrences are detected by Muddle
7668 itself, for example, garbage collections. Muddle can arrange for the
7669 operating system to not signal occurrences of an external interrupt to
7670 it; then, as far as Muddle is concerned, that interrupt does not
7673 Each interrupt has a **name** which is either a `STRING` (for example,
7674 `"GC"`, `"CHAR"`, `"WRITE"`) or an `ATOM` with that `PNAME` in a
7675 special `OBLIST`, named `INTERRUPTS!-`. (This `OBLIST` is returned by
7676 `<INTERRUPTS>`.) Certain names must always be further specified by a
7677 `CHANNEL` or a `LOCATIVE` to tell **which** interrupt by that name is
7680 When an interrupt occurs, the interpreter looks for an association on
7681 the interrupt's name. If there is an association, its `AVALUE` should
7682 be an `IHEADER`, which heads a list of actions to be performed. In
7683 each `IHEADER` is the name of the interrupt with which the `IHEADER`
7684 is or was associated.
7686 In each `IHEADER` is an element telling whether it is disabled. If an
7687 `IHEADER` is **disabled**, then none of its actions is performed. The
7688 opposite of disabled is **enabled**. It is sometimes useful to disable
7689 an `IHEADER` temporarily, but removing its association with the
7690 interrupt's name is better than long-term disabling. There are `SUBR`s
7691 for creating an `IHEADER`, associating it with an interrupt, and later
7692 removing the association.
7694 In each `IHEADER` is a **priority**, a `FIX` greater than `0` which
7695 specifies the interrupt's "importance". The processing of a
7696 higher-priority (larger-numbered) interrupt will supersede the
7697 processing of a lower-priority (smaller-numbered) interrupt until the
7698 high-priority interrupt has been handled.
7700 In each `IHEADER` is a (possibly empty) list of `HANDLER`s. (This list
7701 is not a Muddle `LIST`.) Each `HANDLER` corresponds to an action to
7702 perform. There are `SUBR`s for creating a `HANDLER`, adding it to an
7703 `IHEADER`'s list, and later removing it.
7705 In each `HANDLER` is a function that we will call a **handler** (in
7706 lower case), despite possible confusion, because that is really the
7707 best name for it. An **action** consists of applying a handler to
7708 arguments supplied by the interrupt system. The number and meaning of
7709 the arguments depend on the name of the interrupt. In each `HANDLER`
7710 is an element telling in which `PROCESS` the action should be
7716 <EVENT name priority which>
7718 creates and returns an enabled `IHEADER` with no `HANDLER`s. The
7719 *name* may be an `ATOM` in the `INTERRUPTS` `OBLIST` or a `STRING`; if
7720 it is a `STRING`, `EVENT` does a `LOOKUP` or `INSERT` in
7721 `<INTERRUPTS>`. If there already is an `IHEADER` associated with
7722 *name*, `EVENT` just returns it, ignoring the given *priority*.
7724 *which* must be given only for certain *name*s:
7726 - It must be a `CHANNEL` if and only if *name* is `"CHAR"` (or
7727 `CHAR!-INTERRUPTS`). In this case it is the input `CHANNEL` from
7728 the (pseudo-)terminal or Network socket whose received characters
7729 will cause the interrupt to occur, or the output `CHANNEL` to the
7730 pseudo-terminal or Network socket whose desired characters will
7731 cause the interrupt to occur. (See below. Pseudo-terminals are not
7732 available in the Tenex and Tops-20 versions.)
7733 - The argument must be a `LOCATIVE` if and only if *name* is
7734 `"READ"` (or `READ!-INTERRUPTS`) or `"WRITE"` (or
7735 `WRITE!-INTERRUPTS`). In this case it specifies an object to be
7736 "monitored" for usage by (interpreted) Muddle programs (section
7739 If the interrupt is external, Muddle arranges for the operating system
7740 to signal its occurrences.
7742 21.3. HANDLER (the SUBR)
7743 ------------------------
7745 <HANDLER iheader applicable process>
7747 creates a `HANDLER`, adds it to the front of *iheader*'s `HANDLER`
7748 list (first action to be performed), and returns it as a value.
7749 *applicable* may be any `APPLICABLE` object that takes the proper
7750 number of arguments. (None of the arguments can be `QUOTE`d; they must
7751 all be evaluated at call time.) *process* is the `PROCESS` in which
7752 the handler will be applied, by default whatever `PROCESS` was running
7753 when the interrupt occurred.
7755 The value returned by the handler is ignored, unless it is of `TYPE`
7756 `DISMISS` (`PRIMTYPE` `ATOM`), in which case none of the remaining
7757 actions in the list will be performed.
7759 The processing of an interrupt's actions can terminate prematurely if
7760 a handler calls the `SUBR` `DISMISS` (see below.)
7767 removes the association between *iheader* and the name of its
7768 interrupt, and then disables *iheader* and returns it. (An error
7769 occurs if there is no association.) If the interrupt is external,
7770 Muddle arranges for the operating system not to signal its
7775 finds the `IHEADER` associated with *name* and proceeds as above,
7776 returning the `IHEADER`. *which* must be given only for certain
7777 *names*, as for `EVENT`. Caution: if you `<OFF "CHAR" ,INCHAN>`,
7778 Muddle will become deaf.
7782 returns *handler* after removing it from its list of actions. There is
7783 no effect on any other `HANDLER`s in the list.
7785 Now that you know how to remove `IHEADER`s and `HANDLER`s from their
7786 normal places, you need to know how to put them back:
7790 If *iheader* was previously disabled or disassociated from its name,
7791 `EVENT` will associate and enable it.
7793 <HANDLER iheader handler>
7795 If *handler* was previously removed from its list, `HANDLER` will add
7796 it to the front of *iheader*'s list of actions. Note that *process*
7797 cannot be specified.
7799 21.5. IHEADER and HANDLER (the TYPEs)
7800 -------------------------------------
7802 Both these `TYPE`s are of `PRIMTYPE` `VECTOR`, but they do not `PRINT`
7803 that way, since they are self-referencing. Instead they `PRINT` as
7805 #type most-interesting-component
7807 The contents of `IHEADER`s and `HANDLER`s can be changed by `PUT`, and
7808 the new values will then determine the behavior of Muddle.
7810 Before describing the elements of these `TYPE`s in detail, here are a
7811 picture and a Pattern, both purporting to show how they look:
7813 #IHEADER [name:atom or which
7815 *-----------> #HANDLER [*-----------> #HANDLER [#HANDLER []
7816 priority] <-------------* +------*
7817 applicable | applicable
7818 process] <-------+ process]
7820 <IHEADER <OR ATOM CHANNEL LOCATIVE>
7821 <OR '#LOSE 0 '#LOSE -1>
7822 <HANDLER HANDLER <OR HANDLER IHEADER> APPLICABLE PROCESS>
7827 The elements of an `IHEADER` are as follows:
7829 1. name of interrupt (`ATOM`, or `CHANNEL` if the name is `"CHAR"`,
7830 or `LOCATIVE` if the name is `"READ"` or `"WRITE"`)
7831 2. non-zero if and only if disabled
7832 3. first `HANDLER`, if any, else a zero-length `HANDLER`
7835 If you lose track of an `IHEADER`, you can get it via the association:
7837 - For `"CHAR"` interrupts, `<GET channel INTERRUPT>` returns the
7838 `IHEADER` or `#FALSE ()` if there is no association;
7839 `<EVENT "CHAR" 0 channel>` returns the `IHEADER`, creating it if
7840 there is no association.
7841 - For `"READ"` interrupts, `<GET locative READ!-INTERRUPTS>` returns
7842 the `IHEADER` or `#FALSE ()` if there is no association;
7843 `<EVENT "READ" 0 locative>` returns the `IHEADER`, creating it if
7844 there is no association.
7845 - For `"WRITE"` interrupts, `<GET locative WRITE!-INTERRUPTS>`
7846 returns the `IHEADER` or `#FALSE ()` if there is no association:
7847 `<EVENT "WRITE" 0 locative>` returns the `IHEADER`, creating it if
7848 there is no association.
7849 - Otherwise, the `IHEADER` is `PUT` on the name `ATOM` with the
7850 indicator `INTERRUPT`. Thus, for example,
7851 `<GET CLOCK!-INTERRUPTS INTERRUPT>` returns the `IHEADER` for the
7852 clock interrupt or `#FALSE ()` if there is no association;
7853 `<EVENT "CLOCK" 0>` returns the `IHEADER`, creating it if there is
7858 A `HANDLER` specifies a **particular** action for a **particular**
7859 interrupt. The elements of a `HANDLER` are as follows:
7861 1. next `HANDLER` if any, else a zero-length `HANDLER`
7862 2. previous `HANDLER` or the `IHEADER` (Thus the `HANDLER`s of a
7863 given interrupt form a "doubly-linked list" chaining between each
7864 other and back to the `IHEADER`.)
7865 3. handler to be applied (anything but `APPLICABLE` that evaluates
7866 its arguments -- the application is done not by `APPLY` but by
7867 `RUNINT`, which can take a `PROCESS` argument: see next line)
7868 4. `PROCESS` in which the handler will be applied, or `#PROCESS 0`,
7869 meaning whatever `PROCESS` was running when the interrupt occurred
7870 (In the former case, `RUNINT` is applied to the handler and its
7871 arguments in the currently running `PROCESS`, which causes an
7872 `APPLY` in the `PROCESS` stored in the `HANDLER`, which `PROCESS`
7873 must be `RESUMABLE`. The running `PROCESS` becomes `RESUMABLE`,
7874 and the stored `PROCESS` becomes `RUNNING`, but no other `PROCESS`
7875 variables (for example `RESUMER`) are changed.)
7880 <ON name applicable priority:fix process which>
7884 <HANDLER <EVENT name priority which>
7887 `ON` is a combination of `EVENT` and `HANDLER`: it creates (or finds)
7888 the `IHEADER`, associates and enables it, adds a `HANDLER` to the
7889 front the list (first to be performed), and returns the `HANDLER`.
7893 is effectively `<PUT iheader 2 #LOSE -1>`. Actually the `TYPE` `LOSE`
7894 is unimportant, but the `-1` signifies that *iheader* is disabled.
7898 is effectively `<PUT iheader 2 #LOSE 0>`. Actually the `TYPE` `LOSE`
7899 is unimportant, but the `0` signfies that *iheader* is enabled.
7901 21.7. Priorities and Interrupt Levels
7902 -------------------------------------
7904 At any given time there is a defined **interrupt level**. This is a
7905 `FIX` which determines which interrupts can really "interrupt" -- that
7906 is, cause the current processing to be suspended while their wants are
7907 satisfied. Normal, non-interrupt programs operate at an interrupt
7908 level of 0 (zero.) An interrupt is processed at an interrupt level
7909 equal to the interrupt's priority.
7911 ### 21.7.1. Interrupt Processing
7913 Interrupts "actually" only occur at well-defined points in time:
7914 during a call to a Subroutine, or at critical places within
7915 Subroutines (for example, during each iteration of `MAPF` on a `LIST`,
7916 which may be circular), or while a `PROCESS` is `"BLOCKED"` (see
7917 below). No interrupts can occur during garbage collection.
7919 What actually happens when an enabled interrupt occurs is that the
7920 priority of the interrupt is compared with the current interrupt
7921 level, and the following is done:
7923 If the priority is **greater than** the current interrupt level, the
7924 current processing is "frozen in its tracks" and processing of the
7925 action(s) specified for that interrupt begins.
7927 If the priority is less than or equal to the current interrupt level,
7928 the interrupt occurrence is **queued** -- that is, the fact that it
7929 occurred is saved away for processing when the interrupt level becomes
7932 When the processing of an interrupt's actions is completed, Muddle
7933 usually (1) "acts as if" the previously-existing interrupt level is
7934 restored, and processing continues on what was left off (perhaps for
7935 no time duration); and (2) "acts as if" any queued interrupt
7936 occurrences actually occurred right then, in their original order of
7939 ### 21.7.2. INT-LEVEL
7941 The `SUBR` `INT-LEVEL` is used to examine and change the current
7942 interrupt level directly.
7946 simply returns the current interrupt level.
7950 changes the interrupt level to its argument and returns the
7951 **previously**-existing interrupt level.
7953 If `INT-LEVEL` lowers the priority of the interrupt level, it does not
7954 "really" return until all queued occurrences of interrupts of higher
7955 priority than the target priority have been processed.
7957 Setting the `INT-LEVEL` extremely high (for example,
7958 `<INT-LEVEL <CHTPE <MIN> FIX>>`) effectively disables all interrupts
7959 (but occurrences of enabled interrupts will still be queued).
7961 If `LISTEN` or `ERROR` is called when the `INT-LEVEL` is not zero,
7962 then the typeout will be
7964 LISTENING-AT-LEVEL I PROCESS p INT-LEVEL i
7968 `DISMISS` permits a handler to return an arbitrary value for an
7969 arbitrary `ACTIVATION` at an arbitrary interrupt level. The call is as
7972 <DISMISS value:any activation int-level:fix>
7974 where only the *value* is required. If *activation* is omitted, return
7975 is to the place interrupted from, and *value* is ignored. If
7976 *int-level* is omitted, the `INT-LEVEL` prior to the current interrupt
7979 21.8. Specific Interrupts
7980 -------------------------
7982 Descriptions of the characteristics of particular "built-in" Muddle
7983 interrupts follow. Each is named by its `STRING` name. Expect this
7984 list to be incomplete yesterday.
7986 `"CHAR"` is currently the most complex built-in interrupt, because it
7987 serves duty in several ways. These different ways will be described in
7988 several different sections. All ways are concerned with characters or
7989 machine words that arrive or depart at unpredictable times, because
7990 Muddle is communicating with a person or another processor. Each
7991 `"CHAR"` `IHEADER` has a `CHANNEL` for the element that names the
7992 interrupt, and the mode of the `CHANNEL` tells what kinds of `"CHAR"`
7993 interrupts occur to be handled through that `IHEADER`.
7995 1. If the `CHANNEL` is for `INPUT`, "CHAR" occurs every time an
7996 "interesting" character (see below) is received from the
7997 `CHANNEL`'s real terminal, or any character is received from the
7998 `CHANNEL`'s pseudo-terminal, or a character or word is received
7999 from the `CHANNEL`'s Network socket, or indeed (in the ITS
8000 version) the operating system generates an interrupt for any
8002 2. If the `CHANNEL` is for output to a pseudo-terminal or Network
8003 socket, `"CHAR"` occurs every time a character or word is wanted.
8004 3. If the `CHANNEL` is for output to a terminal, `"CHAR"` occurs
8005 every time a line-feed character is output or (in the ITS version)
8006 the operating system generates a screen-full interrupt for the
8009 ### 21.8.1. "CHAR" received
8011 A handler for an input `"CHAR"` interrupt on a real terminal must take
8012 two arguments: the `CHARACTER` which was typed, and the `CHANNEL` on
8015 In the ITS version, the "interesting" characters are those "enabled
8016 for interrupts" on a real terminal, namely <kbd>\^@</kbd> through
8017 <kbd>\^G</kbd>, <kbd>\^K</kbd> through <kbd>\^\_</kbd>, and
8018 <kbd>DEL</kbd> (that is, ASCII codes 0-7, 13-37, and 177 octal.)
8020 In the Tenex and Tops-20 versions, the operating system can be told
8021 which characters typed on a terminal should cause this interrupt to
8022 occur, by calling the `SUBR` `ACTIVATE-CHARS` with a `STRING` argument
8023 containing those characters (no more than six, all with ASCII codes
8024 less than 33 octal). If called with no argument, `ACTIVATE-CHARS`
8025 returns a `STRING` containing the characters that currently interrupt.
8026 Initially, only <kbd>\^G</kbd>, <kbd>\^S</kbd>, and <kbd>\^O</kbd>
8029 An initial Muddle already has `"CHAR"` enabled on `,INCHAN` with a
8030 priority 8 (eight), the `SUBR` `QUITTER` for a handler to run in
8031 `#PROCESS 0` (the running `PROCESS`); this is how <kbd>`^G`</kbd> and
8032 <kbd>`^S`</kbd> are processed. In addition, every time a new `CHANNEL`
8033 is `OPEN`ed in `"READ"` mode to a terminal, a similar `IHEADER` and
8034 `HANDLER` are associated with that new `CHANNEL` automatically. These
8035 automatically-generated `IHEADER`s and `HANDLER`s use the standard
8036 machinery, and they can be `DISABLE`d or `OFF`ed at will. **However**,
8037 the `IHEADER` for `,INCHAN` should not be `OFF`ed: Muddle knows that
8038 `$` is typed only by an interrupt!
8040 Example: the following causes the given message to be printed out
8041 whenever a <kbd>`^Y`</kbd> is typed on `.INCHAN`:
8043 <SET H <HANDLER <GET .INCHAN INTERRUPT>
8044 #FUNCTION ((CHAR CHAN)
8045 #DECL ((VALUE) ANY (CHAR) CHARACTER (CHAN) CHANNEL)
8046 <AND <==? .CHAR !\^Y>
8047 <PRINC " [Some of the best friends are ^Ys.] ">>)>>$
8048 #HANDLER #FUNCTION **CHAR CHAN) ...)
8049 <+ 2 ^Y [Some of my best friends are ^Ys.] 2>$
8052 #HANDLER #FUNCTION (...)
8054 Note that occurrences of `"CHAR"` do **not** wait for the `$` to be
8055 typed, and the interrupting character is omitted from the input
8058 A `"CHAR"` interrupt can also be associated with an input `CHANNEL`
8059 open to a Network socket (`"NET"` device). A handler gets applied to a
8060 `NETSTATE` array (which see) and the `CHANNEL`.
8062 In the ITS version, a `"CHAR"` interrupt can also be associated with
8063 an input `CHANNEL` open to a pseudo-terminal ("STY" device and
8064 friends). An interrupt occurs when a character is available for input.
8065 These interrupts are set up in exactly the same way as real-terminal
8066 interrupts, except that a handler gets applied to only **one**
8067 argument, the `CHANNEL`. Pseudo-terminal are not available in the
8068 Tenex and Tops-20 versions.
8070 For any other flavor of ITS channel interrupt, a handler gets applied
8071 to only **one** argument, the `CHANNEL`.
8073 ### 21.8.2. "CHAR" wanted
8075 A `"CHAR"` interrupt can be associated with an output `CHANNEL` open
8076 to a Network socket (`"NET"` device). A handlers gets applied to a
8077 `NETSTATE` array (which see) and the `CHANNEL`.
8079 In the ITS version, a `"CHAR"` interrupt can also be associated with
8080 an output `CHANNEL` open to a pseudo-terminal (`"STY"` device and
8081 friends). An interrupt occurs when the program at the other end needs
8082 a character (and the operating-system buffer is empty). A handler gets
8083 applied to one argument, the `CHANNEL`. Pseudo-terminals are not
8084 available in the Tenex and Tops-20 versions.
8086 ### 21.8.3. "CHAR" for new line
8088 A handler for an output `"CHAR"` interrupt on a real terminal must
8089 take **one or two** arguments (using `"OPTIONAL"` or `"TUPLE"`): if
8090 two arguments are supplied by the interrupt system, they are the line
8091 number (`FIX`) and the `CHANNEL`, respectively, and the interrupt is
8092 for a line-feed; if only one argument is supplied (only in the ITS
8093 version), it is the `CHANNEL`, and the interrupt is for a full
8094 terminal screen. Note: the supplied line number comes from the
8095 `CHANNEL`, and it may not be accurate if the program alters it in
8096 subtle ways, for example, via `IMAGE` calls or special control
8097 characters. (The program can compensate by putting the proper line
8098 number into the `CHANNEL`.)
8102 `"GC"` occurs just **after** every garbage collection. Enabling this
8103 interrupt is the only way a program can know that a garbage collection
8104 has occurred. A handler for `"GC"` takes three arguments. The first is
8105 a FLOAT indicating the number of seconds the garbage collection took.
8106 The second argument is a FIX indicating the cause of the garbage
8107 collection, as follows (chapter 22):
8109 0. Program called GC.
8110 1. Movable storage was exhausted.
8111 2. Control stack overflowed.
8112 3. Top-level LVALs overflowed.
8113 4. GVAL vector overflowed.
8114 5. TYPE vector overflowed.
8115 6. Immovable garbage-collected storage was exhausted.
8116 7. Internal stack overflowed.
8117 8. Both control and internal stacks overflowed (rare).
8118 9. Pure storage was exhausted.
8119 10. Second, exhaustive garbage collection occurred.
8121 The third argument is an ATOM indicating what initiated the garbage
8122 collection: `GC-READ`, `BLOAT`, `GROW`, `LIST`, `VECTOR`, `SET`,
8123 `SETG`, `FREEZE`, `GC`, `NEWTYPE`, `PURIFY`, `PURE-PAGE-LOADER` (pure
8124 storage was exhausted), or `INTERRUPT-HANDLER` (stack overflow,
8127 ### 21.8.5. "DIVERT-AGC"
8129 `"DIVERT-AGC"` ("Automatic Garbage Collection") occurs just **before**
8130 a deferrable garbage collection that is needed because of exhausted
8131 movable garbage-collected storage. Enabling this interrupt is the only
8132 way a program can know that a garbage collection is about to occur. A
8133 handler takes two arguments: A `FIX` telling the number of machine
8134 words needed and an `ATOM` telling what initiated the garbage
8135 collection (see above). If it wishes, a handler can try to prevent a
8136 garbage collection by calling `BLOAT` with the `FIX` argument. If the
8137 pending request for garbage-collected storage cannot then be
8138 satisfied, a garbage collection occurs anyway. `AGC-FLAG` is `SET` to
8139 `T` while the handler is running, so that new storage requests do not
8140 try to cause a garbage collection.
8144 `"CLOCK"`, when enabled, occurs every half second (the ITS
8145 "slow-clock" tick.) It is not available in the Tenex or Tops-20
8146 versions. It wants handlers which take no arguments. Example:
8148 <ON "CLOCK" <FUNCTION () <PRINC "TICK ">> 1>
8150 ### 21.8.7. "BLOCKED"
8152 `"BLOCKED"` occurs whenever **any** `PROCESS` (not only the `PROCESS`
8153 which may be in a `HANDLER`) starts waiting or terminal input: that
8154 is, an occurrence indicates that somewhere, somebody did a `READ`,
8155 `READCHR`, `NEXTCHR`, `TYI`, etc. to a console. The handler for a
8156 `"BLOCKED"` interrupt should take one argument, namely the `PROCESS`
8157 which started waiting (which will also be the `PROCESS` in which the
8158 handler runs, if no specific one is in the `HANDLER`).
8160 Example: the following will cause Muddle to acquire a `*` prompting
8163 <ON "BLOCKED" #FUNCTION ((IGNORE) <PRINC !\*>) 5>
8165 ### 21.8.8. "UNBLOCKED"
8167 `"UNBLOCKED"` occurs whenever a `$` (<kbd>`ESC`</kbd>) is typed on a
8168 terminal if a program was hanging and waiting for input, or when a TYI
8169 call (which see) is satisfied. A handler takes one argument: the
8170 `CHANNEL` via which the `$` or character is input.
8172 ### 21.8.9. "READ" and "WRITE"
8174 `"READ"` and `"WRITE"` are associated with read or write references to
8175 Muddle objects. These interrupts are often called "monitors", and
8176 enabling the interrupt is often called "monitoring" the associated
8177 object. A "read reference" to an `ATOM`'s local value includes
8178 applying `BOUND?` or `ASSIGNED?` to the `ATOM`; similarly for a global
8179 value and `GASSIGNED?`. If the `INT-LEVEL` is too high when `"READ"`
8180 or `"WRITE"` occurs, an error occurs, because occurrences of these
8181 interrupts cannot be queued.
8183 Monitors are set up with `EVENT` or `ON`, using a locative to the
8184 object being monitored as the extra *which* argument, just as a
8185 `CHANNEL` is given for `"CHAR"`. A handler for `"READ"` takes two
8186 arguments: the locative and the `FRAME` of the function application
8187 that make the reference. A handler for `"WRITE"` takes three
8188 arguments: the locative, the new value, and the `FRAME`. For example:
8194 <ON "WRITE" <FUNCTION (OBJ VAL FRM)
8195 #DECL ((VALUE VAL ANY (OBJ) LOCATIVE (FRM) FRAME)
8197 <PRINC "Program changed ">
8205 #HANDLER FUNCTION (...)
8209 Program changed #LOCL 2 to 20 via #FRAME PUT
8214 ### 21.8.10. "SYSDOWN"
8216 `"SYSDOWN"` occurs when a system-going-down or system-revived signal
8217 is received from ITS. It is not available in the Tenex or Tops-20
8218 versions. If no `IHEADER` is associated and enabled, a warning message
8219 is printed on the terminal. A handler takes one argument: a `FIX`
8220 giving the number of thirtieths of a second until the shutdown (-1 for
8223 ### 21.8.11. "ERROR"
8225 In an effort to simplify error handling by programs, Muddle has a
8226 facility allowing errors to be handled like interrupts. `SETG`ing
8227 `ERROR` to a user function is a distasteful method, not safe if any
8228 bugs are around. An `"ERROR"` interrupt wants a handler that takes any
8229 number of arguments, via `"TUPLE"`. When an error occurs, handlers are
8230 applied to the `FRAME` of the `ERROR` call and the `TUPLE` of `ERROR`
8231 arguments. If a given handler "takes care of the error", it can
8232 `ERRET` with a value from the `ERROR` `FRAME`, after having done
8233 `<INT-LEVEL 0>`. If no handler takes care of the error, it falls into
8236 If an error occurs at an `INT-LEVEL` greater than or equal to that of
8237 the `"ERROR"` interrupt, real `ERROR` will be called, because
8238 `"ERROR"`interrupts cannot be queued.
8242 `"IPC"` occurs when a message is received on the ITS IPC device
8243 (chapter 23). It is not available in the Tenex and Tops-20 versions.
8245 ### 21.8.13. "INFERIOR"
8247 `"INFERIOR"` occurs when an inferior ITS process interrupts the Muddle
8248 process. It is not available in the Tenex and Tops-20 versions. A
8249 handler takes one argument: A `FIX` between `0` and `7` inclusive,
8250 telling which inferior process is interrupting.
8252 ### 21.8.14. "RUNT and "REALT"
8254 These are not available in the Tenex and Tops-20 versions.
8256 `"RUNT"`, if enabled, occurs **once**, *N* seconds of Muddle running
8257 time (CPU time) after calling `<RUNTIMER N:fix-or-float>`, which
8258 returns its argument. A handler takes no arguments. If `RUNTIMER` is
8259 called with no argument, it returns a `FIX`, the number of run-time
8260 seconds left until the interrupt occurs, or `#FALSE ()` if the
8261 interrupt is not going to occur.
8263 `"REALT"`, if enabled, occurs **every** *N* seconds of real-world time
8264 after calling `<REALTIMER N:fix-or-float>`, which returns its
8265 argument. A handler takes no arguments. `<REALTIMER 0>` tells the
8266 operating system not to generate real-time interrupts. If `REALTIMER`
8267 is called with no argument, it returns a `FIX`, the number of
8268 real-time seconds given in the most recent call to `REALTIMER` with an
8269 argument, or `#FALSE ()` if `REALTIMER` has not been called.
8271 ### 21.8.15. "Dangerous" Interrupts
8273 `"MPV"` ("memory protection violation") occurs if Muddle tries to
8274 refer to a storage address not in its address space. `"PURE"` occurs
8275 if Muddle tries to alter read-only storage. `"ILOPR"` occurs if Muddle
8276 executes and illegal instruction ("operator"). `"PARITY"` occurs if
8277 the CPU detects a parity error in Muddle's address space. All of these
8278 require a handler that takes one argument: the address (`TYPE` `WORD`)
8279 following the instruction that was being executed at the time.
8281 `"IOC"` occurs if Muddle tries to deal illegally with an I/O channel.
8282 A handler must take two arguments: a three-element `FALSE` like one
8283 that `OPEN` might return, and the `CHANNEL` that got the error.
8285 Ideally these interrupts should never occur. In fact, in the Tenex and
8286 Tops-20 versions, these interrupts always go to the superior operating
8287 system process instead of to Muddle. In the ITS version, if and when a
8288 "dangerous" interrupt does occur:
8290 - If no `IHEADER` is associated with the interrupt, then the
8291 interrupt goes to the superior operating system process.
8292 - If an `IHEADER` is associated but disabled, the error
8293 `DANGEROUS-INTERRUPT-NOT-HANDLED` occurs (`FILE-SYSTEM-ERROR` for
8295 - If an `IHEADER` is associated and enabled, but the `INT-LEVEL` is
8296 too high, the error `ATTEMPT-TO-DEFER-UNDEFERABLE-INTERRUPT`
8299 21.9. User-Defined Interrupts
8300 -----------------------------
8302 If the interrupt name given to `EVENT` or `ON` is **not** one of the
8303 standard predefined interrupts of Muddle, they will gleefully create
8304 an `ATOM` in `<INTERRUPTS>` and an associated `IHEADER` anyway, making
8305 the assumption that you are setting up a "program-defined" interrupt.
8307 Program-defined interrupts are made to occur by applying the `SUBR`
8310 <INTERRUPT name arg1 ... argN>
8312 where *name* is a `STRING`, `ATOM` or `IHEADER`, and *arg1* through
8313 *argN* are the arguments wanted by the handlers for the interrupt.
8315 If the interrupt specified by `INTERRUPT` is enabled, `INTERRUPT`
8316 returns `T`; otherwise it returns `#FALSE ()`. All the usual priority
8317 and queueing rules hold, so that even if `INTERRUPT` returns `T`, it
8318 is possible that nothing "really happened" (yet).
8320 `INTERRUPT` can also be used to cause "artificial" occurrences of
8321 standard predefined Muddle interrupts.
8323 Making a program-defined interrupt occur is similar to calling a
8324 handler directly, but there are differences. The value returned by a
8325 handler is ignored, so side effects must be used in order to
8326 communicate information back to the caller, other than whether any
8327 handler ran or will run. One good use for a program-defined interrupt
8328 is to use the priority and queueing machinery of `INT-LEVEL` to
8329 control the execution of functions that must not run concurrently. For
8330 example, if a `"CHAR"` handler just deposits characters in a buffer,
8331 then a function to process the buffered characters should probably run
8332 at a higher priority level -- to prevent unpredictable changes to the
8333 buffer during the processing -- and it is natural to invoke the
8334 processing with `INTERRUPT`.
8336 In more exotic applications, `INTERRUPT` can signal a condition to be
8337 handled by an unknown number of independent and "nameless" functions.
8338 The functions are "nameless" because the caller doesn't know their
8339 name, only the name of the interrupt. This programming style is
8340 modular and event-driven, and it is one way of implementing
8341 "heuristic" algorithms. In addition, each `HANDLER` has a `PROCESS` in
8342 which to run its handler, and so the different handlers for a given
8343 condition can do their thing in different environments quite easily,
8344 with less explicit control than when using `RESUME`.
8346 21.10. Waiting for Interrupts
8347 -----------------------------
8353 hangs interruptibly, without consuming any CPU time, potentially
8354 forever. `HANG` is nice for a program that cannot do anything until an
8355 interrupt occurs. If the optional *pred* is given, it is evaluated
8356 every time an interrupt occurs and is dismissed back into the `HANG`;
8357 if the result of evaluation is not `FALSE`, `HANG` unhangs and returns
8358 it as a value. If *pred* is not given, there had better be a named
8359 `ACTIVATION` somewhere to which a handler can return.
8363 <SLEEP time:fix-or-float pred>
8365 suspends execution, interruptibly, without consuming any CPU time, for
8366 *time* seconds, where *time* is non-negative, and then returns `T`.
8367 *pred* is the same as for `HANG`.
8369 Chapter 22. Storage Management
8370 ==============================
8372 The reason this chapter comes so late in this document is that, except
8373 for special cases, Muddle programs have their storage needs handled
8374 automatically. There is usually no need even to consider storage
8375 management, except as it affects efficiency (chapter 24). This chapter
8376 gives some explanation of why this is so, and covers those special
8377 means by which a program can assume control of storage management.
8379 The Muddle address space is divided into five parts, which are usually
8382 1. movable garbage-collected space,
8383 2. immovable space (both garbage-collected and not),
8384 3. user pure/page space,
8385 4. pure-`RSUBR` mapping space, and
8386 5. internal storage.
8388 Internal storage occupies both the highest and lowest addresses in the
8389 address space, and its size never changes as Muddle executes. The
8390 other spaces can vary in size according to the needs of the executing
8391 program. Generally the interpreter allocates a contiguous set of
8392 addresses for each space, and each space gradually fills up as new
8393 objects are created and as disk files are mapped in. The action taken
8394 when space becomes full varies, as discussed below.
8396 22.1. Movable Garbage-collected Storage
8397 ---------------------------------------
8399 Most storage used explicitly by Muddle programs is obtained from a
8400 pool of free storage managed by a "garbage collector". Storage is
8401 obtained from this pool by the `SUBR`s which construct objects. When a
8402 `SUBR` finds that the pool of available storage is exhausted, it
8403 automatically calls the garbage collector.
8405 The garbage collector has two algorithms available to it: the
8406 "copying" algorithm, which is used by default, and the "mark-sweep"
8407 algorithm. Actually, one often speaks of two separate garbage
8408 collectors, the "copying" one and the "mark-sweep" one, because each
8409 is an independent module that is mapped in to the interpreter's
8410 internal storage from disk only during garbage collection. For
8411 simplicity, this document speaks of "the" garbage collector, which has
8414 The garbage collector examines the storage pool and **marks** all the
8415 objects there, separating them into two classes: those which cannot
8416 possibly be referenced by a program, and those which can. The
8417 "copying" algorithm then copies the latter into one compact section of
8418 the pool, and the remainder of the pool is made available for newly
8419 constructed objects. The "mark-sweep" algorithm, instead, puts all
8420 objects in the former class (garbage) into "free lists", where the
8421 object-construction `SUBR`s can find them and re-use their storage.
8423 If the request for more storage still cannot be satisfied from
8424 reclaimed storage, the garbage collector will attempt to obtain more
8425 total storage from the operating system under which Muddle runs.
8426 (Also, if there is a gross superfluity of storage space, the garbage
8427 collector will politely return some storage to the operating system.)
8428 Only when the total system resources are exhausted will you finally
8431 Thus, if you just "forget about" an object, that is, lose all possible
8432 means of referencing it, its storage is automatically reclaimed.
8433 "Object" in this context includes that stack-structured storage space
8434 used in `PROCESS`es for functional application.
8436 ### 22.1.1. Stacks and Other Internal Vectors
8438 Control stacks are used in Muddle to control the changes in
8439 environment caused by calling and binding. Each active `PROCESS` has
8440 its own control stack. On this stack are stored `LVAL`s for `ATOM`s;
8441 `PRIMTYPE` `TUPLE`s, which are otherwise like `VECTOR`s; `PRIMTYPE`
8442 `FRAME`s, which are generated by calling Subroutines; and
8443 `ACTIVATION`s, which are generated by calling `FUNCTION`s with named
8444 `ACTIVATION`s, `PROG`, and `REPEAT`. `TAG` and `LLOC` can make `TAG`s
8445 and `LOCD`s (respectively) that refer to a specific place on a
8446 specific control stack. (`LEGAL?` returns `T` if and only if the
8447 portion of the control stack in which its argument is found or to
8448 which its argument refers is still active, or if its argument doesn't
8449 care about the control stack. The garbage collector may change a
8450 non-`LEGAL?` object to `TYPE` `ILLEGAL` before reclaiming it.) As the
8451 word "stack" implies, things can be put on it and removed from it at
8452 only one end, called the top. It has a maximum size (or depth), and
8453 attempting to put too many things on it will cause overflow. A stack
8454 is stored like a `VECTOR`, and it must be `GROW`n if and when it
8457 A control stack is actually two stacks in one. One section is used for
8458 "top-level" `LVAL`s -- those `SET` while the `ATOM` is not bound by
8459 any active Function's argument `LIST` or Subroutine's `SPECIAL`
8460 binding -- and the other section is used for everything else. Either
8461 section can overflow, of course. The top-level-`LVAL` section is below
8462 the other one, so that a top-level `LVAL` will be found only if the
8463 `ATOM` is not currently bound elsewhere, namely in the other section.
8465 Muddle also has an internal stack, used for calling and temporary
8466 storage within the interpreter and compiled programs. It too is stored
8467 like a `VECTOR` and can overflow. There are other internal vectors
8468 that can overflow: the "global vector" holds pairs ("slots") of
8469 `ATOM`s and corresponding `GVAL`s ("globally bound" or `GBOUND?` means
8470 that the `ATOM` in question is in this vector, whether or not it
8471 currently has a global value), and the "`TYPE` vector" holds `TYPE`
8472 names (predefined and `NEWTYPE`s) and how they are to be treated.
8474 22.2. Immovable Storage
8475 -----------------------
8477 ### 22.2.1. Garbage-collected: FREEZE
8479 In very special circumstances, such as debugging `RSUBR`s, you may
8480 need to prevent an object from being moved by the garbage collector.
8481 `FREEZE` takes one argument, of `PRIMTYPE` `VECTOR`, `UVECTOR`,
8482 `STRING`, `BYTES` or `TUPLE`. It copies its argument into non-moving
8483 garbage-collected space. `FREEZE` returns the copy `CHTYPE`d to its
8484 `PRIMTYPE`, except in the case of a `TUPLE`, which is changed to a
8487 ### 22.2.2. Non-garbage-collected: STORAGE (the PRIMTYPE)
8489 An object of `PRIMTYPE` `STORAGE` is really a frozen `UVECTOR` whose
8490 `UTYPE` is of `PRIMTYPE` `WORD`, but it is always pointed to by
8491 something internal to Muddle and thus is never garbage-collectible.
8492 The use of `FREEZE` is always preferable, except when for historical
8493 reasons a `STORAGE` is necessary.
8498 User pure/page space serves two purposes. First, when a user program
8499 `PURIFY`s (see below) Muddle objects, they are copied into this space.
8500 Second, so-called hand-crafted `RSUBR`s (assembled but not compiled)
8501 can call on the interpreter to map pages of disk files into this space
8502 for arbitrary purposes.
8504 Pure-`RSUBR` mapping space is used by the interpreter to dynamically
8505 map pages of pure compiled programs into and out of the Muddle address
8506 space. Pure code can refer to impure storage through the "transfer
8507 vector", another internal vector. This space is the most vulnerable to
8508 being compressed in size by the long-term growth of other spaces.
8510 Internal storage has both pure and impure parts. The interpreter
8511 program itself is pure and sharable, while impure storage is used for
8512 internal pointers, counters, and flags, for example, pointers to the
8513 boundaries of other spaces. In the pure part of this space are most of
8514 the `ATOM`s in an initial Muddle, along with their `OBLIST` buckets
8515 (`LIST`s) and `GVAL` slots (a pure extension of the global vector),
8516 where possible. A `SET` or `SETG` of a pure `ATOM` automatically
8517 impurifies the `ATOM` and as much of its `OBLIST` bucket as needs to
8520 22.4. Garbage Collection: Details
8521 ---------------------------------
8523 When either of the garbage-collected spaces (movable or immovable)
8524 becomes full, Muddle goes through the following procedure:
8526 1. A `"DIVERT-AGC"` interrupt occurs if the garbage collection can be
8527 deferred temporarily by shifting boundaries between storage spaces
8528 slightly. The interrupt handler may postpone a garbage collection
8529 by moving boundaries itself with a call to `BLOAT` (below).
8530 2. The garbage collector begins execution. The "copying" algorithm
8531 creates an inferior operating-system process (named `AGC` in the
8532 ITS version) whose address space is used to hold the new copies of
8533 non-garbage objects. Muddle accesses the inferior's address space
8534 through two pages ("frontier" and "window") in its internal space
8535 that are shared with the inferior. If the garbage collection
8536 occurred because movable garbage-collected space was exhausted,
8537 then the "mark-sweep" algorithm might be used instead (see below)
8538 and no inferior process is created.
8539 3. The garbage collector marks and moves all objects that can
8540 possibly be referenced hereafter. It begins with the `<MAIN>`
8541 `PROCESS` and the currently running `PROCESS` `<ME>`, considered
8542 as vectors containing the control stacks, object pointers in live
8543 registers, etc. Every object in these "`PROCESS` vectors" is
8544 marked "accessible", and every element of these objects (bindings,
8545 etc.), and so on recursively. The "copying" algorithm moves
8546 objects into the inferior process's address space as it marks
8548 4. If the garbage collection is "exhaustive" -- which is possible
8549 only in the "copying" algorithm -- then both the chain of
8550 associations and top-level local/global bindings are examined
8551 thoroughly, which takes more time but is more likely to uncover
8552 garbage therein. In a normal garbage collection these constructs
8553 are not treated specially.
8554 5. Finally, the "mark-sweep" algorithm sweeps through the storage
8555 space, adding unmarked objects to the internal free lists for
8556 later re-use. The "copying" algorithm maps the inferior process's
8557 address space into Muddle's own, replacing old garbagey with the
8558 new compact storage, and the inferior process is destroyed.
8563 <GC min:fix exh?:false-or-any ms-freq:fix>
8565 causes the garbage collector to run and returns the total number of
8566 words of storage reclaimed. All of its arguments are optional: if they
8567 are not supplied, a call to GC simply causes a "copying" garbage
8570 If *min* is explicitly supplied as an argument, a garbage-collection
8571 parameter is changed permanently before the garbage collector runs.
8572 *min* is the smallest number of words of "free" (unclaimed, available
8573 for use) movable garbage-collected storage the garbage collector will
8574 be satisfied with having after it is done. Initially it is 8192 words.
8575 If the total amount of reclaimed storage is less than *min*, the
8576 garbage collector will ask the operating system for enough storage (in
8577 1024 word blocks) to make it up. N.B.: the system may be incivil
8578 enough not to grant the request; in that case, the garbage collector
8579 will be content with what it has, **unless** that is not enough to
8580 satisfy a **pending** request for storage. Then it will inform you
8581 that it is losing. A large *min* will result in fewer total garbage
8582 collections, but they will take longer since the total quantity of
8583 storage to be dealt with will generally be larger. Smaller *min*s
8584 result in shorter, more frequent garbage collections.
8589 `BLOAT` is used to cause a temporary expansion of the available
8590 storage space with or without changing the garbage-collection
8591 parameters. `BLOAT` is particularly useful for avoiding unnecessary
8592 garbage collections when loading a large file. It will cause (at most)
8593 one garbage collection, at the end of which the available storage will
8594 be at least the amount specified in the call to `BLOAT`. (Unless, of
8595 course, the operating system is cranky and will not provide the
8596 storage. Then you will get an error. `<ERRET 1>` from this error will
8597 cause the `BLOAT` to return `1`, which usually just causes you to lose
8598 at a later time -- unless the operating system feels nicer when the
8599 storage is absolutely necessary.)
8601 A call to BLOAT looks like this:
8603 <BLOAT fre stk lcl glb typ sto pstk
8604 min plcl pglb ptyp imp pur dpstk dstk>
8606 where all arguments on the first line above are `FIX`, optional (`0`
8607 by default), and indicate the following:
8609 - *fre*: number of words of free movable storage desired (for
8610 `LIST`s, `VECTOR`s, `ATOM`s, etc.)
8611 - *stk*: number of words of free control-stack space desired (for
8612 functional applications and binding of `ATOM`s)
8613 - *lcl*: number of new top-level `LVAL`s for which to leave space
8614 (`SET`s of `ATOM`s which are not currently bound)
8615 - *glb*: number of new `GVAL`s for which to leave space (in the
8617 - *typ*: number of new `TYPE` definitions for which to leave space
8618 (in the `TYPE` vector)
8619 - *sto*: number of words of immovable garbage-collected storage
8621 - *pstk*: number of words of free internal-stack space desired (for
8622 `READ`ing large `STRING`s, and calling routines within the
8623 interpreter and compiled programs)
8625 Arguments on the second line are also `FIX` and optional, but they set
8626 garbage-collection parameters permanently, as follows:
8628 - *min*: as for `GC`
8629 - *plcl*: number of slots for `LVAL`s added when the space for
8630 top-level `LVAL`s is expanded (initially 64)
8631 - *pglb*: number of slots for `GVAL`s added when the global vector
8632 is grown (initially 64)
8633 - *ptyp*: number of slots for `TYPE`s added when the `TYPE` vector
8634 is grown (initially 32)
8635 - *imp*: number of words of immovable garbage-collected storage
8636 added when it is expanded (initially 1024)
8637 - *pur*: number of words reserved for pure compiled programs, if
8638 possible (initially 0)
8639 - *dpstk*: most desirable size for the internal stack, to prevent
8640 repeated shrinking and `GROW`ing (initially 512)
8641 - *dstk*: most desirable size for the control stack (initially 4096)
8643 `BLOAT` returns the actual number of words of free movable
8644 garbage-collected storage available when it is done.
8649 `BLOAT-STAT` can be used with `BLOAT` to "tune" the garbage collector
8650 to particular program requirements.
8652 <BLOAT-STAT length-27:uvector>
8654 fills the *uvector* with information about the state of storage of
8655 Muddle. The argument should be a `UVECTOR` of length 27 and `UTYPE`
8656 `FIX`. If `BLOAT-STAT` does not get an argument, it will provide its
8657 own `UVECTOR`. The information returned is as follows: the first 8
8658 elements indicate the number of garbage collections that are
8659 attributable to certain causes, and the other 19 give information
8660 about certain areas of storage. In detail:
8662 1. number of garbage collections caused by exhaustion of movable
8663 garbage-collected storage
8664 2. ditto by overflow of control stack(s)
8665 3. ditto by overflow of top-level-`LVAL` section of control stack(s)
8666 4. ditto by overflow of global vector
8667 5. ditto by overflow of `TYPE` vector
8668 6. ditto by exhaustion of immovable garbage-collected storage
8669 7. ditto by overflow of internal stack
8670 8. ditto by overflow of both stacks at the same time (rare)
8672 9. number of words of movable storage
8673 10. number of words of movable storage used since last `BLOAT-STAT`
8674 11. maximum number of words of movable storage ever existing
8675 12. number of words of movable storage used since Muddle began running
8676 13. maximum size of control stack
8677 14. number of words on control stack in use
8678 15. maximum size of control stack(s) ever reached
8679 16. number of slots for top-level `LVAL`s
8680 17. number of top-level `LVAL`s existing
8681 18. number of slots for `GVAL`s in global vector
8682 19. number of `GVAL`s existing
8683 20. number of slots for `TYPE`s in `TYPE` vector
8684 21. number of `TYPE`s existing
8685 22. number of words of immovable garbage-collected storage
8686 23. number of words of immovable storage unused
8687 24. size of largest unused contiguous immovable-storage block
8688 25. number of words on internal stack
8689 26. number of words on internal stack in use
8690 27. maximum size of internal stack ever reached
8697 ("garbage-collector monitor") determines whether or not the
8698 interpreter will hereafter print information on the terminal when a
8699 garbage collection starts and finishes, according to whether or not
8700 its argument is true. It returns the previous state. Calling it with
8701 no argument returns the current state. The initial state is false.
8703 When typing is enabled, the "copying" garbage collector prints, when
8706 GIN reason subr-that-caused:atom
8708 and, when it finishes:
8712 The "mark-sweep" garbage collector prints `MSGIN` and `MSGOUT` instead
8713 of `GIN` and `GOUT`.
8715 22.9. Related Subroutines
8716 -------------------------
8718 Two `SUBR`s, described next, use only part of the garbage-collector
8719 algorithm, in order to find all pointers to an object. `GC-DUMP` and
8720 `GC-READ`, as their names imply, also use part in order to translate
8721 between Muddle objects and binary representation thereof.
8723 ### 22.9.1. SUBSTITUTE
8725 <SUBSTITUTE new:any old:any>
8727 returns *old*, after causing a miniature garbage collection to occur,
8728 during which **all** references to *old* are changed so as to refer to
8729 *new*. Neither argument can be of `PRIMTYPE` `STRING` or `BYTES` or
8730 `LOCD` or live on the control stack, unless both are of the same
8731 `PRIMTYPE`. One `TYPE` name cannot be substituted for another. One of
8732 the few legitimate uses for it is to substitute the "right" `ATOM` for
8733 the "wrong" one, after `OBLIST`s have been in the wrong state. This is
8734 more or less the way `ATOM`s are impurified. It is also useful for
8735 unlinking `RSUBR`s. `SUBSTITUTE` returns *old* as a favor: unless you
8736 hang onto *old* at that point, it will be garbage-collected.
8741 <PURIFY any-1 ... any-N>
8743 returns its last argument, after causing a miniature garbage
8744 collection that results in all the arguments becoming pure and
8745 sharable, and ignored afterward by the garbage collector. No argument
8746 can live on the control stack or be of `PRIMTYPE` `PROCESS` or `LOCD`
8747 or `ASOC`. Sharing between operating-system processes actually occurs
8748 after a `SAVE`, if and when the `SAVE` file is `RESTORE`d.
8750 Chapter 23. Muddle as a System Process
8751 ======================================
8753 This chapter treats Muddle considered as executing in an
8754 operating-system process, and interactions between Muddle and other
8755 operating-system processes. See also section 21.8.13.
8760 `TIME` takes any number of arguments, which are evaluated but ignored,
8761 and returns a `FLOAT` giving the number of seconds of CPU time the
8762 Muddle process has used so far. `TIME` is often used in machine-level
8763 debugging to examine the values of its arguments, by having Muddle's
8764 superior process (say, DDT) plant a breakpoint in the code for `TIME`.
8771 returns a `STRING` which is the "user name" of Muddle's process. This
8772 is the "uname" process-control variable in the ITS version and the
8773 logged-in directory in the Tenex and Tops-20 versions.
8777 returns a `STRING` which is the "intended user name" of Muddle's
8778 process. This is the "xuname" process-control variable in the ITS
8779 version and identical to `<UNAME>` in the Tenex and Tops-20 versions.
8783 returns a `STRING` which is the "job name" of Muddle's process. This
8784 is the "jname" process-control variable in the ITS version and the
8785 `SETNM` name in the Tenex and Tops-20 versions. The characters belong
8786 to the "sixbit" or "printing" subset of ASCII, namely those between
8787 `<ASCII *40*>` and `<ASCII *137*>` inclusive.
8791 returns a `STRING` which is the "intended job name" of Muddle's
8792 process. This is the "xjname" process-control variable in the ITS
8793 version and identical to `<JNAME>` in the Tenex and Tops-20 versions.
8800 attempts to log out the process in which it is executed. It will
8801 succeed only if the Muddle is the top-level process, that is, it is
8802 running disowned or as a daemon. If it succeeds, it of course never
8803 returns. If it does not, it returns `#FALSE ()`.
8807 causes Muddle to stop running, in an orderly manner. In the ITS
8808 version, it is equivalent to a `.LOGOUT 1` instruction. In the Tenex
8809 and Tops-20 versions, it is equivalent to a control-C signal, and
8810 control passes to the superior process.
8812 <VALRET string-or-fix>
8814 ("value return") seldom returns. It passes control back up the process
8815 tree to the superior of Muddle, passing its argument as a message to
8816 that superior. If it does return, the value is `#FALSE ()`. If the
8817 argument is a `STRING`, it is passed to the superior as a command to
8818 be executed, via `.VALUE` in the ITS version and `RSCAN` in the
8819 Tops-20 version. If the argument is a `FIX`, it is passed to the
8820 superior as the "effective address" of a `.BREAK 16`, instruction in
8821 the ITS version and ignored in other versions.
8823 23.4. Inter-process Communication
8824 ---------------------------------
8826 All of the `SUBR`s in this section are available only in the ITS
8829 The IPC ("inter-process communication") device is treated as an I/O
8830 device by ITS but not explicitly so by Muddle: that is, it is never
8831 `OPEN`ed. It allows Muddle to communicate with other ITS processes by
8832 means of sending and receiving messages. A process identifies itself
8833 as sender or recipient of a message with an ordered pair of "sixbit"
8834 `STRING`s, which are often but not always `<UNAME>` and `<JNAME>`. A
8835 message has a "body" and a "type".
8837 ### 23.4.1. SEND and SEND-WAIT
8839 <SEND othern1 othern2 body type mynamel myname2>
8841 <SEND-WAIT othern1 othern2 body type mynamel myname2>
8843 both send an IPC message to any job that is listening for it as
8844 *othern1* *othern2*. *body* must be either a `STRING`, or a `UVECTOR`
8845 of objects of `PRIMTYPE` `WORD`. *type* is an optional `FIX`, `0` by
8846 default, which is part of the information the other guy receives. The
8847 last two arguments are from whom the message is to be sent. These are
8848 optional, and `<UNAME>` and `<JNAME>` respectively are used by
8849 default. `SEND` returns a `FALSE` if no one is listening, while
8850 `SEND-WAIT` hangs until someone wants it. Both return `T` if someone
8851 accepts the message.
8853 ### 23.4.2. The "IPC" Interrupt
8855 When your Muddle process receives an IPC message, `"IPC"` occurs
8856 (chapter 21). A handler is called with either four or six arguments
8857 gleaned from the message. *body*, *type*, *othern1*, and *othern2* are
8858 supplied only if they are not this process's `<UNAME>` and `<JNAME>`.
8860 There is a built-in `HANDLER` for the `"IPC"` interrupt, with a
8861 handler named `IPC-HANDLER` and `0` in the `PROCESS` slot. The handler
8862 prints out on the terminal the *body*, whom it is from, the *type* if
8863 not `0`, and whom it is to if not `<UNAME>` `<JNAME>`. If the *type*
8864 is `1` and the *body* is a `STRING`, then, after the message
8865 information is printed out, the `STRING` is `PARSE`d and `EVAL`uated.
8869 `<IPC-OFF>` stops all listening on the IPC device.
8873 <IPC-ON myname1 myname2>
8875 causes listening on the IPC device as *myname1* *myname2*. If no
8876 arguments are provided, listening is on `<UNAME>` `<JNAME>`. When a
8877 message arrives, `"IPC"` occurs.
8879 Muddle is initially listening as `<UNAME>` `<JNAME>` with the built-in
8880 `HANDLER` set up on the `"IPC"` interrupt with a priority of `1`.
8884 <DEMSIG daemon:string>
8886 signals to ITS (directly, not via the IPC device) that the daemon
8887 named by its argument should run now. It returns `T` if the daemon
8888 exists, `#FALSE ()` otherwise.
8890 Chapter 24. Efficiency and Tastefulness
8891 =======================================
8896 Actually, you make Muddle programs efficient by thinking hard about
8897 what they really make the interpreter **do**, and making them do less.
8898 Some guidelines, in order of decreasing expense:
8900 1. Free storage is expensive.
8901 2. Calling functions is expensive.
8902 3. `PROG` and `REPEAT` are expensive, except when compiled.
8906 1. Unnecessary use of free storage (creating needless `LIST`s,
8907 `VECTOR`s, `UVECTOR`s, etc.) will cause the garbage collector to
8908 run more often. This is **expensive!** A fairly large Muddle (for
8909 example, 60,000 36-bit words) can take ten seconds of PDP-10 CPU
8910 time for a garbage collection. Be especially wary of constructions
8911 like `(0)`. Every time that is evaluated, it creates a new
8912 one-element `LIST`; it is too easy to write such things when they
8913 aren't really necessary. Unless you are doing `PUT`s or `PUTREST`s
8914 on it, use `'(0)` instead.
8915 2. Sad, but true. Also generally ignored. If you call a function only
8916 once, or if it is short (less than one line), you are much better
8917 off in speed if you substitute its body in by hand. On the other
8918 hand, you may be much worse off in modularity. There are
8919 techniques for combining several `FUNCTION`s into one `RSUBR`
8920 (with `RSUBR-ENTRY`s), either during or after compilation, and for
8921 changing `FUNCTION`s into `MACRO`s.
8922 3. `PROG` is almost never necessary, given (a) `"AUX"` in
8923 `FUNCTION`s; (b) the fact that `FUNCTION`s can contain any number
8924 of `FORM`s; (c) the fact that `COND` clauses can contain any
8925 number of `FORM`s; and (d) the fact that new variables can be
8926 generated and initialized by `REPEAT`. However, `PROG` may be
8927 useful when an error occurs, to establish bindings needed for
8928 cleaning things up or interacting with a human.
8930 The use of `PROG` may be sensible when the normal flow of control can
8931 be cut short by unusual conditions, so that the program wants to
8932 `RETURN` before reaching the end of `PROG`. Of course, nested `COND`s
8933 can accomplish the same end, but deep nesting may tend to make the
8934 program unreadable. For example:
8937 <OR <SET TEMP <OK-FOR-STEP-1?>>
8940 <OR <SET TEMP <OK-FOR-STEP-2?>>
8944 could instead be written
8946 <COND (<OK-FOR-STEP-1?>
8948 <COND (<OK-FOR-STEP-2?>
8951 By the way, `REPEAT` is faster than `GO` in a `PROG`. The `<GO x>`
8952 `FORM` has to be separately interpreted, right? In fact, if you
8953 organize things properly you **very** seldom need a `GO`; using `GO`
8954 is generally considered "bad style", but in some cases it's needed.
8957 In many cases, a `REPEAT` can be replaced with a `MAPF` or `MAPR`, or
8958 an `ILIST`, `IVECTOR`, etc. of the form
8960 <ILIST .N '<SET X <+ .X 1>>
8962 which generates an `N`-element `LIST` of successive numbers starting
8965 Whether a program is interpreted or compiled, the first two
8966 considerations mentioned above hold: garbage collection and function
8967 calling remain expensive. Garbage collection is, clearly, exactly the
8968 same. Function calling is relatively more expensive. However, the
8969 compiler careth not whether you use `REPEAT`, `GO`, `PROG`, `ILIST`,
8970 `MAPF`, or whatnot: it all gets compiled into practically the same
8971 thing. However, the `REPEAT` or `PROG` will be slower if it has an
8972 `ACTIVATION` that is `SPECIAL` or used other than by `RETURN` or
8977 There follows an example of a `FUNCTION` that does many things wrong.
8978 It is accompanied by commentary, and two better versions of the same
8979 thing. (This function actually occurred in practice. Needless to say,
8980 names are withheld to protect the guilty.)
8982 Blunt comment: this is terrible. Its purpose is to output the
8983 characters needed by a graphics terminal to draw lines connecting a
8984 set of points. The points are specified by two input lists: `X` values
8985 and `Y` values. The output channel is the third argument. The actual
8986 characters for each line are returned in a `LIST` by the function
8989 <DEFINE PLOTVDSK (X Y CHN "AUX" L LIST)
8990 <COND (<NOT <==? <SET L <LENGTH .X>><LENGTH .Y> >>
8991 <ERROR "LENGTHS NOT EQUAL">)>
8994 <SET LIST (!.LIST !<TRANS <.N .X> <.N .Y>>)>
8995 <COND (<G? <SET N <+ .N 1>> .L><RETURN .N>)> >
8996 <REPEAT ((N 1) (L1 <LENGTH .LIST>))
8997 <PRINC <ASCII <.N .LIST>> .CHN>
8998 <COND (<G? <SET N <+ .N 1>> .L1>
8999 <RETURN "DONE">)> >>
9003 1. `LIST` is only temporarily necessary. It is just created and then
9005 2. Worse, the construct `(!.LIST !<TRANS ...>)` **copies** the
9006 previous elements of `LIST` every time it is executed!
9007 3. Indexing down the elements of `LIST` as in `<.N .LIST>` takes a
9008 long time, if the `LIST` is long. `<3 ...>` or `<4 ...>` is not
9009 worth worrying about, but `<10 ...>` is, and `<100 ...>` takes
9010 quite a while. Even if the indexing were not phased out, the
9011 compiler would be happier with `<NTH .LIST .N>`.
9012 4. The variable `CHN` is unnecessary if `OUTCHAN` is bound to the
9014 5. It is tasteful to call `ERROR` in the same way that F/SUBRs do.
9015 This includes using an `ATOM` from the `ERRORS` `OBLIST` (if one
9016 is appropriate) to tell what is wrong, and it includes identifying
9021 <DEFINE PLOTVDSK (X Y OUTCHAN)
9022 #DECL ((OUTCHAN <SPECIAL CHANNEL>)
9023 <COND (<NOT <==? <LENGTH .X> <LENGTH .Y>>>
9024 <ERROR VECTOR-LENGTHS-DIFFER!-ERRORS PLOTVDSK>)>
9027 <COND (<EMPTY? .X> <RETURN "DONE">)>
9028 <REPEAT ((OL <TRANS <1 .X> <1 .Y>>))
9029 <PRINC <ASCII <1 .OL>>>
9030 <COND (<EMPTY? <SET OL <REST .OL>>>
9035 Of course, if you know how long is the `LIST` that `TRANS` returns,
9036 you can avoid using the inner `REPEAT` loop and have explicit `PRINC`s
9037 for each element. This can be done even better by using `MAPF`, as in
9038 the next version, which does exactly the same thing as the previous
9039 one, but uses `MAPF` to do the `REST`ing and the end conditional:
9041 <DEFINE PLOTVDSK (X Y OUTCHAN)
9042 #DECL ((OUTCHAN <SPECIAL CHANNEL>)
9043 <COND (<NOT <==? <LENGTH .X> <LENGTH .Y>>>
9044 <ERROR VECTOR-LENGTHS-DIFFER!-ERRORS PLOTVDSK>)>
9045 <PRINC <ASCII 29>> <MAPF <>
9047 <MAPF <> #FUNCTION ((T) <PRINC <ASCII .T>>) <TRANS
9053 24.2. Creating a LIST in Forward Order
9054 --------------------------------------
9056 If you must create the elements of a `LIST` in sequence from first to
9057 last, you can avoid copying earlier ones when adding a later one to
9058 the end. One way is to use `MAPF` or `MAPR` with a first argument of
9059 `,LIST`: the elements are put on the control stack rather than in free
9060 storage, until the final call to `LIST`. If you know how many elements
9061 there will be, you can put them on the control stack yourself, in a
9062 `TUPLE` built for that purpose. Another way is used when `REPEAT` is
9065 <REPEAT ((FIRST (T)) (LAST .FIRST) ...)
9066 #DECL ((VALUE FIRST LAST) LIST ...)
9068 <SET LAST <REST <PUTREST .LAST (.NEW)>>>
9070 <RETURN <REST .FIRST>>>
9073 Here, `.LAST` always points to the current last element of the `LIST`.
9074 Because of the order of evaluation, the `<SET LAST ...>` could also be
9075 written `<PUTREST .LAST (SET LAST (.NEW)>>`.
9077 24.3. Read-only Free Variables
9078 ------------------------------
9080 If a Function uses the value of a free variable
9081 (`<GVAL unmanifest:atom>` or `<LVAL special:atom>`) without changing
9082 it, the compiled version may be more efficient if the value is
9083 assigned to a dummy `UNSPECIAL` `ATOM` in the Function's `"AUX"` list.
9084 This is true because an `UNSPECIAL` `ATOM` gets compiled into a slot
9085 on the control stack, which is accessible very quickly. The tradeoff
9086 is probably worthwhile if a *special* is referenced more than once, or
9087 if an *unmanifest* is referenced more than twice. Example:
9089 <DEFINE MAP-LOOKUP (THINGS "AUX" (DB ,DATA-BASE))
9090 #DECL ((VALUE) VECTOR (THINGS DB) <UNSPECIAL <PRIMTYPE
9092 <MAPF ,VECTOR <FUNCTION (T) <MEMQ .T .DB>> .THINGS>>
9094 24.4. Global and Local Values
9095 -----------------------------
9097 In the interpreter the sequence `,X .X ,X .X` is slower than
9098 `,X ,X .X .X` because of interference between the `GVAL` and `LVAL`
9099 mechanisms (appendix 1). Thus it is not good to use both the `GVAL`
9100 and `LVAL` of the same `ATOM` frequently, unless references to the
9101 `LVAL` will be compiled away (made into control stack references).
9103 24.5. Making Offsets for Arrays
9104 -------------------------------
9106 It is often the case that you want to attach some meaning to each
9107 element of an array and access it independently of other elements.
9108 Firstly, it is a good idea to use names (`ATOM`s) rather than integers
9109 (`FIX`es or even `OFFSET`s) for offsets into the array, to make future
9110 changes easier. Secondly, it is a good idea to use the `GVAL`s of the
9111 name `ATOM`s to remember the actual `FIX`es, so that the `ATOM`s can
9112 be `MANIFEST` for the compiler's benefit. Thirdly, to establish the
9113 `GVAL`s, both the interpreter and the compiler will be happier with
9114 `<SETG name offset>` rather than
9115 `<DEFINE name ("TUPLE" T) <offset !.T>>`.
9120 There are several ways in Muddle to store a table, that is, a
9121 collection of (names and) values that will be searched.
9122 Unsurprisingly, choosing the best way is often dictated by the size of
9123 the table and/or the nature of the (names and) values.
9125 For a small table, the names and values can be put in (separate)
9126 structures -- the choice of `LIST` or array being determined by
9127 volatility and limitability -- which are searched using `MEMQ` or
9128 `MEMBER`. This method is very space-efficient. If the table gets
9129 larger, and if the elements are completely orderable, a (uniform)
9130 vector can be used, kept sorted, and searched with a binary search.
9132 For a large table, where reasonably efficient searches are required, a
9133 hashing scheme is probably best. Two methods are available in Muddle:
9134 associations and `OBLIST`s.
9136 In the first method, `PUTPROP` and `GETPROP` are used, which are very
9137 fast. The number of hashing buckets is fixed. Duplicates are
9138 eliminated by `==?` testing. If it is necessary to use `=?` testing,
9139 or to find all the entries in the table, you can duplicate the table
9140 in a `LIST` or array, to be used only for those purposes.
9142 In the second method, `INSERT` and `LOOKUP` on a specially-built
9143 `OBLIST` are used. (If the names are not `STRING`s, they can be
9144 converted to `STRING`s using `UNPARSE`, which takes a little time.)
9145 The number of hashing buckets can be chosen for best efficiency.
9146 Duplicates are eliminated by `=?` testing. MAPF/R can be used to find
9147 all the entries in the table.
9152 The beauty of deeply-nested control structures in a single `FUNCTION`
9153 is definitely in the eye of the beholder. (`PPRINT`, a preloaded
9154 `RSUBR`, finds them trying. However, the compiler often produces
9155 better code from them.) **If** you don't like excessive nesting, then
9159 <COND (<0? .X> ...) ...>
9163 <COND (<0? <SET X ...>> ...) ...>
9181 You can see the nature of the choices. Nesting is still and all better