Saturday  Jan 27,1979   LQ+7D.1H.40M.31S.   LISP 1785 / COMPLR 867   -JONL-


1) EVAL-WHEN  - -  a new fsubr, like DECLARE but much more general
2) DEFUN permits LISP-Machine like syntax, and LET-destructuring of arguments.
3) New AUTOLOADable MACROs:  LET, LET*, DESETQ;  and DEFMACRO, MACRO, DEFUN&
   Functions MACROEXPAND and MACROEXPAND-1, defined as on LISPM, are available
4) Better error checking in *RSET mode for functions that cdr down lists:
   LAST now gets the last node of a non-atomic s-expression, or () for ().
5) "MACLISP" is now on the feature list, to help distinguish from LISPM.
6) COMPLR  has some new switches and global variables - EXPAND-OUT-MACROS etc.
7) SUSPEND - review of meanings of arguments
8) Under the ITS operating system, a JCL line with only a <space> means don't 
   use any INIT file, even if the connected directory has one.  This may
   be extended to the TOPS versions also.

____________________________________________________________________________

1) EVAL-WHEN  - -  a new fsubr, like DECLARE but much more general
	(EVAL-WHEN (<id1> <id2> ... <idn>) <foo1> <foo2> . . . <foon>)
   will cause the evaluation of the various <fooi> only if the "evaluator"
   matches one of the indicators in the first list; these indicators <idi>
   may be among EVAL, COMPILE, or LOAD, which respectively trigger 
	EVAL 	  -  a normal, read-eval-print loop
	COMPILE	  -  the "maklap" processor, which compiles files
	LOAD 	  -  "fasload" (which only processes compiler output)
   (EVAL-WHEN (COMPILE)  (SAY THIS))  is entirely equivalent to
	(DECLARE (SAY THIS))
   (EVAL-WHEN (EVAL LOAD) (RUN THAT)) is generally equivalent to
	(RUN THAT)
   (EVAL-WHEN (LOAD) (PRINT '|Loading Compiled version of Foo|))
	will cause the print request to appear only in the compiled FASL
	file, and be run at load time. (or LAP file if you don't assemble).
   (EVAL-WHEN (EVAL COMPILE LOAD) (SETSYNTAX '/% 'MACRO 'FUNNY-FUN))
	causes evaluation in all environments, which is often what one wants
	with macro characters.

2) DEFUN permits LISP-Machine like syntax, and LET-destructuring of arguments.
   DEFUN automatically becomes DEFUN& if "&" keywords occur in the dummy
   argument list, or any dummy argument is not a symbol;  see 3b below.

3) New AUTOLOADable MACROs:  LET, LET*, DESETQ;  and DEFMACRO, MACRO, DEFUN&
   Functions MACROEXPAND and MACROEXPAND-1, defined as on LISPM, are available
   from the file supporting DEFUN&, but they do not have autoload properties.
      LET, LET*, and DESETQ   are on the same file  LISP;LET FASL
      DEFMACRO, MACRO, and DEFUN&  are on the file  LISP;DEFMAC FASL
   In the BNF descriptions below, "{...|...}" denotes precisely one of
   the alternatives between the brackets and separated by vertical-bars;
   "{...}*" means zero or more occurances of the alternatives, "{...}+"
   means one or more occurances.
   3a) LET, LET*, and DESETQ   
	Following the many user definitions of a macro LET, we now
	have an autoload property for LET, and a definitions of it
	which is fairly intuitive:
	   (LET ((A <e1>) (B <E2>) ... (C <en>))
		<computate>)
	macro-expands into
	   ((LAMBDA (A B ... C)  <computate> )
		<e1> <e2> ... <en>)
	In certain arcane instances, one wants a sequential binding, rather
	than the parallel binding that occurs for a multiple-variable LAMBDA;
	thus, LET* may be used:
	   (LET* ((A <e1>) (B <E2>) ... (C <en>))
		 <computate>)
	macro-expands into
	   ((LAMBDA (A)
		    ((LAMBDA (B)
			     ... 
				((LAMBDA (C)  
					 <computate> ) 
				    <en>)
				... )
			 <e2>)
		<en>)
	In all other respect, however, LET* is similar to LET.   One 
	especially useful feature which the  MACLISP macro for LET has is
	that of "pattern decomposition": a general data pattern may be used
	in each place where a variable is expected; and for each combination 
	of data-accessing functions which access a non-null symbol in the data
	pattern, there is set up a binding between that symbol and the same 
	data-accessing path applied to the "argument" expression (that is, 
	one of the <ei>).  Thus nullist in a pattern means "ignore".  A simple 
	example should suffice, but also a BNF description is given.
	    (LET ( ((A . B)  <e1>) 
		   ((() C () D)  <e2>)
		   (TEMP1)
		   TEMP2 )
		 <computate>)
	expands into something that operates like
	    ((LAMBDA (G0001 G0002 A B C D TEMP1 TEMP2)
		     (SETQ A (CAR G0001))
		     (SETQ B (CDR G0001))
		     (SETQ C (CADR G0002))
		     (SETQ D (CADDDR G0002))
		     <computate>)
		<e1> <e2> () () () () () () )
	Just exactly what code comes out of the LET macro depends on many
	things, but the intent is to "decompose" the argument, according
	to the structure of the pattern of variables, and bind the variables
	correspondingly.  
	    DESETQ is similar, but there is no "binding" involved - only 
	"set"ing.  For example,
	   (DESETQ  (A . B)  (MUMBLIFY))
	might become
	   ((LAMBDA (G0001) (SETQ A (CAR G0001) B (CDR G0001))) (MUMBLIFY))
	When compiled, the extra variable G0001 may not cause any noticeable
	slowdown in the running of such code, but if the item being 
	destructured is denoted by a variable, then there is no new LAMBDA:
		(DESETQ (() C () D)  XVAR)
	might expand into
	    (SETQ C (CADR XVAR) D (CADDDR XVAR))
	    A given instance of LET or DESETQ usage will be "DISPLACED" or
	not depending on the value of the variable DEFMACRO-DISPLACE-CALL;
	See 3c below for more information about the use of this flag.
	    In point of fact, LET is continually being extended to know
	about structures other than lists; thus in NIL, one may destructure
	thru VECTORs also, and thru a "record" created by the structure
	package DEFVST (currently on LIBDOC and LIBLSP).  But leaving
	aside these more arcane data structure for now, a BNF description
	would be
	  ( LET ( { <symbol> | ( <pattern> <computation> ) }* )
		{ <s-exp> }* )
	where a "<pattern>" may be a symbol, or the nullist, or any list 
	(or "vector", or "defvst") structure.   Also:
	  ( DESETQ <pattern> <computation> )

   3b) DEFUN&, for maclisp compatibility with the extended DEFUN syntax
	of the LISPMachine, using "&OPTIONAL" and "&REST"
	Also, note that if DEFUN notices the occurance of any of the 
	keywords &OPTIONAL, &REST, or &AUX in the defining arglist, the
	the form is automatically turned into a DEFUN& (which may have 
	to be autoloaded).  This way, it will appear that MACLISP
	supports the extended syntax.   Let an "<arglist>" be defined
	by BNF as follows:
	( {<pattern>}* { &OPTIONAL { <symbol> | ( <pattern> <s-exp> ) }* }
		       { &REST <symbol> }
		       { &AUX { <symbol> | ( <pattern> <s-exp> ) }* } )
	Then the extended DEFUN syntax is defined by
     ( DEFUN { <symbol> | (<symbol> <symbol>) | (<symbol> <symbol> <symbol>) }+
	     { EXPR | FEXPR | MACRO | | }
	     { <symbol> | () | <arglist> }
	     { ( DECLARE { <s-exp> }* ) | | }
	     { <s-exp> }*   )

	    Note that this allow pattern decomposition at each argument
	position of a function definition;  if a single symbol, say <sym>
	occurs in the optional list, it is treated as if it were of the
	form "(<sym> () )"  - this way there is no ambiguity caused by
	the permission of <pattern>s in the optional list, for the use
	of such must be in the default-value-supplied form.  Also, the 
	order of evaluation of the default values for optional arguments, 
	and of the values for the auxillary variables, is strictly 
	left-to-right, **after** all the non-optional argument bindings 
	have been made.  Here is an example with a lot of "bells-and-whistles"
	just for illustrative purposes:
	    (DEFUN FOO ( (() NAME VARLIST . BODY)
			 KIND 
			 &OPTIONAL (PS-FLAG (AND (EQ (CAAR BODY) 'DECLARE)))
				   ((DNAM . DLST)  (AND PS-FLAG (CADAR BODY)))
			 &REST 	   W
			 &AUX 	   (N (COND (PS-FLAG 5) (6)))
			)
		(WORK-IT-OUT ...))
	Thus FOO requires at least two arguments; and two more will be further
	bound, one into PS-FLAG, and the other destructured into (DNAM . DLST) 

   3c) DEFMACRO, MACRO  --  macro-producing macros, compatible with LISPM.
       Three flags are noticed during instances of the macro expansions:
	  DEFMACRO-CHECK-ARGS   			(default = T)
	  DEFMACRO-DISPLACE-CALL			(default = T)
	  DEFMACRO-FOR-COMPILING			(default = T)
       The first flag if non-null, produces a macro which checks each 
	 instance of usage for compatible numbers of "arguments"; since this
	 checking takes time, it may not be desirable in all circumstances.
       The second if non-null, produces a macro which calls
	 DISPLACE in order to displace out the original macro call.
	 The macros MACRO-DISPLACE and DEFMACRO-DISPLACE exist, just
	 as in the LISPM, which do not pay attention to this flag, but
	 rather always yield a product which uses DISPLACE.
       The third determines which of the two macro-defining forms
	  will be used: (DEFUN foo MACRO ...)  or (DEFUN (foo MACRO) ...)
	  If non-null, the latter will be used so that the macro will be
	  compiled by the compiler (whereas the former format is intended 
	  primarily for macros used interpretively, or as compilation aids;  
	  see 5b below.
       DEFMACRO admits a "bound-variable-list" that is reminiscent of
	 the standard argument-list processing:
	   ( {<pattern>}*
	     {&OPTIONAL {<symbol> | (<pattern> <default.evaluation>) }+ }
	     {&REST <symbol>} )
	As with DEFUN&, a single symbol, say <sym>, in the &optional list 
	is treated as if it were of the form  "(<sym> () )", for purposes
	of default initializations.
       Examples:
	(MACRO ERRBRK (X) (COND ((EQ (CADR X) 'BARF) '(ERR))
				(`(PROG2 (PRINC ',(cadr x)) (BREAK ERROR)))))
	(DEFMACRO ERRBRK (MSG &OPTIONAL (BKTYPE 'ERROR))
		  (COND ((EQ (CADR X) 'BARF) '(ERR))
			(`(PROG2 (PRINC ',msg) (BREAK ,bktype)))))

4) Better error checking in *RSET mode for functions that cdr down lists:
   LAST now gets the last node of a non-atomic s-expression, or () for ().
	In *RSET mode, the time is taken to check that no attempt is made 
   to take the cdr of a non-null atom in the functions 
   NTH, NTHCDR, APPEND, NCONC, REVERSE, NREVERSE, NRECONC, ASSQ, MEMQ, DELQ
	Regardless of the setting of *RSET,  the following functions will
   not cdr through a non-null atom:
	LAST, MEMBER, ASSOC, DELETE, all MAP series.
   [In LISP versions prior to about 1783, LAST had the bug that it would
   begin cdr'ing down the plist of any symbol at the termination of a 
   non-standard list - try (LAST '(A . CAR))].   Note however, if any of the 
   MAP series gets expanded into a DO loop by the compiler, the endtest will 
   be replaced by NULL rather than ATOM.


5) "MACLISP" is now on the feature list, to help distinguish from LISPM.
   (STATUS FEATURE LISPM) is non-null for the LISP machine
   (STATUS FEATURE MACLISP) is non-null for all PDP10 and MULTICS MACLISPs
   (STATUS FEATURE NIL)  is non-null for any real or simulated NIL.

6) COMPLR  has some new switches and global variables - EXPAND-OUT-MACROS etc.
   6a) new switch  - H for variable  EXPAND-OUT-MACROS
	Toplevel forms which are not functions to be compiled (or other
	wise specially treated by MAKLAP) could be fully macro-expanded
	before being output to the FASL file.  Normal setting is non-null
	meaning to do this expansion.
   6b) repeat of meaning of the M switch - variable MACROS 
	MAKLAP will not cause the compilation of a form like
	(DEFUN <foo> MACRO (<var>) ...)  when it is processing a file,
	for it assumes that this macro is only for aid during compilation.
	If MACROS is non-null, it will also output an expr form for such
	a macro into the FASL file.  Remember that if the definition is like
	(DEFUN (<foo> MACRO) (<var>) ...), then the compiled version of the
	macro will always be output.  In either case, COMPLR remembers the
	expr definition for use during the subsequent parts of the file.
   6c) new variable -  MAKLAP-DEFAULTF-STYLE 
	The command line read maklap usually consists of two file specs
	separater by a left-arrow (underscore in new ascii); the filling
	in of the unspecified components of a file spec can be done either
	from the accumulated left-to-right mergeing, or begin separately
	for input and output file specs.  MIDAS style is the former, and
	the value of this new variable either is MIDAS or ().
   6d) when making up, can set feature  NO-EXTRA-OBARRAY
	(SSTATUS FEATURE NO-EXTRA-OBARRAY) will permit CCLOAD to make
	up a compiler without the COBARRAY/CREADTABLE which separates
	user environment from compiler environment.  If saving about 1.5K
	or so words means that much to you, and taking a chance means 
	very little . . .

7) SUSPEND - review of meanings of arguments
    [Original information in the LISP NEWS file, under dates
	5/22/74   JAN 13,1978    June 14,1978    ]
    If no arguments are given, then a return to monitor is preceeded by
	the message ";$Suspended$" (in ITS, it is ":Suspended", and those 
	are alt-modes rather than dollar-signs).
    First arg -  string for printing to  exec; null; or (on ITS) small fixnum.
	Ordinarily, when the suspended LISP returns to the monitor, it
	  will print the message ";$Suspended$", but a non-null symbol will
	  be printed instead; null means continue immediately, possibly after
	  dumping out into the file specified by the second argument.
	For ITS system, the message printed out will be executed by DDT, just
	  like a string to VALRET; if the argument is a fixnum, it will be
	  taken as the value to put in the right half of a .BREAK 16,.
    Second arg -  file name in which to dump the pure parts of the system
	For ITS system, the job is PDUMPd, with an "indirect" symbol table;
	    the pages shared with the system-dumped TS LISP are not dumped
	    if (STATUS FLUSH) is non-null.   Since a LISP tries to share its
	    read-only pages with the system-dumped TS LISP, the only reason
	    for allowing them to be copied out into the dump'd file when
	    SUSPENDing is the fear that the system-dumped TS LISP may
	    inadvertently disappear off the file system.
	For TOPS-10 systems (and SAIL), the high segment of a two-segment
	    job is dumped into this file;  one must still type a SSAVE (or
	    or SAVE) at the monitor in order to dump the low segment.  But
	    if (STATUS FLUSH) is non-null, then no dumping of the high
	    segment occurs, and it is flushed before returning to the monitor,
	    so that when the dumped low segment is re-activated, it will try 
	    to retrieve the high segment associated with the original 
	    LISP.SHR file.   Caution!  As of Jan 1979, there may still be
	    bugs in the non-its version of SUSPEND.

8) Under the ITS operating system, a JCL line with only a <space> means don't 
   use any INIT file, even if the connected directory has one.  This may
   be extended to the TOPS versions also.