Saturday  Feb 07,1981  NM+3D.15H.34M.49S.   LISP 2071 / COMPLR 1094  -- JonL --


1) Multiple-value capability implemented thru some autoloadable things:
   New AUTOLOADable macros and capabilities from MLMAC:
     MULTIPLE-VALUE,  VALUES,  MULTIPLE-VALUE-BIND
   Autoloading SUBRs from file MLSUB:
      MULTIPLE-VALUE-LIST,  VALUES-LIST,  and SI:CHECK-MULTIPLICITIES
   Non-autoloading macros available in MLMAC:   
	MULTIPLE-VALUE-RETURN  and RETURN-LIST 
   Reminder: MULTIPLE-VALUE is essentially the same as MSETQ-CALL of
     previous notes.  The names MSETQ-CALL and MSETQ-RETURN will be
     superseded by the LISPM names; however macros to convert them will
     be provided in the UMLMAC file (Utility MacLisp MACros).
  [more exposition below]
2) Additional, new "out-of-core" SUBRs and MACROs:
   Two LSUBRs "<=" and ">=", of 2 or more args are autoloadable from MLSUB file
   SOURCE-TRANS properties are set up, in the MLMAC file, for 
     LOGAND, LOGIOR, LOGXOR, LOGNOT, FIXNUMP, FLONUMP, EVENP, <=, >=, <, and >.
     (see item 4 below for "SOURCE-TRANS"), and these are used to
     generate some other SUBRs in the MLSUB file:
	LOGAND, LOGIOR, LOGXOR, LOGNOT,
	LISTP, FIXNUMP, FLONUMP, and EVENP.
   Non-autoloading macro available in DEFMAC:  DEFUNP 
   Non-autoload versions of FMAKUNBOUND, FSYMEVAL, and FSET are in FUNCEL file.
  [more exposition below]
3) Default value for DEFUN&-CHECK-ARGS is now (), and whenever &OPTIONAL or
    &REST args are specified, the "args property" of the symbol will be set.
  [more exposition below]
   DEFUN&-CHECK-ARGS is the variable which says whether or not there should
    be code in the function itself to do number-of-args checking. 
   The interpreter, and "UUO" handler, when in *RSET mode, will check the 
    number of arguments passed to a LSUBR/SUBR against the "args property", 
    which is retrieved and set by the ARGS function.
4) SOURCE-TRANS properties for COMPLR act almost like LISPM "optimizers".
  [more exposition below]
5) FILE-EXIT-FUNCTIONS is a new global variable which is lambda-bound to
     the value of FILE-EXIT-FUNCTIONS-DEFAULT by LOAD and FASLOAD.
     It holds a list of functions of 1 arg to be run  at end of loading.
  [more exposition below]
6) DEFSFA, a macro for defining macros to make SFA usage easier, is now
    defined in the EXTMAC file (along with DEFCLASS* and DEFMETHOD*)
    see the documentation file SFA.DOC (on ITS system -- .INFO.;LISP SFA)
    for full information.

_______________________________________________________________________

