Tuesday Oct 28,1980 FM+4D.17H.18M.10S. LISP 2033 - Jonl - 1) Some new functions: ASH is a SUBR of two (fixnum) arguments, and is open-coded by the compiler. MAKE-LIST is a SUBR of one (fixnum) argument. LOAD-BYTE, DEPOSIT-BYTE, LDB, and DPB are now installed as SUBR's. LEXPR-FUNCALL, an LSUBR, follows the LISPMachine definition [more exposition below] 2) Many new autoloadable functions and macros: Macros from LISP:MLMAC -- HERALD SELECTQ IF DEFVAR CATCH THROW PSETQ SETQ-IF-UNBOUND MSETQ-CALL MSETQ-RETURN WITHOUT-INTERRUPTS WITH-INTERRUPTS WITHOUT-TTY-INTERRUPTS Macros from LISP:MACAID -- DEFSIMPLEMAC DEFBOTHMACRO Functions from LISP:MACAID -- +INTERNAL-DUP-P +INTERNAL-PERMUTIBLE-P |constant-p/|| |carcdrp/|| |no-funp/|| |side-effectsp/|| SYMBOLCONC FLATTEN-SYMS [more exposition below] 3) A user-extensible data-type scheme, using NIL's EXTEND data type, and with a hierarchical CLASS system. See also the documentation file ".INFO.;LISP EXTEND" on ITS systems and "LISP:EXTEND.DOC" on TOPS-10/20 systems. (The "USRHUNK" facility is required, and is take over by this CLASS system -- see 5 below). The autoloadable parts are: Functions from LISP:EXTEND -- PTR-TYPEP EQ-FOR-EQUAL? SI:DEFCLASS*-1 ADD-METHOD FIND-METHOD WHICH-OPERATIONS DESCRIBE Functions (with compile-time macro definitions) from LISP:EXTBAS ("basic") EXTENDP SI:MAKE-EXTEND SI:XREF SI:XSET SI:EXTEND-LENGTH SI:EXTEND (no macro definition) Macros from LISP:EXTMAC -- DEFCLASS* DEFMETHOD* MAKE-A-METHOD TYPECASEQ plus all accessor macros for CLASS objects Functions from LISP:SUBSEQ -- SUBSEQ REPLACE TO-LIST TO-VECTOR TO-STRING TO-BITS Functions and macros from LISP:EXTSTR ("structures") SI:DEFCLASS*-2 **SELF-EVAL** **CLASS-SELF-EVAL** [more exposition below] 4) Non-autoloadable Macros and Functions of general utility, from LISP:UMLMAC FIXNUMP FLONUMP LISTP EVENP LOGAND LOGIOR LOGXOR LOGNOT BIT-TEST BIT-SET BIT-CLEAR WHEN UNLESS DOLIST DOTIMES <= >= [more exposition below] 5) [delete -- discussed under item (1a) in note of Dec 04,1980] 6) A few piddling minor changes: 6a) There is now a PDP10 on the (STATUS FEATURES) list. 6b) Both " and # are set up in the initial environment as readmacros. # still requires the file LISP:SHARPM.FASL, but the default function for " will still create a pseudo-string (un-intern'd symbol) rather than requiring the full STRING support package; loading in the file LISP:STRING.FASL will do a SETSYNTAX on " to get real STRINGs. 6c) SETF is gone as an FSUBR -- the macro definitions is now autoloading. 6d) (STATUS NOINTERRUPT) returns the current state of the NOINTERRUPT flag. (SSTATUS NOINTERRUPT <foo>) is like (NOINTERRUPT <foo>), but slower. 7) New variable GRLINEL controls GRINDEF -- formerly the linewidth to be used while grinding was computed from (LINEL (OR (CAR OUTFILES) T)) As this is only a heuristic, the variable GRLINEL (default UNBOUND) will have priority if it is bound to a value. ____________________________________________________________________________ 1) Some new functions: ASH is a SUBR of two (fixnum) arguments, and is open-coded by the compiler. MAKE-LIST is a SUBR of one (fixnum) argument. LOAD-BYTE, DEPOSIT-BYTE, LDB, and DPB are now installed as SUBR's. LEXPR-FUNCALL, an LSUBR, follows the LISPMachine definition ASH is the "harmful operation" of arithmetic shifting. Many computer people have been led into thinking that ASH can substitute for multiply (or divide) when the multiplier (divisor) is a power of two; this is a "harmful thought", as the following analysis shows. (ASH <x> <n>) is like <x>*2^<n> for non-negative <n>, and almost like <x>/2^<-n> for negative <n> -- if <x> is also negative then it is like [<x>+2^<-n>-1]/2^<-n>. Many out-of-core functions need a function which generates a list of <n> nulls; hence: (MAKE-LIST 0) ==> () (MAKE-LIST <n>) ==> `( () ,.(make-list <n-1>)) LOAD-BYTE etc have been described in previous notes, but now LOAD-BYTE, DEPOSIT-BYTE, LDB, and DPB are now installed as SUBR's. The COMPLR open-codes some cases as BOOLE's [e.g., (LDB 0203 X) ==> (BOOLE 1 (LSH X -2) 7), and (DPB 0 #o0304 X) ==> (BOOLE 4 X #o170) ] From the LISPMachine manual, page 14, "LEXPR-FUNCALL is like a cross between APPLY and FUNCALL. (LEXPR-FUNCALL <f> <a1> <a1> ... <an> <list>) applies the function <f> to the arguments <a1> through <an> followed by the elements of <list>." 2) Many new autoloadable functions and macros: Macros from LISP:MLMAC -- HERALD SELECTQ IF DEFVAR PSETQ SETQ-IF-UNBOUND MSETQ-CALL MSETQ-RETURN WITHOUT-INTERRUPTS WITH-INTERRUPTS WITHOUT-TTY-INTERRUPTS Macros from LISP:MACAID -- DEFSIMPLEMAC DEFBOTHMACRO Functions from LISP:MACAID -- +INTERNAL-DUP-P +INTERNAL-PERMUTIBLE-P |constant-p/|| |carcdrp/|| |no-funp/|| |side-effectsp/|| SYMBOLCONC FLATTEN-SYMS The file MC:LSPSRC;MLMAC > contains some "MacLisp MACros" which are being standardized for compatibility with LISPM and NIL All of these have AUTOLOAD properties in the latest LISPs (version numbers 1997 and greater, except PSETQ, MSETQ-CALL, and MSETQ-RETURN aren't in 1997). They are generally quite simple, and the most detailed explanation of each one can be gained merely by inspecting the source file. HERALD is used to print a loading message, subject to (STATUS NOLDMSG), and to put a VERSION property on the name of the package being loaded. SELECTQ, DEFVAR, SETQ-IF-UNBOUND, and PSETQ ("parallel setq") are for compatibility with the LISPMachine; MSETQ-CALL, and MSETQ-RETURN are essentially the same as the LISPM's MULTIPLE-VALUE and MULTIPLE-VALUE-RETURN but are limited to 8 args). (IF <p> <e1> ... <en>) is like (COND (<p> <e1>) ('T ... <en>)) The "WITH...INTERRUPTS" series bind NOINTERRUPT to T, (), and TTY respectively, and currently achieve their effect by a kludge which is likely to be unworkable on TOPS-10 systems [an internal "write only" variable, +INTERNAL-WITHOUT-INTERRUPTS, is used to get a memory trap upon binding or unbinding]. Someday this kludgy hack may yield to a potentially slower, but more robust, implementation. The file MC:NILCOM;MACAID > contains some macros and functions which are of aid in writing lisp MACROS. All of these have AUTOLOAD properties in the latest LISPs (version numbers 1997 and greater). DEFSIMPLEMAC -- this is like DEFMACRO restricted to one "argument"; if need be, a LAMBDA is "wrapped" around the macro product to prevent duplication of code. E.g., let SQUARE be defined as (DEFSIMPLEMAC SQUARE (X) `(TIMES ,X ,X)) then (SQUARE (CAR X)) ==> (TIMES (CAR X) (CAR X)), but (SQUARE (HUNOZ X)) ==> ((LAMBDA (G0031) (TIMES G0031 G0031)) (HUNOZ X)) DEFBOTHMACRO -- used just like DEFMACRO, except that a SUBR definition is also produced by macroexpanding a prototypical call, and the macro definition is conditionalized upon loading into a COMPLR. E.g., (DEFBOTHMACRO MAKE-FROBL (X Y Z) `(LIST ,X (LIST ,Y ,Z))) produces the equivalent DEFMACRO defintion which is loaded only when (STATUS FEATURE COMPLR) is true, and also produces a DEFUN like (DEFUN MAKE-FROBL (X Y Z) (LIST X (LIST Y Z))). [Note: Both DEFSIMPLEMAC and DEFBOTHMACRO are limited approximations to what will someday be called "DEFOPEN" -- a complete solution to the DEFSUBST attempt of the LISPM. KMP and I (JONL) have some ideas about doing this, but currently do not have the time to finish it; when completed, this feature will also make available to the user certain very general code-analysis and code-expander modules.] DEFCOMPLRMAC -- used to make the COMPLR part of a DEFBOTHMACRO. Syntax is just like DEFMACRO, and a conditional test for (STATUS FEATURE COMPLR) is "wrapped" around the defmacro. SYMBOLCONC (x1 ... xn) Basically, a form of STRING-APPEND, but result is returned as an INTERNed symbol. FLATTEN-SYMS (x l) Appends a list of all symbols on "x" to the list "l". |constant-p/|| (x) Non-() only if x is a "constant" with respect to EVAL. |carcdrp/|| (x) Non-() iff x is a symbol for a "carcdr" function (like "CADAR"). |no-funp/|| (x) Non-() iff x is a form consisting only of variables, constants, and primitive data access operations (like "CDDAR" and "+" etc). |side-effectsp/|| (x) Non-() iff x is a form whose EVALuation has no ordinary lisp side-effects (like SETQ, RPLACA, or calling unknown functions) +INTERNAL-DUP-P (x) Non-() iff (1) the arg is a piece of lisp code representing a fairly trivial computation, (2) it may be eval'd multiple times without side-effects, and (3) it is "cheaper" to duplicate the permissibly duplicatable code rather than do a lambda-binding. +INTERNAL-PERMUTIBLE-P (l) Non-() iff the forms on the list 'l' may be EVAL'd in any order, and get the same results/effects. For example (5 (MUMBLE X)) is permutible, since nothing which happens inside MUMLBE can affect the value of 5; but (X (RPLACA Y)) is not permutible, since X may point to a list which is updated by the RPLACA. 3) A user-extensible data-type scheme, using NIL's EXTEND data type, and with a hierarchical CLASS system. See also the documentation file ".INFO.;LISP EXTEND" on ITS systems and "LISP:EXTEND.DOC" on TOPS-10/20 systems. (The "USRHUNK" facility is required, and is take over by this CLASS system -- see 5 below). The autoloadable parts are: Functions from LISP:EXTEND -- PTR-TYPEP EQ-FOR-EQUAL? SI:DEFCLASS*-1 ADD-METHOD FIND-METHOD WHICH-OPERATIONS DESCRIBE Functions (with compile-time macro definitions) from LISP:EXTBAS ("basic") EXTENDP SI:MAKE-EXTEND SI:XREF SI:XSET SI:EXTEND-LENGTH SI:EXTEND (no macro definition) Macros from LISP:EXTMAC -- DEFCLASS* DEFMETHOD* MAKE-A-METHOD TYPECASEQ plus all accessor macros for CLASS objects Functions from LISP:SUBSEQ -- SUBSEQ REPLACE TO-LIST TO-VECTOR TO-STRING TO-BITS Functions and macros from LISP:EXTSTR ("structures") SI:DEFCLASS*-2 **SELF-EVAL** **CLASS-SELF-EVAL** A CLASS system, and all the new NIL data types, have been embedded into MacLISP, primarily using certain hooks into MacLISP's hunks. See the documentation file LISP:EXTEND.DOC (or .INFO.;LISP EXTEND on ITS systems, or also LISP;EXTEND DOC). In general, see the file NIL;NEWFUN > on the MIT-MC machine for a description of "new" functions added to NIL (acronymic for "NewImplementationofLisp", or if you like "NilIsLisp"). All of the LISPM string functions mentioned on pages 79.-83. of the manual are implemented, except NSUBSTRING. Also, many more functions are available, including those supporting a new primitive data type called CHARACTER, and for which the user is directed to the first page of the source file LISP:STRING.LSP (or on ITS systems, NILCOM;STRING >). For VECTOR's, whose support is in the file LISP:VECTOR, the functions available are VECTORP, VECTOR-LENGTH, SET-VECTOR-LENGTH (downwards only), VREF, VSET, MAKE-VECTOR and VECTOR. (MAKE-VECTOR <n>) makes vector full of nulls of size <n>; (VECTOR e0 e1 ... en) makes a vector of size n+1, with components e0 e1 ... en, and (VREF <x> i) on such a vector would get the i'th zero-origined component; (VSET <x> i <val>) would set it to the value <val>. For BITS's (bit strings, or sequences of 0's and 1's), the functions, completely analogous with VECTORs, are BITSP, BITS-LENGTH, SET-BITS-LENGTH (downwards only), BIT, RPLACBIT, and MAKE-BITS. In addition, there are NIBBLE and SET-NIBBLE: (NIBBLE <bs> <i> <n>) gets <n> bits out of the bitstring <bs>, beginning at index <i>, and makes them into a FIXNUM with bit <i> being numerically the least significant. From the file LISP:SUBSEQ are several generic functions; (SUBSEQ <x> <i> <n>) constructs a new sequence of the same type as <x>, beginning with element <i> for a total new length of <n>; the second are third arguments are optional, with reasonable defaults. Thus, for example, (SUBSEQ "abcdefg" 2) would give out "cdefg". The functions TO-xxx are like SUBSEQ, except that they force the type of sequence output to be "xxx"; e.g. (TO-BITS '(1 0 1 1 0 0 1)) gives out #B"1011001", and (TO-VECTOR "AbC") gives #(~A ~/b ~C). REPLACE is for destructively clobbering a subpart of one sequence with that of another: (REPLACE <x> <y> <ix> <iy> <n>) starts at index <ix> of the sequence <x> and replaces it with elements of the sequence <y> beginning from <iy>, for a total of <n> elements; the third, fourth, and fifth arguments are optional, with reasonable defaults. 4) Non-autoloadable Macros and Functions of general utility, from LISP:UMLMAC FIXNUMP FLONUMP LISTP EVENP LOGAND LOGIOR LOGXOR LOGNOT BIT-TEST BIT-SET BIT-CLEAR WHEN UNLESS DOLIST DOTIMES <= >= The definitions for most of these macros should be obvious, but a few need some more explanation: FIXNUMP is *not* the same as FIXP (which admits bignums); both FIXNUMP and FLONUMP merely check the TYPEP of their arg. LISTP admits the nullist as well as cons cells. EVENP is just not ODDP; "<=" is just "not >", but calls with 2 or 3 arguments are permitted. LOGxxx are the bitwise boolean operators defined on FIXNUMs, and may be given arbitrarily many arguments (except LOGNOT) BIT-xxx takes exactly two arguments; BIT-TEST is "true" if and only if the LOGAND is non-zero; BIT-SET is just LOGIOR; and BIT-CLEAR is non-commutative for (BIT-CLEAR <x> <y>) acts like (LOGAND (LOGNOT <x>) <y>). (WHEN p e1 e2 ... en) is like (COND (p e1 e2 ... en)) (UNLESS p e1 e2 ... en) is like (COND ((NOT p) e1 e2 ... en)) (DOTIMES (i n) ...<body>...) expands into a DO loop which "does" the body n times, with "i" set to the loop counter each time (DOLIST (x y) ...<body>...) is much like (PROGN (MAPC '(LAMBDA (x) ...<body>...) y) ()) (DOLIST (x y i) ...<body>...) is similar, but "i" is set to a counter which is incremented each time down the list "y".