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".