1) Multiple-value capability implemented thru some autoloadable things:
   New AUTOLOADable macros and capabilities from MLMAC:
     MULTIPLE-VALUE,  VALUES,  MULTIPLE-VALUE-BIND
   Autoloading SUBRs from file MLSUB:
      MULTIPLE-VALUE-LIST,  VALUES-LIST,  and SI:CHECK-MULTIPLICITIES
   Non-autoloading macros available in MLMAC:   
	MULTIPLE-VALUE-RETURN  and RETURN-LIST 
   Reminder: MULTIPLE-VALUE is essentially the same as MSETQ-CALL of
     previous notes.  The names MSETQ-CALL and MSETQ-RETURN will be
     supersede by the LISPM names; however macros to convert them will
     be provided in the UMLMAC file (Utility MacLisp MACros).

      Frequently, it is convenient to think of a function as returning
   several values; in LISP, one often just constructed a list of the
   several item, and the calling function would "destructure" that list.
   The basic special forms  MULTIPLE-VALUE and VALUES are provided to
   indicate respectively a function call which is expected to return
   (possibly) multiple values, and a function exit which does provide
   (possibly) multiple values.  Cooperation is achieved through a 
   "return-values vector", which in MacLISP is just a collection of
   several special variables.  MULTIPLE-VALUE is somewhat like SETQ
   in that the multiple-values returned by the call will be set into
   some variables; e.g.,
	(MULTIPLE-VALUE (AVERAGE MAX STANDARD-DEVIATION)
			(STATISTICS-GATHERER x1 y1 ...))
   might set up three values in the variables AVERAGE, MAX, and 
   STANDARD-DEVIATION, but without requiring an intermediate list of
   results.  Similarly, 
	(MULTIPLE-VALUE-BIND (AVERAGE MAX STANDARD-DEVIATION)
			     (STATISTICS-GATHERER x1 y1 ...)
		(do-something ...)
		... 
		(do-last-thing ...))
   provides a lambda-binding, rather than a setting, of the variables,
   over the enclosed scope.  Also, for example, the routine
   STATISTICS-GATHERER  might look like
 	(DEFUN STATISTICS-GATHERER (a1 a2 ...)
	   ... 	;lotta work here!
	   (VALUES  (//$ SUM N)  HIGHEST  (COMPUTE-SD)))
   The value of the form (MULTIPLE-VALUE (X ...) ...) is the thing
   which got set to X;  since destructuring works with MULTIPLE-VALUE,
   then (MULTIPLE-VALUE (() Y ...) ...)  returns the thing which would
   have been set to the first variable, had it not been ().

   MSETQ-CALL and MSETQ-RETURN are being superseded by the LISPM names,
   which are now essentially equivalent; minor differences are noted by 
   an occurrence of **** in the documentation here below.
   1a) MULTIPLE-VALUE, in MacLISP, macroexpands into code to setq the requested
	variables to the multiple values returned by a function call.  E.g.
	    (MULTIPLE-VALUE (FORM EX?) (MACROEXPAND-1*M FORM))
	calls a macroexpander which returns two values -- the first is the
	possibly expanded form, and the second is a flag saying whether or
	not any expansion really happened.   If there aren't enough returned
	values to set all the indicated variables, the default action of the
	MacLISP facility is to pad out with ()'s (same as on LISPM); 
	however, **** if the global variable SI:CHECK-MULTIPLICITIES is 
	set to CERROR, an error will be signalled instead.   See the 
	discussion under item 4 below.
   1b) VALUES is a new LISPM special form, and in NIL/MacLISP it is 
	essentially the same thing as MSETQ-RETURN was; its basic action is
	to set up a "return-values vector";  typical usage would be to
	call VALUES as the last form in a lambda-expression.  Example:
	    (DEFUN TWIST (X Y) 
		(COND ((AND (NUMBERP X) (NUMBERP Y)) 
			(VALUES 'T (LESSP X Y)))
		      ('T (SETQ X (TO-STRING X) Y (TO-STRING Y))
			  (VALUES () (ALPHALESSP X Y)))))
   1c) MULTIPLE-VALUE-LIST constructs a list of all the (possibly multiple) 
        values returned by the evaluated sub-form.  Format of usage is like
	    (MULTIPLE-VALUE-LIST (<fun> ...))
	where <fun> should return some (possibly multiple) values.
   1d) RETURN in MacLISP still admits only one argument **** -- in order to do
	a RETURN with multiple arguments, do (RETURN (VALUES first second ...))
        MULTIPLE-VALUE-RETURN is primitive on the LISPM, but is macro expanded
	in MacLISP to use merely RETURN.  Currently, RETURN (but not
	MULTIPLE-VALUE-RETURN) is primitive in MacLISP, and this causes one
	incompatibility -- (RETURN (VALUES ...)) on the LISPM might return
	only one value, but in MacLISP it will return as many values as are 
	provided by the VALUES;  also, if FOO is a function returning
	multiple values, then (RETURN (FOO)) will "pass them all thru" doing
	essentially what MULTIPLE-VALUE-RETURN does on the LISPM.
   1e) VALUES-LIST is a SUBR of one argument, a list, which it "spreads out"
	into the "return-values vector";  Thus  (VALUES-LIST '(1 B 3))
	is the same as (VALUES 1 'B 3).
       RETURN-LIST macroexpands into something like 
	    (MULTIPLE-VALUE-RETURN (VALUES-LIST ...))
	As mentioned above for MULTIPLE-VALUE-RETURN, there is the implicit 
	LISPM/MacLISP incompatibility about RETURN.
   1f) MULTIPLE-VALUE-BIND -- a form is to be evaluated, returning several
	values, and *then* a lambda-binding contour is created, with
	the values bound to some variables;  following that, the body of
	and implicit PROGN is executed.  Example:
	    (MULTIPLE-VALUE-BIND  (A B C)  (GET-THREE-VALS ...) 
		(COGITATE-UPON A)
		(LIST B C))
   1G) SI:CHECK-MULTIPLICITIES  **** is called whenever MULTIPLE-VALUE or
	MULTIPLE-BIND have more variables than there are returned values;
	the value of SI:CHECK-MULTIPLICITIES, as a variable, then determines
	what to do (default setting is null):
	  ()     -- means pad out unsupplied multiple-return-values with nulls;
	  CERROR -- means run an error if not enough values supplied;
	  any thing else should be a function to funcall with an argument which
		is the number of variables minus one (*:ARn contains the
		actual number of returned values).
  Remember also that MULTIPLE-VALUE depends upon a "return-values vector" being
  set up by the function called, and thus constructs like 
    (MULTIPLE-VALUE (v1 v2) (PROG1 (MANY-VALUED-FUN a1 a3) (SOMETHING-ELSE)))
  will not work in general;  a correct way to do this particular example is 
	(LET (unique-var-1 unique-var-2)
	  (MULTIPLE-VALUE (unique-var-1 unique-var-2) (MANY-VALUED-FUN a1 a3))
	  (SOMETHING-ELSE)
	  (SETQ v1 unique-var-1 v2 unique-var-2)
	  v1)
  This "fault" of side-effecting also applies to MULTIPLE-VALUE-LIST.

  The multiple-value functions operate quite efficiently for 8 or fewer
   return values -- many of them are "open-coded" by virtue of the code 
   produced by the macroexpansions.  Any returned values more than 8 are 
   passed via a cons'ing mechanism.  Degenerate forms will generally
   work OK, provided they make sense; e.g. (VALUES FOOBAZ)  is just the
   same as FOOBAZ, except the internal "number-of-extra-return-values"
   variable is set up;  (MULTIPLE-VALUE (X) ...)  again will turn out
   pretty much like an ordinary SETQ, and (MULTIPLE-VALUE () (FOO))
   will turn out pretty much like (FOO), except that the internal
   count variable is set up.

