4.2BSD/usr/lisp/ch4.n

." $Header: ch4.n 1.4 83/07/27 15:11:44 layer Exp $
.pp
.Lc Special\ Functions 4
.Lf and "[g_arg1 ...]"
.Re
the value of the last argument if all arguments evaluate
to a non-nil value, otherwise 
.i and 
returns nil.
It returns t if there are no arguments.
.No
the arguments are evaluated left to right and evaluation will cease
with the first nil encountered
.Lf apply "'u_func 'l_args"
.Re
the result of applying function u_func to the arguments in the list l_args.
.No
If u_func is a lambda, then the \fI(length\ l_args)\fP should equal the
number of formal parameters for the u_func.
If u_func is a nlambda or macro, then l_args is bound to the single
formal parameter.
.Eb
; \fIadd1\fP is a lambda of 1 argument
\-> \fI(apply 'add1 '(3))\fP
4

; we will define \fIplus1\fP as a macro which will be equivalent to \fIadd1\fP
\-> \fI(def plus1 (macro (arg) (list 'add1 (cadr arg))))\fP
plus1
\-> \fI(plus1 3)\fP
4

; now if we \fIapply\fP a macro we obtain the form it changes to.
\-> \fI(apply 'plus1 '(plus1 3))\fP
(add1 3)

; if we \fIfuncall\fP a macro however, the result of the macro is \fIeval\fPed
; before it is returned.
\-> \fI(funcall 'plus1 '(plus1 3))\fP
4

; for this particular macro, the \fIcar\fP of the \fIarg\fP is not checked
; so that this too will work
\-> \fI(apply 'plus1 '(foo 3))\fP
(add1 3)

.Ee
.Lf arg "['x_numb]"
.Re 
if x_numb is specified then the x_numb'\fIth\fP argument to 
the enclosing lexpr
If x_numb is not specified then this returns the number of arguments 
to the enclosing lexpr.
.No
it is an error to the interpreter if x_numb is given and out of range.
.Lf break "[g_message ['g_pred]]"
.Wh
if g_message is not given it is assumed to be the null string, and
if g_pred is not given it is assumed to be t.
.Re
the value of \fI(*break 'g_pred 'g_message)\fP
.Lf *break "'g_pred 'g_message"
.Re
nil immediately if g_pred is nil, else
the value of the next (return 'value) expression typed in at top level.
.Se
If the predicate, g_pred, evaluates to non-null,
the lisp system stops and prints out `Break '
followed by g_message. 
It then enters a break loop
which allows one to interactively debug a program.
To continue execution from a break you can use the
.i return 
function. 
to return to top level or another break level, you can use
.i retbrk 
or 
.i reset .
.Lf caseq "'g_key-form l_clause1 ..."
.Wh 
l_clause\fIi\fP is a list of the form
(g_comparator ['g_form\fIi\fP ...]).
The comparators may be symbols, small fixnums, a list of small fixnums or
symbols.
.No
The way caseq works is that it evaluates g_key-form,
yielding a value we will call the selector.
Each clause is examined until the selector is found
consistent with the comparator.
For a symbol, or a fixnum, this means the two must be \fIeq\fP.
For a list, this means that the selector must be \fIeq\fP to
some element of the list.
.br
.sp
The symbol \fBt\fP has special semantics:
it matches anything, and consequently, should be the last comparator.
Then, having chosen a clause, \fIcaseq\fP evaluates each form
within that clause and
.Re
the value of the last form.  If no comparators are matched,
\fIcaseq\fP returns nil.
.Eb
Here are two ways of defining the same function:
\->\fI(defun fate (personna)
	(caseq personna
	  (cow '(jumped over the moon))
	  (cat '(played nero))
	  ((dish spoon) '(ran away together))
	  (t '(lived happily ever after))))\fP
fate
\->\fI(defun fate (personna)
	(cond
		((eq personna 'cow) '(jumped over the moon))
		((eq personna 'cat) '(played nero))
		((memq personna '(dish spoon)) '(ran away together))
		(t '(lived happily ever after))))\fP
fate
.Ee
.Lf catch "g_exp [ls_tag]"
.Wh
if ls_tag is not given, it is assumed to be nil.
.Re
the result of \fI(*catch 'ls_tag g_exp)\fP
.No
catch is defined as a macro.
.Lf *catch "'ls_tag g_exp"
.Wh
ls_tag is either a symbol or a list of symbols.
.Re
the result of evaluating g_exp or the value thrown during the evaluation
of g_exp.
.Se
this first sets up a `catch frame' on the lisp runtime stack.
Then it begins to evaluate g_exp.
If g_exp evaluates normally, its value is returned.
If, however, a value is thrown during the evaluation of g_exp then
this *catch will return with that value if one of these cases
is true:
.nr $p 0
.np
the tag thrown to is ls_tag 
.np
ls_tag is a list and the tag thrown to is a member of this list
.np
ls_tag is nil.
.No
Errors are implemented as a special kind of throw.
A catch with no tag will not catch an error but a catch whose tag is
the error type will catch that type of error.
See Chapter 10 for more information.
.Lf comment "[g_arg ...]"
.Re
the symbol comment.
.No
This does absolutely nothing.
.Lf cond "[l_clause1 ...]"
.Re
the last value evaluated in the first clause satisfied.
If no clauses are satisfied then nil is returned.
.No
This is the basic conditional `statement' in lisp.
The clauses are processed from left to right.
The first element of a clause is evaluated.
If it evaluated to a non-null value then that clause is satisfied and
all following elements of that clause are evaluated.
The last value computed is returned as the value of the cond.
If there is just one element in the clause then its value is returned.
If the first element of a clause evaluates to nil, then the other
elements of that clause are not evaluated and the system moves to
the next clause.
.Lf cvttointlisp
.Se
The reader is modified to conform with the Interlisp syntax.
The character % is made the escape character and special meanings for
comma, backquote and backslash are removed. 
Also the reader is told to convert upper case to lower case. 
.Lf cvttofranzlisp
.Se
The reader is modified to conform with franz's default syntax.
One would run this function after having run cvttomaclisp, only.
Backslash is made the escape character, and super-brackets are
reinstated.  The reader is reminded to distinguish between upper and
lower case.
.Lf cvttomaclisp
.Se
The reader is modified to conform with Maclisp syntax.
The character / is made the escape character and the special meanings
for backslash, left and right bracket are removed.
The reader is made case-insensitive.
.Lf cvttoucilisp
.Se
The reader is modified to conform with UCI Lisp syntax.
The character / is made the escape character, tilde is made the comment
character, exclamation point takes on the unquote function normally
held by comma, and backslash, comma, semicolon become normal 
characters.
Here too, the reader is made case-insensitive.
.Lf debug "s_msg"
.Se
Enter the Fixit package described in Chapter 15.
This package allows you to examine the evaluation stack in detail.
To  leave the Fixit package type 'ok'.
.Lf debugging "'g_arg"
.Se
If g_arg is non-null,
Franz unlinks the transfer tables, does a \fI(*rset\ t)\fP to turn on
evaluation monitoring and sets the all-error catcher (ER%all) to be
\fIdebug-err-handler\fP.
If g_arg is nil,
all of the above changes are undone.
.Lf declare "[g_arg ...]"
.Re
nil
.No
this is a no-op to the evaluator.
It has special meaning to the compiler (see Chapter 12).
.Lf def "s_name (s_type l_argl g_exp1 ...)"
.Wh
s_type is one of lambda, nlambda, macro or lexpr.
.Re
s_name
.Se
This defines the function s_name to the lisp system.
If s_type is nlambda or macro then the argument list l_argl must contain
exactly one non-nil symbol.
.Lf defmacro "s_name l_arg g_exp1 ..."
.Lx defcmacro "s_name l_arg g_exp1 ..."
.Re
s_name
.Se
This defines the macro s_name.  
\fIdefmacro\fP makes it easy to write macros since it makes
the syntax just like \fIdefun\fP.
Further information on \fIdefmacro\fP is in \(sc8.3.2.
\fIdefcmacro\fP defines compiler-only macros, or cmacros.  
A cmacro is stored on the property list of a
symbol under the indicator \fBcmacro\fP.
Thus a function can
have a normal definition and a cmacro definition.
For an example of the use of cmacros, see the definitions
of nthcdr and nth in /usr/lib/lisp/common2.l
.Lf defun "s_name [s_mtype] ls_argl g_exp1 ... "
.Wh
s_mtype is one of fexpr, expr, args or macro.
.Re
s_name
.Se
This defines the function s_name.
.No
this exists for Maclisp compatibility, it is just a macro which
changes the defun form to the def form.
An s_mtype of fexpr is converted to nlambda
and of expr to lambda. Macro remains the same.
If ls_arg1 is a non-nil symbol, then the type is assumed to be lexpr and
ls_arg1 is the symbol which is bound to the number of args when the
function is entered.
.br
For compatability with the Lisp Machine lisp, there are three types of
optional parameters that can occur in ls_argl:  \fI&optional\fP declares that
the following symbols are optional, and may or may not appear in the
argument list to the function, \fI&rest symbol\fP
declares that all forms in the
function call that are not accounted for by previous lambda bindings
are to be assigned to \fIsymbol\fP, and \fI&aux form1 ... formn\fP
declares that the \fIformi\fP are either symbols, in which case they
are lambda bound to \fBnil\fP, or lists, in which case the first element
of the list is lambda bound to the second, evaluated element.
.Eb
; \fIdef\fP and \fIdefun\fP here are used to define identical functions
; you can decide for yourself which is easier to use.
\-> \fI(def append1 (lambda (lis extra) (append lis (list extra))))\fP
append1

\-> \fI(defun append1 (lis extra) (append lis (list extra)))\fP
append1

; Using the & forms...
\-> \fI(defu\kCn test (a b &optional c &aux (retval 0) &rest z)
        \h'|\nCu'\kB(if c them (msg \kA"Optional arg present" N
                        \h'|\nAu'"c is " c N))
        \h'|\nBu'(msg \kA"rest is " z N
             \h'|\nAu'"retval is " retval N))\fP
test
\-> \fI(test 1 2 3 4)\fP
Optional arg present
c is 3
rest is (4)
retval is 0
.Ee
.Lf defvar "s_variable ['g_init]"
.Re
s_variable.
.No
This form is put at the top level in files, like \fIdefun\fB.
.Se
This declares s_variable to be special. If g_init is present,
and s_variable is unbound when the file is read in, s_variable
will be set to the value of g_init.
An advantage of `(defvar foo)' over `(declare (special foo))' is that if
a file containing defvars is loaded (or fasl'ed) in during compilation,
the variables mentioned in the defvar's will be declared special.  The only
way to have that effect with `(declare (special foo))' is to \fIinclude\fP
the file.  
.Lf do "l_vrbs l_test g_exp1 ..."
.Re
the last form in the cdr of l_test evaluated, or a value explicitly given by
a return evaluated within the do body.
.No
This is the basic iteration form for
.Fr .
l_vrbs is a list of zero or more var-init-repeat forms.
A var-init-repeat form looks like:
.br
.tl ''(s_name [g_init [g_repeat]])''
There are three cases depending on what is present in the form.
If just s_name is present, this means that when the do is entered,
s_name is lambda-bound to nil and is never modified by the system 
(though the program is certainly free to modify its value).
If the form is (s_name\ 'g_init) then the only difference is that
s_name is lambda-bound to the value of g_init instead of nil.
If g_repeat is also present then s_name is lambda-bound to g_init
when the loop is entered and after each pass through the do body
s_name is  bound to the value of g_repeat.
.br
l_test is either nil or has the form of a cond clause.
If it is nil then the do body will be evaluated only once and the
do will return nil.
Otherwise, before the do body is evaluated the car of l_test is 
evaluated and if the result is non-null, this signals an end to
the looping.
Then the rest of the forms in l_test are evaluated
and the value of the last one is returned as the value of the do.
If the cdr of l_test is nil, then nil is returned -- thus this is not
exactly like a cond clause.
.br
g_exp1 and those forms which follow constitute the do body.
A do body is like a prog body and thus may have labels and one may
use the functions go and return.
.br
The sequence of evaluations is this:
.nr $p 0
.np
the init forms are evaluated left to right and  stored in temporary
locations.
.np
Simultaneously all do variables are lambda bound to the value of
their init forms or nil.
.np
If l_test is non-null, then the car is evaluated and if it is non-null,
the rest of the forms in l_test are evaluated and the last value is 
returned as the value
of the do.
.np
The forms in the do body are evaluated left to right.
.np
If l_test is nil the do function returns with the value nil.
.np
The repeat forms are evaluated and saved in temporary locations.
.np
The variables with repeat forms are simultaneously
bound to the values of those forms.
.np
Go to step 3.
.No
there is an alternate form of do which can be used when there is
only one do variable.
It is described next.
.Eb
; this is  a simple function which numbers the elements of a list.
; It uses a \fIdo\fP function with two local variables.
\-> \fI(defun printem (lis)
	     (do ((xx lis (cdr xx))
		  (i 1 (1+ i)))
		 ((null xx) (patom "all done") (terpr))
		 (print i)
		 (patom ": ")
		 (print (car xx))
		 (terpr)))\fP
printem
\-> \fI(printem '(a b c d))\fP
1: a
2: b
3: c
4: d
all done
nil
\-> 
.Ee
.Lf do "s_name g_init g_repeat g_test g_exp1 ..."
.nr $p 0
.No
this is another, less general,  form of do.
It is evaluated by:
.np
evaluating g_init
.np
lambda binding s_name to value of g_init
.np
g_test is evaluated and if it is not nil the do function returns with nil.
.np
the do body is evaluated beginning at g_exp1.
.np
the repeat form is evaluated and stored in s_name.
.np
go to step 3.
.Re
nil
.Lf environment "[l_when1 l_what1 l_when2 l_what2 ...]"
.Lx environment-maclisp "[l_when1 l_what1 l_when2 l_what2 ...]"
.Lx environment-lmlisp "[l_when1 l_what1 l_when2 l_what2 ...]"
.Wh
the when's are a subset of (eval compile load), and the symbols have the
same meaning as they do in 'eval-when'.
.br
.sp
The what's may be 
.br
	(files file1 file2 ... fileN),
.br
which insure that the named files are loaded.
To see if file\fIi\fP is loaded,
it looks for a 'version' property under
file\fIi\fP's property list.  Thus to prevent multiple loading,
you should put
.br
	(putprop 'myfile t 'version),
.br
at the end of myfile.l.
.br
.sp
Another acceptible form for a what is
.br
(syntax type)
.br
Where type is either maclisp, intlisp, ucilisp, franzlisp.
This sets the syntax correctly.
.br
.sp
\fIenvironment-maclisp\fP sets the environment to that which
`liszt -m' would generate.
\fIenvironment-lmlisp\fP  sets up the lisp machine environment. This is like
maclisp but it has additional macros.
For these specialized environments, only the \fBfiles\fP clauses are useful.
.Eg
	(environment-maclisp (compile eval) (files foo bar))
.Lf err "['s_value [nil]]"
.Re
nothing (it never returns).
.Se
This causes an error and if this error is caught by an 
.i errset
then that 
.i errset
will return s_value instead of nil.
If the second arg is given, then it must be nil (\s-2MAC\s0lisp 
compatibility).
.Lf error "['s_message1 ['s_message2]]"
.Re
nothing (it never returns).
.Se
s_message1 and s_message2 are \fIpatom\fPed if they are given and
then \fIerr\fP is called (with no arguments), which causes an error.
.Lf errset "g_expr [s_flag]"
.Re
a list of one element, which is the value resulting from evaluating g_expr.
If an error occurs during the evaluation of g_expr, then the locus of control
will return to the 
.i errset
which will then return nil (unless the error was caused by a call to
.i err,
with a non-null argument).
.Se
S_flag is evaluated before g_expr is evaluated. 
If s_flag is not given, then it is assumed to be t.
If an error occurs during the evaluation of g_expr, and s_flag evaluated to 
a non-null value, then the error message associated with the
error is printed before control returns to the errset.
.Lf eval "'g_val ['x_bind-pointer]"
.Re
the result of evaluating g_val.
.No
The evaluator evaluates g_val in this way:
.br
If g_val is a symbol, then the evaluator returns its value.
If g_val had never been assigned a value, then this causes 
an `Unbound Variable' error.
If x_bind-pointer is given, then the variable is evaluated with
respect to that pointer (see \fIevalframe\fP for details on bind-pointers).
.br
.sp
If g_val is of type value, then its value is returned.
If g_val is of any other type than list, g_val is returned.
.br
.sp
If g_val is a list object then g_val is either a function call or
array reference.
Let g_car be the first element of g_val.
We continually evaluate g_car until we end up with a symbol with
a non-null function binding
or a non-symbol.
Call what we end up with: g_func.
.br
.sp
G_func must be one of three types: list, binary or array.
If it is a list then the first element of the list, which 
we shall call g_functype, must be either
lambda, nlambda, macro or lexpr.
If g_func is a binary, then its discipline, which we shall call
g_functype, is either lambda, nlambda, macro or a string.
If g_func is an array then this form is evaluated specially, see
Chapter 9 on arrays.
If g_func is a list or binary, then g_functype will determine how
the arguments to this function, the cdr of g_val, are processed.
If g_functype is a string, then this is a foreign function call (see \(sc8.5
for more details).
.br
.sp
If g_functype is lambda or lexpr, the arguments are evaluated
(by calling 
.i eval
recursively) and stacked.
If g_functype is nlambda then the argument list is stacked.
If g_functype is macro then the entire form, g_val is stacked.
.br
.sp
Next, the formal variables are lambda bound.
The formal variables are the cadr of g_func.  If g_functype is
nlambda, lexpr or macro, there should only be one formal variable.
The values on the stack are lambda bound to the formal variables
except in the case of a lexpr, where the number of actual arguments
is bound to the formal variable.
.br
.sp
After the binding is done, the function is invoked, either by
jumping to the entry point in the case of a binary or 
by evaluating the list of forms beginning at cddr g_func.
The result of this function invocation is returned as the value 
of the call to eval.
.Lf evalframe "'x_pdlpointer"
.Re
an evalframe descriptor for the evaluation frame just before x_pdlpointer.
If x_pdlpointer is nil, it returns the evaluation frame of the frame just
before the current call to \fIevalframe\fP.
.No
An evalframe descriptor describes a call to \fIeval\fP, \fIapply\fP
or \fIfuncall\fP.
The form of the descriptor is 
.br
\fI(type pdl-pointer expression bind-pointer np-index lbot-index)\fP
.br
where type is `eval' if this describes a call to \fIeval\fP or `apply'
if this is a call to \fIapply\fP or \fIfuncall\fP.
pdl-pointer is a number which  describes
this context. 
It can be passed to
.i evalframe
to obtain the next descriptor and
can be passed to 
.i freturn
to cause a return from this context.
bind-pointer is the size of variable  binding stack when this
evaluation began. 
The bind-pointer can be given as a second argument
to \fIeval\fP to order to evaluate variables in the same context as
this  evaluation. 
If type is `eval' then expression
will have the form \fI(function-name\ arg1\ ...)\fP.
If type is `apply' then expression will have the form
\fI(function-name\ (arg1\ ...))\fP.
np-index and lbot-index are pointers into the
argument stack (also known as the \fInamestack\fP array) at the time of call.
lbot-index points to the first argument, np-index points one beyond
the last argument.
.br
In order for there to be enough information
for \fIevalframe\fP to return, you must call \fI(*rset\ t)\fP.
.Ex
\fI(progn (evalframe nil))\fP
.br
returns \fI(eval 2147478600 (progn (evalframe nil)) 1 8 7)\fP
.Lf evalhook "'g_form 'su_evalfunc ['su_funcallfunc]"
.Re 
the result of evaluating g_form after lambda binding `evalhook' to
su_evalfunc and, if it is given, lambda binding `funcallhook' to 
su_funcallhook.
.No
As explained in \(sc14.4, the function
.i eval
may pass the job of evaluating a form to a user `hook' function when 
various switches are set.
The  hook function normally prints the form to be evaluated on the
terminal and then evaluates it by calling 
.i evalhook .
.i Evalhook
does the lambda binding mentioned above and then calls 
.i eval 
to evaluate the form after setting an internal switch to tell 
.i eval
not to call the user's hook function just this one time.
This allows the evaluation process to advance one step and yet
insure that further calls to 
.i eval
will cause traps to the hook function (if su_evalfunc is non-null).
.br
In order for \fIevalhook\fP to work, \fI(*rset\ t)\fP and 
\fI(sstatus\ evalhook\ t)\fP must have been done previously.
.Lf exec "s_arg1 ..."
.Re
the result of forking and executing the command named by concatenating
the s_arg\fIi\fP together with spaces in between.
.Lf exece "'s_fname ['l_args ['l_envir]]"
.Re
the error code from the system if it was unable to 
execute the command s_fname with arguments
l_args and with the environment set up as specified in l_envir.
If this function is successful, it will not return, instead the lisp
system will be overlaid by the new command.
.Lf freturn "'x_pdl-pointer 'g_retval"
.Re
g_retval from the context given by x_pdl-pointer.
.No
A pdl-pointer denotes a certain expression currently being evaluated.  
The pdl-pointer for a given expression can be obtained from
.i evalframe .
.Lf frexp "'f_arg"
.Re
a list cell \fI(exponent . mantissa)\fP which represents the 
given flonum
.No
The exponent will be a fixnum, the mantissa a 56 bit bignum.
If you think of the the binary point occurring right after the
high order bit of mantissa, then
f_arg\ =\ 2\*[exponent\*]\ *\ mantissa.
.Lf funcall "'u_func ['g_arg1 ...]"
.Re
the value of applying function u_func to the arguments g_arg\fIi\fP
and then evaluating that result if u_func is a macro.
.No
If u_func is a macro or nlambda then there should be only one g_arg.
\fIfuncall\fP is the function which the evaluator uses to evaluate
lists.
If \fIfoo\fP is a lambda or lexpr or array, 
then \fI(funcall\ 'foo\ 'a\ 'b\ 'c)\fP
is equivalent to \fI(foo\ 'a\ 'b\ 'c)\fP.
If \fIfoo\fP is a nlambda
then \fI(funcall\ 'foo\ '(a\ b\ c))\fP is equivalent to
\fI(foo a b c)\fP.
Finally, if 
.i foo
is a macro then
.i (funcall\ 'foo\ '(foo\ a\ b\ c))
is equivalent to
.i (foo\ a\ b\ c) .
.Lf funcallhook "'l_form 'su_funcallfunc ['su_evalfunc]"
.Re 
the result of \fIfuncall\fPing 
the \fI(car\ l_form)\fP
on the already evaluated
arguments in the \fI(cdr\ l_form)\fP 
after lambda binding `funcallhook' to
su_funcallfunc and, if it is given, lambda binding `evalhook' to 
su_evalhook.
.No
This function is designed to continue the evaluation process 
with as little work as possible after a funcallhook trap has occurred. 
It is for this reason that the form of l_form is unorthodox: its 
.i car
is the name of the function to call and its 
.i cdr
are a list of arguments to stack (without evaluating again)
before calling the given function.
After stacking the arguments 
but
before calling
.i funcall
an internal switch is set to prevent \fIfuncall\fP
from passing the job of funcalling to su_funcallfunc.
If \fIfuncall\fP is called recursively in funcalling l_form and
if su_funcallfunc is non-null, then 
the arguments to 
.i funcall
will actually be given to su_funcallfunc (a lexpr) 
to be funcalled.
.br
In order for \fIevalhook\fP to work, \fI(*rset\ t)\fP and 
\fI(sstatus\ evalhook\ t)\fP must have been done previously.
A more detailed description of 
.i evalhook
and 
.i funcallhook
is given in Chapter 14.
.Lf function "u_func"
.Re
the function binding of u_func if it is an symbol with a function binding
otherwise u_func is returned.
.Lf getdisc "'y_func"
.Re
the discipline of the machine coded function (either lambda, nlambda
or macro).
.Lf go "g_labexp"
.Wh
g_labexp is either a symbol or an expression.
.Se
If g_labexp is an expression, that expression is evaluated and 
should
result in a symbol.
The locus of control moves to just following the symbol g_labexp in the
current prog or do body.
.No
this is only valid in the context of a prog or do body.
The interpreter and compiler will allow non-local 
.i go 's 
although the compiler won't allow a \fIgo\fP to leave a function body.
The compiler will not allow g_labexp to be an expression.
.Lf if "'g_a 'g_b"
.Lx if "'g_a 'g_b 'g_c ..."
.Lx if "'g_a \fBthen\fP  'g_b [...] [\fBelseif\fP 'g_c \fBthen\fP 'g_d ...] [\fBelse\fP 'g_e [...]"
.Lx if "'g_a \fBthen\fP  'g_b [...] [\fBelseif\fP 'g_c \fBthenret\fP] [\fBelse\fP 'g_d [...]"
.No
The various forms of \fIif\fP are intended to be a more readable
conditional statement, to be used in place of \fIcond\fP.  There
are two varieties of \fIif\fP, with keywords, and without.  The
keyword-less variety is inherited from common Maclisp usage.
A keyword-less, two argument \fIif\fP is equivalent to a one-clause
\fIcond\fP, i.e. (\fIcond\fP (a b)).   Any other keyword-less \fIif\fP
must have at least three arguments.  The first two arguments are the
first clause of the equivalent \fIcond\fP, and all remaining arguments
are shoved into a second clause beginning with \fBt\fP.  Thus, the
second form of \fIif\fP is equivalent to
.br
	(\fIcond\fP (a b) (t c ...)).
.br
.sp
The keyword variety has the following grouping of arguments:
a predicate, a then-clause, and optional
else-clause.  The predicate is evaluated, and if the result is
non-nil, the then-clause will be performed, in the sense
described below.  Otherwise, (i.e. the result of the predicate
evaluation was precisely nil), the else-clause will be performed.
.br
.sp
Then-clauses will either consist entirely
of the single keyword \fBthenret\fP, or will start with the keyword
\fBthen\fP, and be followed by at least one general expression.
(These general expressions must not be one of the keywords.)
To actuate a \fBthenret\fP means to cease further evaluation
of the \fIif\fP, and to return the value of the predicate just calculated.
The performance of the longer clause means to evaluate each general expression
in turn, and then return the last value calculated.
.br
.sp
The else-clause may begin with the keyword \fBelse\fP and be followed
by at least one general expression.
The rendition of this clause is just like that of a then-clause.
An else-clause
may begin alternatively with the keyword \fBelseif\fP, and be followed
(recursively) by a predicate, then-clause, and optional else-clause.
Evaluation of this clause, is just evaluation of an \fIif\fP-form, with
the same predicate, then- and else-clauses.
.Lf I-throw-err "'l_token"
.Wh
l_token is the \fIcdr\fP of the value returned from a \fI*catch\fP with
the tag ER%unwind-protect.
.Re
nothing (never returns in the current context)
.Se
The error or throw denoted by l_token is continued.
.No
This function is used to implement \fIunwind-protect\fP which allows the
processing of a transfer of control though a certain context to be
interrupted, a user function to be executed and than the transfer of
control to continue.
The form of l_token is either
.br
\fI(t tag value)\fP for a throw or
.br
\fI(nil type message valret contuab uniqueid [arg ...])\fP for an error.
.br
This function is not to be used for implementing throws or
errors and is only documented here for completeness.
.Lf let "l_args g_exp1 ... g_exprn"
.Re
the result of evaluating g_exprn within the bindings given by l_args.
.No
l_args is either nil (in which case 
.i let
is just like
.i progn )
or it is a list of binding objects.
A binding object is a list \fI(symbol\ expression)\fP.
When a 
.i let 
is entered all of the expressions are evaluated and then simultaneously
lambda bound to the corresponding symbols.
In effect, a 
.i let
expression is just like a lambda expression except the symbols and
their initial values are next to each other which makes the expression
easier to understand.
There are some added features to the 
.i let 
expression:
A binding object can just be a symbol, in which case the expression
corresponding to that symbol is `nil'.
If a binding object is a list and the first element of that list is
another list, then that list is assumed to be a binding template
and 
.i let
will do a 
.i desetq
on it.
.Lf let* "l_args g_exp1 ... g_expn"
.Re
the result of evaluating g_exprn within the bindings given by l_args.
.No
This is identical to 
.i let
except the expressions in the binding list l_args are evaluated
and bound sequentially instead of in parallel.
.Lf lexpr-funcall "'g_function ['g_arg1 ...] 'l_argn"
.No
This is a cross between funcall and apply.
The last argument, must be a list (possibly empty).
The element of list arg are stack and then the function is
funcalled.
.Ex
(lexpr-funcall 'list 'a '(b c d)) is the same as
 (funcall 'list 'a 'b 'c 'd)
.Lf listify "'x_count"
.Re
a list of x_count of the arguments to the current function (which
must be a lexpr).
.No
normally arguments 1 through x_count are returned. 
If x_count is negative then  a list of last abs(x_count) arguments are
returned.
.Lf map "'u_func 'l_arg1 ..."
.Re
l_arg1
.No
The function u_func is applied to successive sublists of the l_arg\fIi\fP.
All sublists should have the same length.  
.\".pg
.Lf mapc "'u_func 'l_arg1 ..."
.Re
l_arg1.
.No
The function u_func is applied to successive elements of the argument 
lists.
All of the lists should have the same length.
.Lf mapcan "'u_func 'l_arg1 ..."
.Re
nconc applied to the results of the functional evaluations.
.No
The function u_func is applied to successive elements of the 
argument lists.
All sublists should have the same length.
.Lf mapcar "'u_func 'l_arg1 ..."
.Re
a list of the values returned from the functional application.
.No
the function u_func is applied to successive elements of the
argument lists.
All sublists should have the same length.
.Lf mapcon "'u_func 'l_arg1 ..."
.Re
nconc applied to the results of the functional evaluation.
.No
the function u_func is applied to successive sublists of the
argument lists.
All sublists should have the same length.
.Lf maplist "'u_func 'l_arg1 ..."
.Re
a list of the results of the functional evaluations.
.No
the function u_func is applied to successive sublists of the arguments
lists.
All sublists should have the same length.
.lp
Readers may find the following summary table useful in remembering
the differences between the six mapping functions:

.TS
box;
c | c s s.
\	Value returned is

.T&
c | c c c.
T{
.na
Argument to functional is
.ad
T}	l_arg1	list of results	\fInconc\fP of results
_
.T&
c | c c c.

elements of list	mapc	mapcar	mapcan

sublists	map	maplist	mapcon
.TE
.sp 2v
.Lf mfunction "t_entry 's_disc"
.Re
a lisp object of type binary composed of t_entry and s_disc.
.No
t_entry is a pointer to the machine code for a function, and s_disc is the
discipline (e.g. lambda).
.\".pg
.Lf oblist
.Re
a list of all symbols on the oblist.
.Lf or "[g_arg1 ... ]"
.Re
the value of the first non-null argument  or nil if all arguments 
evaluate to nil.
.No
Evaluation proceeds left to right and stops as soon as one of the arguments
evaluates to a non-null value.
.Lf prog "l_vrbls g_exp1 ..."
.Re
the value explicitly given in a return form
or else nil if no return is done by the time the last g_exp\fIi\fP is
evaluated.
.No
the local variables are lambda bound to nil then the g_exp\fI\fP
are evaluated from left to right.
This is a prog body (obviously) and this means than 
any symbols seen are not evaluated,
instead they are treated as labels.
This also means that return's and go's are allowed.
.Lf prog1 "'g_exp1 ['g_exp2 ...]"
.Re
g_exp1
.Lf prog2 "'g_exp1 'g_exp2 ['g_exp3 ...]"
.Re
g_exp2
.No
the forms are evaluated from left to right and the value of g_exp2 is
returned.
.Lf progn "'g_exp1 ['g_exp2 ...]"
.Re
the last g_exp\fIi\fP.
.Lf progv "'l_locv 'l_initv g_exp1 ..."
.Wh
l_locv is a list of symbols and l_initv is a list of expressions.
.Re
the value of the last g_exp\fIi\fP evaluated.
.No
The expressions in l_initv are evaluated from left to right
and then lambda-bound to the symbols in l_locv.
If there are too few expressions in l_initv then the missing values
are assumed to be nil.
If there are too many expressions in l_initv then the extra ones are
ignored (although they are evaluated).
Then the g_exp\fIi\fP are evaluated left to right.
The body of a progv is like the body of a progn, it is 
.i not
a prog body.
(C.f. 
.i let )
.Lf purcopy "'g_exp"
.Re
a copy of g_exp with new pure cells allocated wherever possible.
.No
pure space is never swept up by the garbage collector, so this should
only be done on expressions which are not likely to become garbage
in the future.
In certain cases, data objects in pure space become read-only after
a 
.i dumplisp
and then an attempt to modify the object will result in an illegal memory
reference.
.Lf purep "'g_exp"
.Re
t iff the object g_exp is in pure space.
.Lf putd "'s_name 'u_func"
.Re
u_func
.Se
this sets the function binding of symbol s_name to u_func.
.Lf return "['g_val]"
.Re
g_val (or nil if g_val is not present) from the enclosing prog or do body.
.No
this form is only valid in the context of a prog or do body.
.Lf selectq "'g_key-form [l_clause1 ...]"
.No
This function is just like \fIcaseq\fP (see above), except that
the symbol \fBotherwise\fP has the same semantics as the
symbol \fBt\fP, when used as a comparator.
.Lf setarg "'x_argnum 'g_val"
.Wh
x_argnum is greater than zero and less than or equal to the number of
arguments to the lexpr.
.Re
g_val
.Se
the lexpr's x_argnum'th argument is set to g-val.
.No
this can only be used within the body of a lexpr.
.Lf throw "'g_val [s_tag]"
.Wh
if s_tag is not given, it is assumed to be nil.
.Re
the value of \fI(*throw 's_tag 'g_val)\fP.
.Lf *throw "'s_tag 'g_val"
.Re
g_val from the first enclosing catch with 
the tag s_tag or with no tag at all.
.No
this is used in conjunction with 
.i *catch
to cause a clean jump to an enclosing context.
.Lf unwind-protect "g_protected [g_cleanup1 ...]"
.Re
the result of evaluating g_protected.
.No
Normally g_protected is evaluated and its value
remembered, then the g_cleanup\fIi\fP
are evaluated and finally the saved value of g_protected is returned.
If something should happen when evaluating g_protected which causes
control to pass through g_protected  and thus through
the call to the unwind-protect,
then the g_cleanup\fIi\fP will still be evaluated.
This is useful if g_protected does  something sensitive which 
must be cleaned up whether or not g_protected completes.