Sunday Sept 17,1978 FM+11H.57M.58S. LISP 1742 -HIC, JONL- Changes affecting all LISPs: [1] New autoloadable interpreter macros: backquote ("`") and LET. [2] New functions: NTH, NTHCDR, and LIST* [3] *THROW, *CATCH, CATCHALL, CATCH-BARRIER, and UNWIND-PROTECT. [4] SFA's (Software File Arrays) are implemented; see below. [5] DISPLACE now treats atomic arguments differently. [6] Minor changes to treatment of bound-variable lists. NIL is now ignored if used as a variable in bound-variable-lists. PROGV with more variables than values will make the extras "unbound" [7] OPEN now complains about illegal keywords [8] The null pname now prints as || [9] New features: SFA, EXPERIMENTAL Changes affecting ITS LISPs: [A] Planned move of autoloadable system files from COMMON; to LISP; [B] PURE now defaultly 1 [C] Arg to TTY-RETURN function is now meaningful Changes of interest to LISP internals hackers: [{] There is now a way, using some LAP or MIDAS code, to handle IOC errors Compiler changes: [i] The name "QCOMPLR" replaced by "COMPLR" [ii] COMPLR will now try to fully macro-expand any toplevel form. [iii] More on COMPLR command line switch settings, and on error messages. [iv] New names used for temporary files usage during compilation. You may find FOO _FASL_ and FOO _UNFA_ while producing FOO FASL. ---------------------------------------------------------------------- Changes affecting all LISPs: [1] New autoloadable interpreter macros: backquote ("`") and LET. The "backquote" macro and the LET macro will be autoloaded when used. The backquote macro allows generation of quoted structure with evaluated inserts, and is compatible with the LISP Machine's version. A "," within a backquote indicates evaluation of the next s-expression, and ",@" indicates not only evaluation but also that the resultant form is "spliced" into the surrounding list. For example: `(A B ,(+ 1 2)) reads in like (CONS 'A (CONS 'B (CONS (+ 1 2) 'NIL))) which when evaluated generates (A B 3) `(A B ,@(LIST 1 2)) read in like (CONS 'A (CONS 'B (APPEND (LIST 1 2) 'NIL))) which when evaluated generates (A B 1 2) One can imagine how especially helpful this will be in writing definitions of MACROs. The LET macro provides a convenient way to lambda-bind variables to values. Its usages is as follows: (LET ((var1 val1) (var2 val2) . . . (varn valn)) <form1> . . . <formn>) One may substitute merely "var" in place of "(var NIL)" For example: (LET ((A 1) (B 2) C) <forms>) Binds A to 1, B to 2, and C to NIL and then evaluates <forms>. An extension to the binding of one variable, is a "pattern" of variables, which are bound to the corresponding subparts of the "val"; e.g., (LET ( ((A . B) '(CONS 1 2)) ((C () D) (LIST 1 2 3))) <forms>) would bind A to "CONS", B to "(1 2)", C to "1", and D to "3". There is an attempt by the LET macro code to optimize the destructuring operations of CAR and CDR over the original value. [2] New functions: NTH, NTHCDR, and LIST* For cdr'ing down a list, using 0-origin indexing, use NTHCDR and NTH: (NTHCDR 0 x) is just x, and (NTHCDR n+1 x) is (CDR (NTHCDR n x)) (NTH n x) is the same as (CAR (NTHCDR n x)) For compound constructions using CONS, use LIST* as if it were an LSUBR version of CONS. For example, (LIST* <e0> <e1> . . . <en>) evals like (CONS <e0> (CONS <e1> . . . (CONS <en-1> <en>) . . . )) [3] *THROW, *CATCH, CATCHALL, CATCH-BARRIER, and UNWIND-PROTECT. For compatibility with the new format of CATCH and THROW in the LISP Machine, and in NIL, we are introducing *THROW and *CATCH. Please use these, and sometime in the future, CATCH and THROW in PDP10 MACLISP may be changed also. It is recommended that old code be converted to *CATCH and *THROW. (*CATCH <tag> e1 e2 ... e<n>) Forms e1 through e<n> are evaluated, returning the last as the value of the CATCH, unless a THROW (or *THROW) occurs whose tag matches the value of <tag> during the sub-evaluations; then the value of the catch is the value from the THROW. Note that <tag> is evaluated first. (*THROW <tag> <val>) Both <tag> and <val> are evaluated as in normal SUBR control, and a control-chain break-up is initiated, passing along both values; at some higher level, the break-up will be "caught". If the "catching" is by CATCH, then the value of <val> is passed to CATCH; if by CATCHALL, the both values are passed (q.v.). (CATCHALL <fun-2-args> e1 e2 ... e<n>) Has same semantics as CATCH, except that if **any** THROW occurs during the sub-evaluations, then the value of the CATCH is obtained by applying the value of <fun-2-args> to the throw value and throw tag. E.g. (CATCHALL '(LAMBDA (TG VAL) ;Note that for some tags, the throw is ; repeated, so that the CATCHALL acts as ; if it in fact ignores that THROW. (COND ((MEMQ TG '(TOPLEVEL BREAK)) (THROW VAL TG)) ((OR STOPP (EQ TG 'FOO)) (THROW VAL 'FOO)) (#T VAL))) (SETUP 25) (RUNLIKE ABAT)) (CATCH-BARRIER <tag-list> e1 e2 ... e<n>) Has the same syntax as CATCH, and more or less the same semantics, but if a thrown tag is not in the tag-list, then the THROW that threw it goes into an unseen-throw-tag error. The idea is that searching does not proceed back up the stack beyond this point; whereas if a THROW of a tag is not caught by a particular CATCH, then tag searching continues back up to the stack above the CATCH. (UNWIND-PROTECT <e> u1 u2 ... u<n>) The form <e> will be evaluated, but if the stack is "unwound" past the point of the UNWIND-PROTECT for ANY REASON, then the unwinder must cause the evaluation, in order, of u1 through u<n> in the environment that obtains by first unwinding to the stack point of the UNWIND-PROTECT; then the unwinding may continue. If <e> terminates normally, then the value will be that obtained from <e>, but the forms u1 through u<n> will be evaluated also. The intent is that the operation of <e> will do some things that need to be undone after sucessful completion, but which can not be undone merely by lambda-binding (eg, closing an opened file). Thus any aborting of the evaluation of <e> will not leave undesired states hanging around. Before the u<n>'s are run, NOINTERRUPT is set to T, so that asynchronous conditions cannot cause premature termination of the handlers. It is restored to its previous value upon completion of the u<n>'s. If a THROW is done, the user must reset NOINTERRUPT to the value he wishes it to be! The UNWIND-PROTECT frame is removed from the stack BEFORE the u<n>'s are run so that they may freely do THROWS (et al.). [4] SFA's (Software File Arrays) are implemented. As the documentation on these are lengthy and is subject to change, please check the file LISP;SFA > for the latest information. [5] DISPLACE now treats atomic arguments differently. Its definition is now like: (DEFUN DISPLACE (X Y) (AND (ATOM X) (ERROR '|-- not a list. (DISPLACE)| X)) (COND ((ATOM Y) (RPLACA X 'PROGN) (RPLACD X (NCONS Y))) (T (RPLACA X (CAR Y)) (RPLACD X (CDR Y))))) [6] Minor changes to treatment of bound-variable lists. NIL is now ignored if used as a variable in bound-variable-lists. PROGV with more variables than values will make the extras "unbound" For example ((LAMBDA (A () B) (LIST A B)) '1 '2 '3) ==> (1 3) All of "'1", "'2", "'3" are evaluated, but there is no binding to NIL. And (PROGV '(A B C) '(1 2) (LIST A C)) will generate an UNBND-VRBL error. A binding is actually provided for "C", but it is the internal "UNBOUND" marker which the interpreter catches. [7] OPEN now complains about illegal keywords in the modelist. Thus, (OPEN '(FOO BAR) '(OUT MUMBLE)) will cause an error, of the WRNG-TYPE-ARG variety. [8] The null pname now prints as ||, rather than not printing at all. GRINDEF has been changed to return an asterisk. [9] Two new possible feature names have been added. SFA is in the feature list if the LISP contains SFA's, and EXPERIMENTAL is in the feature list if the LISP is considered experimental. Changes affecting ITS LISPs: [A] There is a planned move of autoloadable system files from COMMON; to LISP;. Links will be left from COMMON; to LISP; for some period of time and then those links will be flushed. All new autoloadable files will go on LISP;. Please modify any programs that explicitly look on COMMON; for autoload files to look on LISP; [B] The value of PURE now defaults to 1. Since with the new UUOLINKS scheme, uuolinks segments are added dynamically, there is only a minor loss of core when PURE is non-NIL. It is still possible to set PURE to NIL before FASLOADING any files thus not using any extra core at all. [C] The arg given by LISP to the TTY-RETURN function is now meaningful. If it is the atom IN, then LISP is hanging in one of the canonical input waits. If the LISP was not in one of the input waits, then a value of NIL is supplied as the argument. Changes of interest to LISP internals hackers: [{] There is now a way, using some LAP or MIDAS code, to handle IOC errors. The user must put an instruction to XCT in IOCINS. If LISP does not know about the PC of the IOC error (it currently does not know about any IOC errors), then the user's instruction gets XCT'ed with the PC of the error in AC R, and the error code in AC D. The user's routine must not change any AC's other than R and D, though the stacks may be used. If the XCT'ed instruction skips, the right half of R must have been set up by the user to be the PC to dispatch to after leaving interrupt level, and the left half of R to 400000+<adr in which LISP should store the error code>. Compiler changes: [i] The name "QCOMPLR" replaced by "COMPLR" The names "QCOMPLR", "QC", "NCOMPLR" and "N" (as well as all the "old" versions like "OQCOMPL") have been superseded by "COMPLR" and "CL" (and "OCOMPL" and "OC"). There will no longer be provided support for oldio compilers. [ii] COMPLR will now try to fully macro-expand any toplevel form. Any form in a file that the compiler would normally just pass on through to the FASL file will now be fully macro expanded, in that a "pseudo-compilation" phase is done on it to expand macros. [iii] More on COMPLR command line switch settings, and on error messages. A review of the current command line switches, and their meanings: letter | variable name | meaning ---------------------------------------------------------------------- A ASSEMBLE Source is to be assembled only (generally used on a file of LAP code - see "K" switch below) C CLOSED Generic arithmetic functions are not open-coded D DISOWNED Run the compilation disowned E EXPR-HASH Output the EXPR-HASH properties in the FASL F FASL Compile and produce FASL file (normal mode) G GAG-ERRBREAKS Don't go into break loop when finding bad data K NOLAP Don't write a LAP file, or if "A" switch is on kill the "LAP" file (which may be source file) M MACROS Output MACRO defunitions to FASL file O ARRAYOPEN Open-code the array-accessing (no error checking in the open-coded variety) S SPECIALS Treat all variables as if declared SPECIAL T TTYNOTES Prompt notes and warning msgs go to TTY U UNFASLCOMMENTS A file (second name UNFASL) of messages will be produced; warnings, errors, comments, etc. W MUZZLED Don't inform about failure to open-code generic arithmetic functions X MAPEX Open-code all MAP type functions Z SYMBOLS Assembler symbol definitions go out to FASL + FIXSW All generic arithmetic is FIXNUM only. $ FLOSW All generic arithmetic is FLONUM only. In an initialized COMPLR, only the F, K, O, U, and V switches are "on", and all others are "off". They may be set by explicit lisp code in which a non-null value for the "variable-name" means "on", or by the appearance of the "switch-letter" between parens in the command line. More of an attempt is being made not to let error msgs clog up the TTY. Warning msgs will be printed on the TTY only if TTYNOTES is non-null, and error breaks on erroneous-looking input data will be run only if not disowned and GAG-ERRBREAKS is null (default state of each variable is null)