2) Additional, new "out-of-core" SUBRs and MACROs:
   Two LSUBRs "<=" and ">=", of 2 or more args are autoloadable from MLSUB file
   SOURCE-TRANS properties are set up, in the MLMAC file, for 
     LOGAND, LOGIOR, LOGXOR, LOGNOT, FIXNUMP, FLONUMP, EVENP, <=, >=, <, and >.
     (see item 4 below for "SOURCE-TRANS"), and these are used to
     generate some other SUBRs in the MLSUB file:
	LOGAND, LOGIOR, LOGXOR, LOGNOT,
	LISTP, FIXNUMP, FLONUMP, and EVENP.
   Non-autoloading macro available in DEFMAC:  DEFUNP 
   Non-autoload versions of FMAKUNBOUND, FSYMEVAL, and FSET are in FUNCEL file.

   Each of <= and >= take two or more arguments; in addition, SOURCE-TRANS
     properties are set up for <=, >=, < ,and > so that the case of three 
     or more arguments are "wrapped up in a LAMBDA" and the basic open-coding 
     action of the COMPLR  on the binary version can be used.
   NILAID permits usage of any of <, <=, >=, >, <$, <=$, >=$, and >$ with
     two or more arguments;  the "$" versions are for floating-point.
   In conjunction with the functions which get SOURCE-TRANS properties
     from the MLMAC file, there are SUBR definitions of them in this
     file (MLSUB, which is acronymic for "MacLisp SUBrs"):
	LOGAND, LOGIOR, LOGXOR, LOGNOT, FIXNUMP, FLONUMP, and EVENP.
     For example, the definition of EVENP can be 
	(DEFUN EVENP (X) (EVENP X))
     because the SOURCE-TRANS's cause "(EVENP X)" to expand into
     "(NOT (ODDP X))"; similar tactics are used for multiple-argumented
     funtions like LOGXOR etc.
   Non-autoloading macro available in DEFMAC:  DEFUNP 
    As on the LISPM, (DEFUNP FOO (<args>) e1 e2 ... en) macroexpands
    into  (DEFUN FOO (<args>) 
	     (PROG () 
		   e1 
		   e2 
		   (RETURN en)))
   Non-autoload versions of FMAKUNBOUND, FSYMEVAL, and FSET are in FUNCEL file.
    By loading in the EXTEND feature, a pseudo SUBR object can be created 
    and manipulated;  thus reasonable versions of the LISPM/NIL functions 
    FMAKUNBOUND, FSYMEVAL, and FSET are implemented.   
    This facility is pre-loaded into NILAID.


3) Default value for DEFUN&-CHECK-ARGS is now (), and whenever &OPTIONAL or
    &REST args are specified, the "args property" of the symbol will be set.

   DEFUN&-CHECK-ARGS is the variable which says whether or not there should
    be code in the function itself to do number-of-args checking. 
   The interpreter, and "UUO" handler, when in *RSET mode, will check the 
    number of arguments passed to a LSUBR/SUBR against the "args property", 
    which is retrieved and set by the ARGS function.


4) SOURCE-TRANS properties for COMPLR act almost like LISPM "optimizers".

   It is now possible to carry out "code-transformations" in COMPLR
     by means of the SOURCE-TRANS mechanism. When compiling a form whose
     CAR is a symbol, the compiler will check for a SOURCE-TRANS property
     on the symbol. The value of this propery should be a list of
     transformation routines, each of which must be a function of one
     argument. Furthermore, each transformation routine must return two
     values (e.g., via VALUES), the first being the transformed form and
     the second being a flag which, when non-null, indicates that the
     transformation routine has "done something". The compiler applies
     each transformation routine in turn, passing the form to be
     transformed as the sole argument. If the transformation routine
     returns a second value of () then it is considered to have
     "done nothing" and the next transformation routine is tried; otherwise
     the routine is considered to have "done something" and the entire
     process begins anew with the first transformation routine.
     The transformation of the original form is complete only after all
     transformation routines have been tried and "done nothing". This
     transformation procedure is carried out fully before any macro
     expansion is attempted.
   Note well, that this differs from the LISPM facility in that the
     translating functions *must* return at least two values.

 
5) FILE-EXIT-FUNCTIONS is a new global variable which is lambda-bound to
     the value of FILE-EXIT-FUNCTIONS-DEFAULT by LOAD and FASLOAD.
     It holds a list of functions of 1 arg to be run  at end of loading.

   The argument supplied to each function is null if loading completed 
     successfully;  otherwise it is the file-array of the file being 
     aborted.  This provision uses the UNWIND-PROTECT mechanism, so these 
     functions will be called even if the file is aborted by ^G or *THROW.
   The initial setting of FILE-EXIT-FUNCTIONS-DEFAULT is null, so if you
     set it to something else, those functions will be run at the end of
     every file loading;  typically, a file itself may push forms onto
     FILE-EXIT-FUNCTIONS to provide for individual "cleanup".