% -*- Mode: TeX -*- % Control and Data flow % Functions % Variables % Control Transfer % Predicates and Truth Values % Truth Values % Identity/Equality % Functional Composition % Boolean Composition % Conditionals % Dispatch % Multiple Values % Data and Control % Setf %-------------------- Functions -------------------- %%% ========== APPLY % should this be an accessor rather than a function? --sjl 5 mar 92 \begincom{apply}\ftype{Function} %!!! This needs some careful review. -kmp 1-Sep-91 \label Syntax:: \DefunWithValues apply {function {\rest} \plus{args}} {\starparam{result}} \label Arguments and Values:: \issue{FUNCTION-TYPE:X3J13-MARCH-88} \param{function}---a \term{function designator}. \endissue{FUNCTION-TYPE:X3J13-MARCH-88} \param{args}---a \term{spreadable argument list designator}. %% 7.9.2 5 \param{results}---the \term{values} returned by \param{function}. \label Description:: %% 7.3.0 2 \term{Applies} the \param{function} to the \param{args}. %%This is implied by the use of "spreadable argument list designator" above. -kmp 15-Aug-91 % All but the last \param{arg} must be the % arguments taken by \param{function}. % The last \param{arg} supplied must be a \term{list} of such arguments. % % The argument list for \param{function} consists of the last \param{arg} supplied % appended to the end of a \term{list} of all the other \param{args}. \issue{REST-LIST-ALLOCATION:MAY-SHARE} When the \param{function} receives its arguments via \keyref{rest}, it is permissible (but not required) for the \term{implementation} to \term{bind} the \term{rest parameter} to an \term{object} that shares structure with the last argument to \funref{apply}. Because a \term{function} can neither detect whether it was called via \funref{apply} nor whether (if so) the last argument to \funref{apply} was a \term{constant}, \term{conforming programs} must neither rely on the \term{list} structure of a \term{rest list} to be freshly consed, nor modify that \term{list} structure. \endissue{REST-LIST-ALLOCATION:MAY-SHARE} \macref{setf} can be used with \funref{apply} in certain circumstances; \seesection\SETFofAPPLY. \label Examples:: \issue{REST-LIST-ALLOCATION:MAY-SHARE} \code (setq f '+) \EV + (apply f '(1 2)) \EV 3 (setq f #'-) \EV # (apply f '(1 2)) \EV -1 (apply #'max 3 5 '(2 7 3)) \EV 7 (apply 'cons '((+ 2 3) 4)) \EV ((+ 2 3) . 4) (apply #'+ '()) \EV 0 (defparameter *some-list* '(a b c)) (defun strange-test (&rest x) (eq x *some-list*)) (apply #'strange-test *some-list*) \EV \term{implementation-dependent} (defun bad-boy (&rest x) (rplacd x 'y)) (bad-boy 'a 'b 'c) has undefined consequences. (apply #'bad-boy *some-list*) has undefined consequences. \endcode \endissue{REST-LIST-ALLOCATION:MAY-SHARE} \code (defun foo (size &rest keys &key double &allow-other-keys) (let ((v (apply #'make-array size :allow-other-keys t keys))) (if double (concatenate (type-of v) v v) v))) (foo 4 :initial-contents '(a b c d) :double t) \EV #(A B C D A B C D) \endcode \label Affected By:\None. \label Exceptional Situations:\None. %!!! Barmar: "Last argument must be a list." \label See Also:: \funref{funcall}, \funref{fdefinition}, \specref{function}, {\secref\Evaluation}, {\secref\SETFofAPPLY} \label Notes:\None. \endcom %%% ========== DEFUN \begincom{defun}\ftype{Macro} \issue{DECLS-AND-DOC} \issue{FUNCTION-NAME:LARGE} \label Syntax:: \DefmacWithValuesNewline defun {function-name lambda-list {\DeclsAndDoc} \starparam{form}} {function-name} \label Arguments and Values:: \param{function-name}---a \term{function name}. % tweaked --sjl 5 Mar 92 %\param{lambda-list}---a \term{lambda list}. \param{lambda-list}---an \term{ordinary lambda list}. \param{declaration}---a \misc{declare} \term{expression}; \noeval. %% 5.3.1 3 \param{documentation}---a \term{string}; \noeval. %% 5.3.1 4 \param{forms}---an \term{implicit progn}. \param{block-name}---the \term{function block name} of the \param{function-name}. \label Description:: Defines a new \term{function} named \param{function-name} in the \term{global environment}. The body of the \term{function} defined by \macref{defun} consists of \param{forms}; they are executed as an \term{implicit progn} when the \term{function} is called. %% 5.3.1 6 \macref{defun} can be used to define a new \term{function}, to install a corrected version of an incorrect definition, to redefine an already-defined \term{function}, or to redefine a \term{macro} as a \term{function}. %% 5.3.1 5 %% 7.7.0 4 \macref{defun} implicitly puts a \specref{block} named \param{block-name} around the body \param{forms} \issue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS} (but not the \term{forms} in the \param{lambda-list}) \endissue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS} of the \term{function} defined. %% 5.3.1 3 \issue{DOCUMENTATION-FUNCTION-BUGS:FIX} \param{Documentation} is attached as a \term{documentation string} to \param{name} (as kind \specref{function}) and to the \term{function} \term{object}. \endissue{DOCUMENTATION-FUNCTION-BUGS:FIX} %% 5.3.1 2 Evaluating \macref{defun} causes \param{function-name} to be a global name for the \term{function} specified by the \term{lambda expression} \code (lambda \param{lambda-list} {\DeclsAndDoc} (block \param{block-name} \starparam{form})) \endcode processed in the \term{lexical environment} in which \macref{defun} was executed. (None of the arguments are evaluated at macro expansion time.) \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} \macref{defun} is not required to perform any compile-time side effects. In particular, \macref{defun} does not make the \term{function} definition available at compile time. An \term{implementation} may choose to store information about the \term{function} for the purposes of compile-time error-checking (such as checking the number of arguments on calls), or to enable the \term{function} to be expanded inline. \endissue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} \label Examples:: \code (defun recur (x) (when (> x 0) (recur (1- x)))) \EV RECUR (defun ex (a b &optional c (d 66) &rest keys &key test (start 0)) (list a b c d keys test start)) \EV EX (ex 1 2) \EV (1 2 NIL 66 NIL NIL 0) (ex 1 2 3 4 :test 'equal :start 50) \EV (1 2 3 4 (:TEST EQUAL :START 50) EQUAL 50) (ex :test 1 :start 2) \EV (:TEST 1 :START 2 NIL NIL 0) ;; This function assumes its callers have checked the types of the ;; arguments, and authorizes the compiler to build in that assumption. (defun discriminant (a b c) (declare (number a b c)) "Compute the discriminant for a quadratic equation." (- (* b b) (* 4 a c))) \EV DISCRIMINANT (discriminant 1 2/3 -2) \EV 76/9 ;; This function assumes its callers have not checked the types of the ;; arguments, and performs explicit type checks before making any assumptions. (defun careful-discriminant (a b c) "Compute the discriminant for a quadratic equation." (check-type a number) (check-type b number) (check-type c number) (locally (declare (number a b c)) (- (* b b) (* 4 a c)))) \EV CAREFUL-DISCRIMINANT (careful-discriminant 1 2/3 -2) \EV 76/9 \endcode \label Affected By:\None. \label Exceptional Situations:\None. % adequately addressed in the packages chapter. --sjl 5 mar 92 % \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} % For each \i{S} that is a \term{symbol} in \thepackage{common-lisp}, % the consequences are undefined if either \i{S} or \f{(setf \i{S})} % is used as the \param{function-name}. % \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} \label See Also:: \specref{flet}, \specref{labels}, \specref{block}, \specref{return-from}, \misc{declare}, \funref{documentation}, {\secref\Evaluation}, {\secref\OrdinaryLambdaLists}, {\secref\DocVsDecls} \label Notes:: %% 5.3.1 5 \specref{return-from} can be used to return prematurely from a \term{function} defined by \macref{defun}. Additional side effects might take place when additional information (typically debugging information) about the function definition is recorded. \endissue{FUNCTION-NAME:LARGE} \endissue{DECLS-AND-DOC} \endcom %%% ========== FDEFINITION \begincom{fdefinition}\ftype{Accessor} \issue{FUNCTION-NAME:LARGE} \label Syntax:: \DefunWithValues fdefinition {function-name} {definition} \Defsetf fdefinition {function-name} {new-definition} \label Arguments and Values:: \param{function-name}---a \term{function name}. \issue{FUNCTION-TYPE:X3J13-MARCH-88} In the non-\macref{setf} case, the \term{name} must be \term{fbound} in the \term{global environment}. \endissue{FUNCTION-TYPE:X3J13-MARCH-88} \param{definition}---Current global function definition named by \param{function-name}. \param{new-definition}---a \term{function}. \label Description:: \funref{fdefinition} \term{accesses} the current global function definition named by \param{function-name}. The definition may be a \term{function} or may be an \term{object} representing a \term{special form} or \term{macro}. \issue{FUNCTION-TYPE:X3J13-MARCH-88} The value returned by \funref{fdefinition} when \funref{fboundp} returns true but the \param{function-name} denotes a \term{macro} or \term{special form} is not well-defined, but \funref{fdefinition} does not signal an error. \endissue{FUNCTION-TYPE:X3J13-MARCH-88} \label Examples:\None. \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:: \Shouldchecktype{function-name}{a \term{function name}} An error \oftype{undefined-function} is signaled in the non-\macref{setf} case if \param{function-name} is not \term{fbound}. \label See Also:: \funref{fboundp}, \funref{fmakunbound}, \funref{macro-function}, \issue{SPECIAL-FORM-P-MISNOMER:RENAME} \funref{special-operator-p}, \endissue{SPECIAL-FORM-P-MISNOMER:RENAME} \funref{symbol-function} \label Notes:: \funref{fdefinition} cannot \term{access} the value of a lexical function name produced by \specref{flet} or \specref{labels}; it can \term{access} only the global function value. \macref{setf} can be used with \funref{fdefinition} to replace a global function definition when the \param{function-name}'s function definition does not represent a \term{special form}. \issue{FUNCTION-TYPE:X3J13-MARCH-88} \macref{setf} of \funref{fdefinition} requires a \term{function} as the new value. It is an error to set the \funref{fdefinition} of a \param{function-name} to a \term{symbol}, a \term{list}, or the value returned by \funref{fdefinition} on the name of a \term{macro} or \term{special form}. \endissue{FUNCTION-TYPE:X3J13-MARCH-88} \endissue{FUNCTION-NAME:LARGE} \endcom %%% ========== FBOUNDP \begincom{fboundp}\ftype{Function} \label Syntax:: \DefunWithValues fboundp {name} {generalized-boolean} \label Pronunciation:: \pronounced{\stress{ef}\Stress{ba\.und}p\harde} \label Arguments and Values:: \issue{FUNCTION-NAME:LARGE} \param{name}---a \term{function name}. \endissue{FUNCTION-NAME:LARGE} \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: %% 7.1.1 20 \Predicate{name}{\term{fbound}} \label Examples:: %Some "implementation dependent" => "true" per Moore #2 (first public review). -kmp 12-May-93 \code (fboundp 'car) \EV \term{true} (fboundp 'nth-value) \EV \term{false} (fboundp 'with-open-file) \EV \term{true} (fboundp 'unwind-protect) \EV \term{true} (defun my-function (x) x) \EV MY-FUNCTION (fboundp 'my-function) \EV \term{true} (let ((saved-definition (symbol-function 'my-function))) (unwind-protect (progn (fmakunbound 'my-function) (fboundp 'my-function)) (setf (symbol-function 'my-function) saved-definition))) \EV \term{false} (fboundp 'my-function) \EV \term{true} (defmacro my-macro (x) `',x) \EV MY-MACRO (fboundp 'my-macro) \EV \term{true} (fmakunbound 'my-function) \EV MY-FUNCTION (fboundp 'my-function) \EV \term{false} (flet ((my-function (x) x)) (fboundp 'my-function)) \EV \term{false} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:: \Shouldchecktype{name}{a \term{function name}} \label See Also:: \funref{symbol-function}, \funref{fmakunbound}, \funref{fdefinition} \label Notes:: It is permissible to call \funref{symbol-function} on any \term{symbol} that is \term{fbound}. \funref{fboundp} is sometimes used to ``guard'' an access to the \term{function cell}, as in: \code (if (fboundp x) (symbol-function x)) \endcode \issue{SETF-FUNCTIONS-AGAIN:MINIMAL-CHANGES} Defining a \term{setf expander} \param{F} does not cause the \term{setf function} \f{(setf \param{F})} to become defined. %% Moon wanted this removed because he thinks it is "redundant and pompous". -kmp 4-Dec-91 % as such, if there is such a definition % of a \term{setf expander} \param{F}, the \term{function} \f{(setf \param{F})} % can be \term{fbound} if and only if, by design or coincidence, a % function binding for \f{(setf \param{F})} has been independently established. \endissue{SETF-FUNCTIONS-AGAIN:MINIMAL-CHANGES} \endcom %%% ========== FMAKUNBOUND \begincom{fmakunbound}\ftype{Function} \label Syntax:: \DefunWithValues fmakunbound {name} {name} \label Pronunciation:: \pronounced{\stress{ef}\Stress{mak}\schwa n\stress{ba\.und}} or \pronounced{\stress{ef}\Stress{m\harda k}\schwa n\stress{ba\.und}} \label Arguments and Values:: \issue{FUNCTION-NAME:LARGE} \param{name}---a \term{function name}. \endissue{FUNCTION-NAME:LARGE} \label Description:: Removes the \term{function} or \term{macro} definition, if any, of \param{name} in the \term{global environment}. \label Examples:: \code (defun add-some (x) (+ x 19)) \EV ADD-SOME (fboundp 'add-some) \EV \term{true} (flet ((add-some (x) (+ x 37))) (fmakunbound 'add-some) (add-some 1)) \EV 38 (fboundp 'add-some) \EV \term{false} \endcode \label Side Effects:\None. % I see no symbol here. --sjl 5 Mar 92 %The \term{function cell} of \param{symbol} is modified. \label Affected By:\None. \label Exceptional Situations:: \Shouldchecktype{name}{a \term{function name}} The consequences are undefined if \param{name} is a \term{special operator}. \label See Also:: \funref{fboundp}, \funref{makunbound} \label Notes:\None. \endcom %%% ========== FLET %%% ========== LABELS %%% ========== MACROLET \begincom{flet, labels, macrolet}\ftype{Special Operator} \issue{DECLS-AND-DOC} \label Syntax:: \issue{FLET-DECLARATIONS:ALLOW} \DefspecWithValuesNewline flet {\vtop{\hbox{\paren{\starparen{\param{function-name} \param{lambda-list} {\LocalDeclsAndDoc} \starparam{local-form}}}} \hbox{\starparam{declaration} \starparam{form}}}} {\starparam{result}} \DefspecWithValuesNewline labels {\vtop{\hbox{\paren{\starparen{\param{function-name} \param{lambda-list} {\LocalDeclsAndDoc} \starparam{local-form}}}} \hbox{\starparam{declaration} \starparam{form}}}} {\starparam{result}} \DefspecWithValuesNewline macrolet {\vtop{\hbox{\paren{\starparen{\param{name} \param{lambda-list} {\LocalDeclsAndDoc} \starparam{local-form}}}} \hbox{\starparam{declaration} \starparam{form}}}} {\starparam{result}} \endissue{FLET-DECLARATIONS:ALLOW} \label Arguments and Values:: \issue{FUNCTION-NAME:LARGE} \param{function-name}---a \term{function name}. \endissue{FUNCTION-NAME:LARGE} \param{name}---a \term{symbol}. %name of the \term{macro} being defined. \param{lambda-list}---a \term{lambda list}; for \specref{flet} and \specref{labels}, it is an \term{ordinary lambda list}; for \specref{macrolet}, it is a \term{macro lambda list}. \param{local-declaration}---a \misc{declare} \term{expression}; \noeval. \param{declaration}---a \misc{declare} \term{expression}; \noeval. \param{local-documentation}---a \term{string}; \noeval. \param{local-forms}, \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} of the \param{forms}. \label Description:: \specref{flet}, \specref{labels}, and \specref{macrolet} define local \term{functions} and \term{macros}, and execute \param{forms} using the local definitions. \param{Forms} are executed in order of occurrence. \issue{FLET-IMPLICIT-BLOCK:YES} \issue{FUNCTION-NAME:LARGE} \issue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS} The body forms (but not the \term{lambda list}) \endissue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS} of each \term{function} created by \specref{flet} and \specref{labels} and each \term{macro} created by \specref{macrolet} are enclosed in an \term{implicit block} whose name is the \term{function block name} of the \param{function-name} or \param{name}, as appropriate. \endissue{FUNCTION-NAME:LARGE} \endissue{FLET-IMPLICIT-BLOCK:YES} \issue{FLET-DECLARATIONS} The scope of the \param{declarations} between the list of local function/macro definitions and the body \param{forms} in \specref{flet} and \specref{labels} does not include the bodies of the locally defined \term{functions}, except that for \specref{labels}, any \declref{inline}, \declref{notinline}, or \declref{ftype} declarations that refer to the locally defined functions do apply to the local function bodies. That is, their \term{scope} is the same as the function name that they affect. \issue{DECLARATION-SCOPE:NO-HOISTING} %The following will be deleted from the standard: % %when the \param{declarations} %are \term{pervasive}. Non-\term{pervasive} %\param{declarations} have no effect on those bodies, except when %\specref{labels} includes the %body in the \term{scope} of a function non-\term{pervasively} declared. % %End of deletion. \endissue{DECLARATION-SCOPE:NO-HOISTING} The scope of these \param{declarations} does not include the bodies of the macro expander functions defined by \specref{macrolet}. \endissue{FLET-DECLARATIONS} % This is adequately covered in the packages chapter. --sjl 5 mar 92 %\issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} %The consequences are undefined if a \term{symbol} in \thepackage{common-lisp} %that is defined as a \term{function}, \term{macro}, or \term{special form} %is used as the function-name or name argument. %If such a \term{symbol} is not defined as a \term{function}, \term{macro}, or %\term{special form}, it is allowed to (lexically) bind it as a \term{function} %or \term{macro}. %\endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} \beginlist \itemitem{\bf flet} %% 7.5.0 17 \specref{flet} defines locally named \term{functions} and executes a series of \param{forms} with these definition \term{bindings}. Any number of such local \term{functions} can be defined. The \term{scope} of the name \term{binding} encompasses only the body. Within the body of \specref{flet}, \param{function-names} matching those defined by \specref{flet} refer to the locally defined \term{functions} rather than to the global function definitions of the same name. \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} Also, within the scope of \specref{flet}, global \term{setf expander} definitions of the \param{function-name} defined by \specref{flet} do not apply. %% This shouldn't be needed any more under SETF-METHOD-VS-SETF-METHOD. %!!! Issue: (defun (setf x) ...) vs (defmethod (setf x) ...) is really the issue, isn't it? Note that this applies to {\tt (defsetf \i{f} ...)}, not {\tt (defmethod (setf \i{f}) ...)}. \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} The names of \term{functions} defined by \specref{flet} are in the \term{lexical environment}; they retain their local definitions only within the body of \specref{flet}. The function definition bindings are visible only in the body of \specref{flet}, not the definitions themselves. Within the function definitions, local function names that match those being defined refer to \term{functions} or \term{macros} defined outside the \specref{flet}. \specref{flet} can locally \term{shadow} a global function name, and the new definition can refer to the global definition. Any \param{local-documentation} is attached to the corresponding local \param{function} (if one is actually created) as a \term{documentation string}. \itemitem{\bf labels} %% 7.5.0 18 \specref{labels} is equivalent to \specref{flet} except that the scope of the defined function names for \specref{labels} encompasses the function definitions themselves as well as the body. % That is, within the body of \specref{labels}, % \param{function-names} matching those defined by \specref{labels} % refer to the locally defined \term{functions} % rather than to % the global function definitions of the same name. %!!! FLET duplicates this same text. Is there a way to centralize it? \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} %% Moon says this is "redundant and confusing"--presumably because it's %% already said under FLET, which LABELS purports to be equivalent to. -kmp 4-Dec-91 % Within the scope of \specref{labels}, % any global \term{setf expander} definitions whose names are among the \param{function-names} % are lexically disabled. %% This shouldn't be needed under SETF-METHOD-VS-SETF-METHOD % Note that this applies to {\tt (defsetf \i{f} ...)}, not % {\tt (defmethod (setf \i{f}) ...)}. \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \itemitem{\bf macrolet} %% 7.5.0 19 \specref{macrolet} %is different from \specref{flet} in that it establishes local \term{macro} definitions, using the same format used by \macref{defmacro}. %!!! Duplicated in FLET and LABELS. Centralize? -kmp 8-May-91 \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} % We haven't defined what the scope is yet. --sjl 5 mar 92 %Within the scope of \specref{macrolet}, Within the body of \specref{macrolet}, global \term{setf expander} definitions of the \param{names} defined by the \specref{macrolet} do not apply; rather, \macref{setf} expands the \term{macro form} and recursively process the resulting \term{form}. %!!! See note above about (defun (setf x) ...) ... % Note that this applies to {\tt (defsetf \i{f} ...)}, not % {\tt (defmethod (setf \i{f}) ...)}. \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} %!!! Barmar: Mention that macros are expadned at semantic analysis time % so even global varaible references must be to variables gieven values at compile time. %% 7.5.0 20 The macro-expansion functions defined by \specref{macrolet} are defined in the \issue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} \term{lexical environment} in which the \specref{macrolet} form appears. %global environment. Declarations and \specref{macrolet} and \specref{symbol-macrolet} definitions affect the local macro definitions in a \specref{macrolet}, but the consequences are undefined if the local macro definitions reference any local \term{variable} or \term{function} \term{bindings} that are visible in that \term{lexical environment}. %Lexical entities that would ordinarily be lexically apparent %are not visible within the expansion functions. However, %lexical entities are visible %within the body of the \specref{macrolet} form and are visible %to the code that is the expansion of a macro call. \endissue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} Any \param{local-documentation} is attached to the corresponding local \param{macro function} as a \term{documentation string}. \endlist \label Examples:: \code (defun foo (x flag) (macrolet ((fudge (z) ;The parameters x and flag are not accessible ; at this point; a reference to flag would be to ; the global variable of that name. \bq\ (if flag (* ,z ,z) ,z))) ;The parameters x and flag are accessible here. (+ x (fudge x) (fudge (+ x 1))))) \EQ (defun foo (x flag) (+ x (if flag (* x x) x) (if flag (* (+ x 1) (+ x 1)) (+ x 1)))) \endcode after macro expansion. The occurrences of \f{x} and \f{flag} legitimately refer to the parameters of the function \f{foo} because those parameters are visible at the site of the macro call which produced the expansion. \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} %Barmar points out that this example violated LISP-SYMBOL-REDEFINITION: % \code % (flet ((+ (&rest args) 'crossed-out)) (+ 1 2 3)) \EV CROSSED-OUT % \endcode \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} \code (flet ((flet1 (n) (+ n n))) (flet ((flet1 (n) (+ 2 (flet1 n)))) (flet1 2))) \EV 6 (defun dummy-function () 'top-level) \EV DUMMY-FUNCTION (funcall #'dummy-function) \EV TOP-LEVEL (flet ((dummy-function () 'shadow)) (funcall #'dummy-function)) \EV SHADOW (eq (funcall #'dummy-function) (funcall 'dummy-function)) \EV \term{true} (flet ((dummy-function () 'shadow)) (eq (funcall #'dummy-function) (funcall 'dummy-function))) \EV \term{false} (defun recursive-times (k n) (labels ((temp (n) (if (zerop n) 0 (+ k (temp (1- n)))))) (temp n))) \EV RECURSIVE-TIMES (recursive-times 2 3) \EV 6 (defmacro mlets (x &environment env) (let ((form `(babbit ,x))) (macroexpand form env))) \EV MLETS (macrolet ((babbit (z) `(+ ,z ,z))) (mlets 5)) \EV 10 \endcode \code (flet ((safesqrt (x) (sqrt (abs x)))) ;; The safesqrt function is used in two places. (safesqrt (apply #'+ (map 'list #'safesqrt '(1 2 3 4 5 6))))) \EV 3.291173 \endcode \code (defun integer-power (n k) (declare (integer n)) (declare (type (integer 0 *) k)) (labels ((expt0 (x k a) (declare (integer x a) (type (integer 0 *) k)) (cond ((zerop k) a) ((evenp k) (expt1 (* x x) (floor k 2) a)) (t (expt0 (* x x) (floor k 2) (* x a))))) (expt1 (x k a) (declare (integer x a) (type (integer 0 *) k)) (cond ((evenp k) (expt1 (* x x) (floor k 2) a)) (t (expt0 (* x x) (floor k 2) (* x a)))))) (expt0 n k 1))) \EV INTEGER-POWER \endcode \issue{FLET-DECLARATIONS} \code (defun example (y l) (flet ((attach (x) (setq l (append l (list x))))) (declare (inline attach)) (dolist (x y) (unless (null (cdr x)) (attach x))) l)) (example '((a apple apricot) (b banana) (c cherry) (d) (e)) '((1) (2) (3) (4 2) (5) (6 3 2))) \EV ((1) (2) (3) (4 2) (5) (6 3 2) (A APPLE APRICOT) (B BANANA) (C CHERRY)) \endcode \endissue{FLET-DECLARATIONS} \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \misc{declare}, \macref{defmacro}, \macref{defun}, \funref{documentation}, \macref{let}, {\secref\Evaluation}, {\secref\DocVsDecls} \label Notes:: It is not possible to define recursive \term{functions} with \specref{flet}. \specref{labels} can be used to define mutually recursive \term{functions}. If a \specref{macrolet} \term{form} is a \term{top level form}, the body \param{forms} are also processed as \term{top level forms}. \Seesection\FileCompilation. \endissue{DECLS-AND-DOC} \endcom %%% ========== FUNCALL \begincom{funcall}\ftype{Function} \label Syntax:: \DefunWithValues funcall {function {\rest} args} {\starparam{result}} \label Arguments and Values:: \param{function}---a \term{function designator}. \param{args}---\term{arguments} to the \param{function}. %% 7.9.2 5 \param{results}---the \term{values} returned by the \param{function}. \label Description:: %% 7.3.0 3 \funref{funcall} applies \param{function} to \param{args}. \issue{FUNCTION-TYPE:X3J13-MARCH-88} %!!! Barmar: "a symbol" => "a function name" If \param{function} is a \term{symbol}, it is coerced to a \term{function} as if by %!!! Barmar: => "... as if fdefinition." finding its \term{functional value} in the \term{global environment}. \endissue{FUNCTION-TYPE:X3J13-MARCH-88} \label Examples:: \code (funcall #'+ 1 2 3) \EV 6 (funcall 'car '(1 2 3)) \EV 1 (funcall 'position 1 '(1 2 3 2 1) :start 1) \EV 4 (cons 1 2) \EV (1 . 2) (flet ((cons (x y) `(kons ,x ,y))) (let ((cons (symbol-function '+))) (funcall #'cons (funcall 'cons 1 2) (funcall cons 1 2)))) \EV (KONS (1 . 2) 3) \endcode \label Affected By:\None. \label Exceptional Situations:: An error \oftype{undefined-function} should be signaled if \param{function} is a \term{symbol} that does not have a global definition as a \term{function} or that has a global definition as a \term{macro} or a \term{special operator}. \label See Also:: \funref{apply}, \specref{function}, {\secref\Evaluation} \label Notes:: \code (funcall \param{function} \param{arg1} \param{arg2} ...) \EQ (apply \param{function} \param{arg1} \param{arg2} ... nil) \EQ (apply \param{function} (list \param{arg1} \param{arg2} ...)) \endcode The difference between \funref{funcall} and an ordinary function call is that in the former case the \param{function} is obtained by ordinary \term{evaluation} of a \term{form}, and in the latter case it is obtained by the special interpretation of the function position that normally occurs. \endcom %%% ========== FUNCTION \begincom{function}\ftype{Special Operator} % What about these? % #'#.#'car % (#.#'car '(x)) % -kmp 24-Apr-91 \issue{FUNCTION-NAME:LARGE} \label Syntax:: \DefspecWithValues function {name} {function} \label Arguments and Values:: \param{name}---a \term{function name} or \term{lambda expression}. %% 2.13.0 5 \param{function}---a \term{function} \term{object}. \label Description:: %% 7.1.1 4 The \term{value} of \specref{function} is the \term{functional value} of \param{name} in the current \term{lexical environment}. If \param{name} is a \term{function name}, the functional definition of that name %which is that is that %!!! Must be a better way to say this! -kmp % Yup. -- sjl 5 Mar 92 established by the innermost lexically enclosing \specref{flet}, \specref{labels}, or \specref{macrolet} \term{form}, %if there is one, or else the global functional definition of the \term{symbol} if there is one. Otherwise the global functional definition of the \term{function name} is returned. If \param{name} is a \term{lambda expression}, then a \term{lexical closure} is returned. In situations where a \term{closure} over the same set of \term{bindings} might be produced more than once, the various resulting \term{closures} might or might not be \funref{eq}. \issue{FUNCTION-TYPE:X3J13-MARCH-88} It is an error to use \specref{function} on a \term{function name} that does not denote a \term{function} in the lexical environment in which the \specref{function} form appears. Specifically, it is an error to use \specref{function} on a \term{symbol} that denotes a \term{macro} or \term{special form}. An implementation may choose not to signal this error for performance reasons, but implementations are forbidden from defining the failure to signal an error as a useful behavior. \endissue{FUNCTION-TYPE:X3J13-MARCH-88} \label Examples:: \code (defun adder (x) (function (lambda (y) (+ x y)))) \endcode The result of \f{(adder 3)} is a function that adds \f{3} to its argument: \code (setq add3 (adder 3)) (funcall add3 5) \EV 8 \endcode This works because \specref{function} creates a \term{closure} of the \term{lambda expression} that is able to refer to the \term{value} \f{3} of the variable \f{x} even after control has returned from the function \f{adder}. \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. %!!! Moon: Perhaps "should signal" undefined-function and/or type-error. \label See Also:: \macref{defun}, \funref{fdefinition}, \specref{flet}, \specref{labels}, \funref{symbol-function}, {\secref\SymbolsAsForms}, {\secref\SharpsignQuote}, {\secref\PrintingOtherObjects} \label Notes:: The notation {\tt \#'\param{name}} may be used as an abbreviation for {\tt (function \param{name})}. \endissue{FUNCTION-NAME:LARGE} \endcom %%% ========== FUNCTION-LAMBDA-EXPRESSION \begincom{function-lambda-expression}\ftype{Function} \issue{FUNCTION-DEFINITION:JAN89-X3J13} \label Syntax:: \DefunWithValuesNewline function-lambda-expression {function} {lambda-expression, closure-p, name} \label Arguments and Values:: \param{function}---a \term{function}. \param{lambda-expression}---a \term{lambda expression} or \nil. \param{closure-p}---a \term{generalized boolean}. \param{name}---an \term{object}. \label Description:: Returns information about \param{function} as follows: The \term{primary value}, \param{lambda-expression}, is \param{function}'s defining \term{lambda expression}, or \nil\ if the information is not available. The \term{lambda expression} may have been pre-processed in some ways, but it should remain a suitable argument to \funref{compile} or \specref{function}. Any \term{implementation} may legitimately return \nil\ as the \param{lambda-expression} of any \param{function}. The \term{secondary value}, \param{closure-p}, is \nil\ if \param{function}'s definition was enclosed in the \term{null lexical environment} or something \term{non-nil} if \param{function}'s definition might have been enclosed in some \term{non-null lexical environment}. Any \term{implementation} may legitimately return \term{true} as the \param{closure-p} of any \param{function}. The \term{tertiary value}, \param{name}, is the ``name'' of \param{function}. The name is intended for debugging only and is not necessarily one that would be valid for use as a name in \macref{defun} or \specref{function}, for example. By convention, \nil\ is used to mean that \param{function} has no name. Any \term{implementation} may legitimately return \nil\ as the \param{name} of any \param{function}. \label Examples:: The following examples illustrate some possible return values, but are not intended to be exhaustive: \code (function-lambda-expression #'(lambda (x) x)) \EV NIL, \term{false}, NIL \OV NIL, \term{true}, NIL \OV (LAMBDA (X) X), \term{true}, NIL \OV (LAMBDA (X) X), \term{false}, NIL (function-lambda-expression (funcall #'(lambda () #'(lambda (x) x)))) \EV NIL, \term{false}, NIL \OV NIL, \term{true}, NIL \OV (LAMBDA (X) X), \term{true}, NIL \OV (LAMBDA (X) X), \term{false}, NIL (function-lambda-expression (funcall #'(lambda (x) #'(lambda () x)) nil)) \EV NIL, \term{true}, NIL \OV (LAMBDA () X), \term{true}, NIL \NV NIL, \term{false}, NIL \NV (LAMBDA () X), \term{false}, NIL (flet ((foo (x) x)) (setf (symbol-function 'bar) #'foo) (function-lambda-expression #'bar)) \EV NIL, \term{false}, NIL \OV NIL, \term{true}, NIL \OV (LAMBDA (X) (BLOCK FOO X)), \term{true}, NIL \OV (LAMBDA (X) (BLOCK FOO X)), \term{false}, FOO \OV (SI::BLOCK-LAMBDA FOO (X) X), \term{false}, FOO (defun foo () (flet ((bar (x) x)) #'bar)) (function-lambda-expression (foo)) \EV NIL, \term{false}, NIL \OV NIL, \term{true}, NIL \OV (LAMBDA (X) (BLOCK BAR X)), \term{true}, NIL \OV (LAMBDA (X) (BLOCK BAR X)), \term{true}, (:INTERNAL FOO 0 BAR) \OV (LAMBDA (X) (BLOCK BAR X)), \term{false}, "BAR in FOO" \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:\None. \label Notes:: Although \term{implementations} are free to return ``\nil, \term{true}, \nil'' in all cases, they are encouraged to return a \term{lambda expression} as the \term{primary value} in the case where the argument was created by a call to \funref{compile} or \funref{eval} (as opposed to being created by \term{loading} a \term{compiled file}). \endissue{FUNCTION-DEFINITION:JAN89-X3J13} \endcom %%% ========== FUNCTIONP \begincom{functionp}\ftype{Function} \issue{FUNCTION-TYPE:X3J13-MARCH-88} \label Syntax:: \DefunWithValues functionp {object} {generalized-boolean} \label Arguments and Values:: \param{object}---an \term{object}. \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: \TypePredicate{object}{function} %% 6.2.2 26 %% 6.2.2 27 % These are overridden by FUNCTION-TYPE:X3J13-MARCH-88. \label Examples:: \code (functionp 'append) \EV \term{false} (functionp #'append) \EV \term{true} (functionp (symbol-function 'append)) \EV \term{true} (flet ((f () 1)) (functionp #'f)) \EV \term{true} (functionp (compile nil '(lambda () 259))) \EV \term{true} (functionp nil) \EV \term{false} (functionp 12) \EV \term{false} (functionp '(lambda (x) (* x x))) \EV \term{false} (functionp #'(lambda (x) (* x x))) \EV \term{true} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None! \label See Also:\None. \label Notes:: \code (functionp \param{object}) \EQ (typep \param{object} 'function) \endcode \endissue{FUNCTION-TYPE:X3J13-MARCH-88} \endcom %%% ========== COMPILED-FUNCTION-P \begincom{compiled-function-p}\ftype{Function} \label Syntax:: \DefunWithValues compiled-function-p {object} {generalized-boolean} \label Arguments and Values:: \param{object}---an \term{object}. \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: %% 6.2.2 28 \TypePredicate{object}{compiled-function} \label Examples:: \code (defun f (x) x) \EV F (compiled-function-p #'f) \EV \term{false} \OV \term{true} (compiled-function-p 'f) \EV \term{false} (compile 'f) \EV F (compiled-function-p #'f) \EV \term{true} (compiled-function-p 'f) \EV \term{false} (compiled-function-p (compile nil '(lambda (x) x))) \EV \term{true} (compiled-function-p #'(lambda (x) x)) \EV \term{false} \OV \term{true} (compiled-function-p '(lambda (x) x)) \EV \term{false} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None! \label See Also:: \funref{compile}, \funref{compile-file}, \funref{compiled-function} \label Notes:: \code (compiled-function-p \param{object}) \EQ (typep \param{object} 'compiled-function) \endcode \endcom %%% ========== CALL-ARGUMENTS-LIMIT \begincom{call-arguments-limit}\ftype{Constant Variable} \label Constant Value:: An integer not smaller than \f{50} and at least as great as the \term{value} of \conref{lambda-parameters-limit}, the exact magnitude of which is \term{implementation-dependent}. \label Description:: %% 7.3.0 7 The upper exclusive bound on the number of \term{arguments} that may be passed to a \term{function}. \label Examples:\None. \label See Also:: \conref{lambda-parameters-limit}, \conref{multiple-values-limit} \label Notes:\None. \endcom %%% ========== LAMBDA-LIST-KEYWORDS \begincom{lambda-list-keywords}\ftype{Constant Variable} \label Constant Value:: a \term{list}, the \term{elements} of which are \term{implementation-dependent}, but which must contain at least the \term{symbols} \keyref{allow-other-keys}, \keyref{aux}, \keyref{body}, \keyref{environment}, \keyref{key}, \keyref{optional}, \keyref{rest}, and \keyref{whole}. \label Description:: %% 5.2.2 27 A \term{list} of all the \term{lambda list keywords} used in the \term{implementation}, including the additional ones used only by \term{macro} definition \term{forms}. \label Examples:\None. \label See Also:: \macref{defun}, \specref{flet}, \macref{defmacro}, \specref{macrolet}, {\secref\EvaluationModel} \label Notes:\None. \endcom %%% ========== LAMBDA-PARAMETERS-LIMIT \begincom{lambda-parameters-limit}\ftype{Constant Variable} \label Constant Value:: \term{implementation-dependent}, but not smaller than \f{50}. \label Description:: %% 5.2.2 29 A positive \term{integer} that is the upper exclusive bound on the number of \term{parameter} \term{names} that can appear in a single \term{lambda list}. \label Examples:\None. \label See Also:: \conref{call-arguments-limit} \label Notes:: Implementors are encouraged to make the \term{value} of \conref{lambda-parameters-limit} as large as possible. \endcom %-------------------- Variables -------------------- %%% ========== DEFCONSTANT \begincom{defconstant}\ftype{Macro} \label Syntax:: %% 5.3.2 14 \DefmacWithValues defconstant {name initial-value \brac{documentation}} {name} \label Arguments and Values:: \param{name}---a \term{symbol}; \noeval. \param{initial-value}---a \term{form}; \eval. %% 5.3.2 10 \issue{DEFVAR-DOCUMENTATION:UNEVALUATED} \param{documentation}---a \term{string}; \noeval. \endissue{DEFVAR-DOCUMENTATION:UNEVALUATED} \label Description:: %% 5.3.2 7 \macref{defconstant} %!!! KMP: Maybe use "establishes" here somewhere? causes the global variable named by \param{name} to be given a value that is the result of evaluating \param{initial-value}. %Once \param{name} has been defined using \macref{defconstant}, its value %is constant and cannot be changed by assignment or \term{binding}. %% 5.1.2 6 A constant defined by \macref{defconstant} can be redefined with \macref{defconstant}. %This sentence added per Barmar: -kmp 28-Dec-90 However, the consequences are undefined if an attempt is made to assign a \term{value} to the \term{symbol} using another operator, or to assign it to a \term{different} %%I gave different a formal meaning the same as non-EQL. -kmp 1-Jan-91 % (non-\funref{eql}) \term{value} using a subsequent \macref{defconstant}. If \param{documentation} is supplied, it is attached to \param{name} as a \term{documentation string} of kind \misc{variable}. \issue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} \macref{defconstant} normally appears as a \term{top level form}, but it is meaningful for it to appear as a \term{non-top-level form}. However, the compile-time side effects described below only take place when \macref{defconstant} appears as a \term{top level form}. \endissue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} %% 5.3.2 8 The consequences are undefined if there are any \term{bindings} of the variable named by \param{name} at the time \macref{defconstant} is executed or if the value is not \funref{eql} to the value of \param{initial-value}. %%% 5.3.2 9 %Once \param{name} has been declared by \macref{defconstant} to be constant, %the consequences are undefined if any further assignment to or \term{binding} %of \param{name} is attempted. \issue{DEFCONSTANT-SPECIAL:NO} The consequences are undefined when constant \term{symbols} are rebound as either lexical or dynamic variables. In other words, a reference to a \term{symbol} declared with \macref{defconstant} always refers to its global value. \endissue{DEFCONSTANT-SPECIAL:NO} The side effects of the execution of \macref{defconstant} must be equivalent to at least the side effects of the execution of the following code: % We explicitly addressed the question of whether DEFCONSTANT must % proclaim the variable SPECIAL in issue DEFCONSTANT-SPECIAL; the final % decision was that it might or might not. Including such a proclamation % here as required behavior is incorrect. --sjl 5 Mar 92 % \code % (declaim (special \i{name})) % (setf (symbol-value '\i{name}) \i{initial-value}) % (setf (documentation '\i{name} 'variable) '\i{documentation}) % \endcode \code (setf (symbol-value '\i{name}) \i{initial-value}) (setf (documentation '\i{name} 'variable) '\i{documentation}) \endcode \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} % added qualification about top-level-ness --sjl 5 Mar 92 If a \macref{defconstant} \term{form} appears as a \term{top level form}, the \term{compiler} must recognize that \param{name} names a \term{constant variable}. An implementation may choose to evaluate the value-form at compile time, load time, or both. Therefore, users must ensure that the \param{initial-value} can be \term{evaluated} at compile time (regardless of whether or not references to \param{name} appear in the file) and that it always \term{evaluates} to the same value. \endissue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} \editornote{KMP: Does ``same value'' here mean eql or similar?} \reviewer{Moon: Probably depends on whether load time is compared to compile time, or two compiles.} % Removed redundant text. --sjl 5 Mar 92 % Names of \term{constant variables} defined by \macref{defconstant} % become reserved and may not be further assigned to or bound (although % they may be redefined by using \macref{defconstant}). \label Examples:: \code (defconstant this-is-a-constant 'never-changing "for a test") \EV THIS-IS-A-CONSTANT this-is-a-constant \EV NEVER-CHANGING (documentation 'this-is-a-constant 'variable) \EV "for a test" (constantp 'this-is-a-constant) \EV \term{true} \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \funref{declaim}, \macref{defparameter}, \macref{defvar}, \funref{documentation}, \funref{proclaim}, {\secref\ConstantVars}, {\secref\Compilation} \label Notes:\None. \endcom %%% ========== DEFVAR %%% ========== DEFPARAMETER \begincom{defparameter, defvar}\ftype{Macro} \label Syntax:: \DefmacWithValues defparameter {name initial-value \brac{documentation} } {name} \DefmacWithValues defvar {name \ttbrac{initial-value \brac{documentation}}} {name} \label Arguments and Values:: \param{name}---a \term{symbol}; \noeval. \issue{DEFVAR-INIT-TIME:NOT-DELAYED} % I believe that the confusing wording of CLtL about evaluation has been avoided here, % so there is no explicit wording to support the intent of this proposal. \endissue{DEFVAR-INIT-TIME:NOT-DELAYED} \param{initial-value}---a \term{form}; for \macref{defparameter}, it is always \term{evaluated}, but for \macref{defvar} it is \term{evaluated} only if \param{name} is not already \term{bound}. \issue{DEFVAR-DOCUMENTATION:UNEVALUATED} \param{documentation}---a \param{string}; \noeval. \endissue{DEFVAR-DOCUMENTATION:UNEVALUATED} \label Description:: %% 5.3.2 2 %% 5.3.2 4 \macref{defparameter} and \macref{defvar} \term{establish} \param{name} as a \term{dynamic variable}. \macref{defparameter} unconditionally \term{assigns} the \param{initial-value} to the \term{dynamic variable} named \param{name}. \macref{defvar}, by contrast, \term{assigns} \param{initial-value} (if supplied) to the \term{dynamic variable} named \param{name} only if \param{name} is not already \term{bound}. \issue{DEFVAR-INITIALIZATION:CONSERVATIVE} If no \param{initial-value} is supplied, \macref{defvar} leaves the \term{value cell} of the \term{dynamic variable} named \param{name} undisturbed; if \param{name} was previously \term{bound}, its old \term{value} persists, and if it was previously \term{unbound}, it remains \term{unbound}. \endissue{DEFVAR-INITIALIZATION:CONSERVATIVE} If \param{documentation} is supplied, it is attached to \param{name} as a \term{documentation string} of kind \misc{variable}. \issue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} \macref{defparameter} and \macref{defvar} normally appear as a \term{top level form}, but it is meaningful for them to appear as \term{non-top-level forms}. However, the compile-time side effects described below only take place when they appear as \term{top level forms}. \endissue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} \label Examples:: \code (defparameter *p* 1) \EV *P* *p* \EV 1 (constantp '*p*) \EV \term{false} (setq *p* 2) \EV 2 (defparameter *p* 3) \EV *P* *p* \EV 3 (defvar *v* 1) \EV *V* *v* \EV 1 (constantp '*v*) \EV \term{false} (setq *v* 2) \EV 2 (defvar *v* 3) \EV *V* *v* \EV 2 (defun foo () (let ((*p* 'p) (*v* 'v)) (bar))) \EV FOO (defun bar () (list *p* *v*)) \EV BAR (foo) \EV (P V) \endcode The principal operational distinction between \macref{defparameter} and \macref{defvar} is that \macref{defparameter} makes an unconditional assignment to \param{name}, while \macref{defvar} makes a conditional one. In practice, this means that \macref{defparameter} is useful in situations where loading or reloading the definition would want to pick up a new value of the variable, while \macref{defvar} is used in situations where the old value would want to be retained if the file were loaded or reloaded. For example, one might create a file which contained: \code (defvar *the-interesting-numbers* '()) (defmacro define-interesting-number (name n) `(progn (defvar ,name ,n) (pushnew ,name *the-interesting-numbers*) ',name)) (define-interesting-number *my-height* 168) ;cm (define-interesting-number *my-weight* 13) ;stones \endcode Here the initial value, \f{()}, for the variable \f{*the-interesting-numbers*} is just a seed that we are never likely to want to reset to something else once something has been grown from it. As such, we have used \macref{defvar} to avoid having the \f{*interesting-numbers*} information reset if the file is loaded a second time. It is true that the two calls to \macref{define-interesting-number} here would be reprocessed, but if there were additional calls in another file, they would not be and that information would be lost. On the other hand, consider the following code: \code (defparameter *default-beep-count* 3) (defun beep (&optional (n *default-beep-count*)) (dotimes (i n) (si:%beep 1000. 100000.) (sleep 0.1))) \endcode Here we could easily imagine editing the code to change the initial value of \f{*default-beep-count*}, and then reloading the file to pick up the new value. In order to make value updating easy, we have used \macref{defparameter}. On the other hand, there is potential value to using \macref{defvar} in this situation. For example, suppose that someone had predefined an alternate value for \f{*default-beep-count*}, or had loaded the file and then manually changed the value. In both cases, if we had used \macref{defvar} instead of \macref{defparameter}, those user preferences would not be overridden by (re)loading the file. The choice of whether to use \macref{defparameter} or \macref{defvar} has visible consequences to programs, but is nevertheless often made for subjective reasons. \label Side Effects:: \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} % added qualification about top-level-ness --sjl 5 Mar 92 If a \macref{defvar} or \macref{defparameter} \term{form} appears as a \term{top level form}, the \term{compiler} must recognize that the \param{name} has been proclaimed \declref{special}. However, it must neither \term{evaluate} the \param{initial-value} \term{form} nor \term{assign} the \term{dynamic variable} named \param{name} at compile time. \endissue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} There may be additional (\term{implementation-defined}) compile-time or run-time side effects, as long as such effects do not interfere with the correct operation of \term{conforming programs}. \label Affected By:: \macref{defvar} is affected by whether \param{name} is already \term{bound}. \label Exceptional Situations:\None. \label See Also:: \funref{declaim}, \macref{defconstant}, \funref{documentation}, {\secref\Compilation} \label Notes:: It is customary to name \term{dynamic variables} with an \term{asterisk} at the beginning and end of the name. e.g., \f{*foo*} is a good name for a \term{dynamic variable}, but not for a \term{lexical variable}; \f{foo} is a good name for a \term{lexical variable}, but not for a \term{dynamic variable}. This naming convention is observed for all \term{defined names} in \clisp; however, neither \term{conforming programs} nor \term{conforming implementations} are obliged to adhere to this convention. The intent of the permission for additional side effects is to allow \term{implementations} to do normal ``bookkeeping'' that accompanies definitions. For example, the \term{macro expansion} of a \macref{defvar} or \macref{defparameter} \term{form} might include code that arranges to record the name of the source file in which the definition occurs. \macref{defparameter} and \macref{defvar} might be defined as follows: \code (defmacro defparameter (name initial-value &optional (documentation nil documentation-p)) `(progn (declaim (special ,name)) (setf (symbol-value ',name) ,initial-value) ,(when documentation-p `(setf (documentation ',name 'variable) ',documentation)) ',name)) (defmacro defvar (name &optional (initial-value nil initial-value-p) (documentation nil documentation-p)) `(progn (declaim (special ,name)) ,(when initial-value-p `(unless (boundp ',name) (setf (symbol-value ',name) ,initial-value))) ,(when documentation-p `(setf (documentation ',name 'variable) ',documentation)) ',name)) \endcode \endcom %%% ========== DESTRUCTURING-BIND \begincom{destructuring-bind}\ftype{Macro} \issue{DECLS-AND-DOC} \issue{DESTRUCTURING-BIND:NEW-MACRO} \label Syntax:: \DefmacWithValuesNewline destructuring-bind {lambda-list expression \starparam{declaration} \starparam{form}} {\starparam{result}} \label Arguments and Values:: %% 8.1.0 9 %% 8.1.0 10 %% 8.1.0 11 %% 8.1.0 12 % tweaked --sjl 5 Mar 92 %\param{lambda-list}---a \term{lambda list}; % can contain the \term{lambda list keywords} % \keyref{allow-other-keys}, % \keyref{aux}, % \keyref{body}, % \keyref{key}, % \keyref{optional}, % \keyref{rest}, % and % \keyref{whole}. \param{lambda-list}---a \term{destructuring lambda list}. \param{expression}---a \term{form}. \param{declaration}---a \misc{declare} \term{expression}; \noeval. \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} returned by the \term{forms}. \label Description:: \macref{destructuring-bind} binds the variables specified in \param{lambda-list} to the corresponding values in the tree structure resulting from the evaluation of \param{expression}; then \macref{destructuring-bind} evaluates \param{forms}. % All of this text is redundant; a simple cross-reference will do. % --sjl 5 Mar 92 % Anywhere in \param{lambda-list} where a parameter name can appear, and % where ordinary \term{lambda list} syntax as described in {\secref\OrdinaryLambdaLists} % does not otherwise allow a \term{list}, a \term{lambda list} can appear % in place of the parameter name. When this is done, then the portion of % the tree structure resulting from the evaluation of \param{expression} % that would match the parameter is treated as a tree structure for satisfying % the parameters in the embedded \term{lambda list}. % % If any of the \term{lambda list keywords} % \keyref{optional}, \keyref{rest}, \keyref{key}, \keyref{allow-other-keys} % and \keyref{aux} appears in \param{lambda-list}, % it is treated as it would be in an \term{ordinary lambda list}. % % If the \term{lambda list keyword} \keyref{body} appears, % it is treated the same as if \keyref{rest} had appeared. % (Only one of \keyref{body} or \keyref{rest} can be used at any one level.) % % If the \term{lambda list keyword} \keyref{whole} appears, % it must be immediately followed by a single variable that is bound % to the entire tree at the current level. % \keyref{whole} and its following variable should appear first in the list, % before any other \term{parameter} or \term{lambda list keyword}. % % It is also permissible for any level of \param{lambda-list} to be a % \term{dotted list}, ending in a parameter name. This situation is % treated exactly as if the parameter name that ends the \term{dotted list} % had appeared preceded by \keyref{rest} in a \term{proper list}. % For example, the notation \f{(x y . z)} is equivalent to \f{(x y \&rest z)}. % % For \keyref{optional} and \keyref{key} parameters, initialization forms and ``supplied-p'' % parameters can be supplied, just as for \macref{defun}. The \param{lambda-list} supports destructuring as described in \secref\DestructuringLambdaLists. \label Examples:: \code (defun iota (n) (loop for i from 1 to n collect i)) ;helper (destructuring-bind ((a &optional (b 'bee)) one two three) `((alpha) ,@(iota 3)) (list a b three two one)) \EV (ALPHA BEE 3 2 1) \endcode \label Affected By:\None. \label Exceptional Situations:: If the result of evaluating the \param{expression} does not match the destructuring pattern, an error \oftype{error} should be signaled. \label See Also:: \specref{macrolet}, \macref{defmacro} \label Notes:\None. \endissue{DESTRUCTURING-BIND:NEW-MACRO} \endissue{DECLS-AND-DOC} \endcom %%% ========== LET %%% ========== LET* \begincom{let, let*}\ftype{Special Operator} \issue{DECLS-AND-DOC} \label Syntax:: \issue{VARIABLE-LIST-ASYMMETRY:SYMMETRIZE} \DefspecWithValues let {\paren{\star{\VarValue}} \starparam{declaration} \starparam{form}} {\starparam{result}} \DefspecWithValues let* {\paren{\star{\VarValue}} \starparam{declaration} \starparam{form}} {\starparam{result}} \endissue{VARIABLE-LIST-ASYMMETRY:SYMMETRIZE} \label Arguments and Values:: %!!! Barmar thinks this should say "non-constant symbol". \param{var}---a \term{symbol}. % fixed some confusion about whether this is ``init-form'' or ``value''. % --sjl 5 Mar 92 \param{init-form}---a \term{form}. %!!! Barmar asks why "not evaluated" is only specified for this argument. %% 7.5.0 6 %% 7.5.0 10 \param{declaration}---a \misc{declare} \term{expression}; \noeval. \param{form}---a \term{form}. \param{results}---the \term{values} returned by the \term{forms}. \label Description:: %% 7.5.0 3 \specref{let} and \specref{let*} create new variable \term{bindings} and execute a series of \param{forms} that use these \term{bindings}. \specref{let} performs the \term{bindings} in parallel and \specref{let*} does them sequentially. %% 7.5.0 4 %% 7.5.0 5 The form \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} \code (let ((\param{var1} \param{init-form-1}) (\param{var2} \param{init-form-2}) ... (\param{varm} \param{init-form-m})) \param{declaration1} \param{declaration2} ... \param{declarationp} \param{form1} \param{form2} ... \param{formn}) \endcode first evaluates the expressions \param{init-form-1}, \param{init-form-2}, and so on, \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} in that order, saving the resulting values. Then all of the variables \param{varj} are bound to the corresponding values; each \term{binding} is lexical unless there is a \declref{special} declaration to the contrary. The expressions \param{formk} are then evaluated in order; the values of all but the last are discarded (that is, the body of a \specref{let} is an \term{implicit progn}). %% 7.5.0 7 %% 7.5.0 9 \specref{let*} is similar to \specref{let}, but the \term{bindings} of variables are performed sequentially rather than in parallel. The expression for the \param{init-form} of a \param{var} can refer to \param{vars} previously bound in the \specref{let*}. %% 7.5.0 8 The form \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} \code (let* ((\param{var1} \param{init-form-1}) (\param{var2} \param{init-form-2}) ... (\param{varm} \param{init-form-m})) \param{declaration1} \param{declaration2} ... \param{declarationp} \param{form1} \param{form2} ... \param{formn}) \endcode first evaluates the expression \param{init-form-1}, then binds the variable \param{var1} to that value; then it evaluates \param{init-form-2} and binds \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} \param{var2}, and so on. The expressions \param{formj} are then evaluated in order; the values of all but the last are discarded (that is, the body of \specref{let*} is an implicit \specref{progn}). For both \specref{let} and \specref{let*}, if there is not an \param{init-form} associated with a \param{var}, \param{var} is initialized to \nil. % This is a property of TYPE declarations and doesn't need to % be said again here. --sjl 5 Mar 92 % The consequences are undefined if a type \param{declaration} is supplied for a % \param{var} and the initial \param{value} of % that \param{var} is not consistent with the type \param{declaration}. The special form \specref{let} has the property that the \term{scope} of the name binding does not include any initial value form. For \specref{let*}, a variable's \term{scope} also includes the remaining initial value forms for subsequent variable bindings. %New name bindings take precedence over any %higher level binding or declarations. For example, % %\code % (locally (declare (special x) (float y)) % (let ((x 5) (y 10)) % (print (+ x y)))) %\endcode % %If there are no %proclamations are in effect, %then {\tt x} is local (not \declref{special}) %and {\tt y} is bound with no particular %type information because the {\tt y} being bound is a different variable %from the {\tt y} declared {\tt float}. %See \misc{declare}. % This is adequately addressed in the packages chapter. --sjl 5 Mar 92 %\issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} %It is permissible to use symbols in \thepackage{common-lisp} as lexical variable names, %provided they are not globally defined as \term{variables}. %\endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13} \label Examples:: \code (setq a 'top) \EV TOP (defun dummy-function () a) \EV DUMMY-FUNCTION (let ((a 'inside) (b a)) (format nil "~S ~S ~S" a b (dummy-function))) \EV "INSIDE TOP TOP" (let* ((a 'inside) (b a)) (format nil "~S ~S ~S" a b (dummy-function))) \EV "INSIDE INSIDE TOP" (let ((a 'inside) (b a)) (declare (special a)) (format nil "~S ~S ~S" a b (dummy-function))) \EV "INSIDE TOP INSIDE" \endcode \medbreak The code \code (let (x) (declare (integer x)) (setq x (gcd y z)) ...) \endcode is incorrect; although \f{x} is indeed set before it is used, and is set to a value of the declared type \term{integer}, nevertheless \f{x} initially takes on the value \nil\ in violation of the type declaration. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{progv} \label Notes:\None. \endissue{DECLS-AND-DOC} \endcom %%% ========== PROGV \begincom{progv}\ftype{Special Operator} \label Syntax:: \DefspecWithValues progv {\param{symbols} \param{values} \starparam{form}} {\starparam{result}} \label Arguments and Values:: %!!! Barmar thinks this should say "non-constant symbols" \param{symbols}---a \term{list} of \term{symbols}; \eval. \param{values}---a \term{list} of \term{objects}; \eval. \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} returned by the \term{forms}. \label Description:: \specref{progv} creates new dynamic variable \term{bindings} and executes each \param{form} using those \term{bindings}. Each \param{form} is evaluated in order. %% 7.5.0 14 \specref{progv} allows \term{binding} one or more dynamic variables whose names may be determined at run time. Each \param{form} is evaluated in order with the dynamic variables whose names are in \param{symbols} bound to corresponding \param{values}. If too few \param{values} are supplied, the remaining \term{symbols} are bound and then made to have no value. If too many \param{values} are supplied, the excess values are ignored. The \term{bindings} of the dynamic variables are undone on exit from \specref{progv}. \label Examples:: \code (setq *x* 1) \EV 1 (progv '(*x*) '(2) *x*) \EV 2 *x* \EV 1 Assuming *x* is not globally special, (let ((*x* 3)) (progv '(*x*) '(4) (list *x* (symbol-value '*x*)))) \EV (3 4) \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{let}, {\secref\Evaluation} \label Notes:: %% 7.5.0 16 Among other things, \specref{progv} is useful when writing interpreters for languages embedded in \Lisp; it provides a handle on the mechanism for \term{binding} \term{dynamic variables}. \endcom %%% ========== SETQ \begincom{setq}\ftype{Special Form} \label Syntax:: \DefspecWithValues setq {\stardown{pair}} {result} \auxbnf{pair}{var form} \label Pronunciation:: \pronounced{\Stress{set}\stress{ky\"u}} \label Arguments and Values:: %!!! Perhaps there should be a glossary term which makes this more convenient to say. \param{var}---a \term{symbol} naming a \term{variable} other than a \term{constant variable}. \param{form}---a \term{form}. %% 7.1.2 4 \param{result}---the \term{primary value} of the last \param{form}, or \nil\ if no \param{pairs} were supplied. \label Description:: Assigns values to \term{variables}. %% 7.1.2 3 \f{(setq \i{var1} \i{form1} \i{var2} \i{form2} ...)} is the simple variable assignment statement of \Lisp. First \param{form1} is evaluated and the result is stored in the variable \param{var1}, then \param{form2} is evaluated and the result stored in \param{var2}, and so forth. \specref{setq} may be used for assignment of both lexical and dynamic variables. \issue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM} If any \param{var} refers to a \term{binding} made by \specref{symbol-macrolet}, then that \param{var} is treated as if \macref{setf} (not \specref{setq}) had been used. \endissue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM} \label Examples:: \code ;; A simple use of SETQ to establish values for variables. (setq a 1 b 2 c 3) \EV 3 a \EV 1 b \EV 2 c \EV 3 ;; Use of SETQ to update values by sequential assignment. (setq a (1+ b) b (1+ a) c (+ a b)) \EV 7 a \EV 3 b \EV 4 c \EV 7 ;; This illustrates the use of SETQ on a symbol macro. (let ((x (list 10 20 30))) (symbol-macrolet ((y (car x)) (z (cadr x))) (setq y (1+ z) z (1+ y)) (list x y z))) \EV ((21 22 30) 21 22) \endcode \label Side Effects:: The \term{primary value} of each \param{form} is assigned to the corresponding \param{var}. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{psetq}, \funref{set}, \macref{setf} \label Notes:\None. \endcom %%% ========== PSETQ \begincom{psetq}\ftype{Macro} \label Syntax:: \DefmacWithValues psetq {\stardown{pair}} {\nil} \auxbnf{pair}{var form} \label Pronunciation:: \macref{psetq}: \pronounced{\maybeStress{p\harde}\Stress{set}\stress{ky\"u}} \label Arguments and Values:: %!!! Perhaps there should be a glossary term which makes this more convenient to say. \param{var}---a \term{symbol} naming a \term{variable} other than a \term{constant variable}. \param{form}---a \term{form}. \label Description:: Assigns values to \term{variables}. This is just like \specref{setq}, except that the assignments happen ``in parallel.'' That is, first all of the forms are evaluated, and only then are the variables set to the resulting values. In this way, the assignment to one variable does not affect the value computation of another in the way that would occur with \specref{setq}'s sequential assignment. \issue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM} If any \param{var} refers to a \term{binding} made by \specref{symbol-macrolet}, then that \param{var} is treated as if \macref{psetf} (not \macref{psetq}) had been used. \endissue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM} \label Examples:: \code ;; A simple use of PSETQ to establish values for variables. ;; As a matter of style, many programmers would prefer SETQ ;; in a simple situation like this where parallel assignment ;; is not needed, but the two have equivalent effect. (psetq a 1 b 2 c 3) \EV NIL a \EV 1 b \EV 2 c \EV 3 ;; Use of PSETQ to update values by parallel assignment. ;; The effect here is very different than if SETQ had been used. (psetq a (1+ b) b (1+ a) c (+ a b)) \EV NIL a \EV 3 b \EV 2 c \EV 3 ;; Use of PSETQ on a symbol macro. (let ((x (list 10 20 30))) (symbol-macrolet ((y (car x)) (z (cadr x))) (psetq y (1+ z) z (1+ y)) (list x y z))) \EV ((21 11 30) 21 11) ;; Use of parallel assignment to swap values of A and B. (let ((a 1) (b 2)) (psetq a b b a) (values a b)) \EV 2, 1 \endcode \label Side Effects:: The values of \param{forms} are assigned to \param{vars}. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{psetf}, \specref{setq} \label Notes:\None. \endcom % I moved the dictionary entry for the SPECIAL declaration to chapter 3, % to live with all the other declaration specifiers. --sjl 5 Mar 92 %-------------------- Control Transfer -------------------- %%% ========== BLOCK \begincom{block}\ftype{Special Operator} \label Syntax:: \DefspecWithValues block {\param{name} \star{\param{form}}} {\starparam{result}} \label Arguments and Values:: %% 7.7.0 3 \param{name}---a \term{symbol}. \param{form}---a \term{form}. %% 7.9.2 11 %% 7.9.2 12 \param{results}---the \term{values} of the \term{forms} if a \term{normal return} occurs, or else, if an \term{explicit return} occurs, the \term{values} that were transferred. \label Description:: %% 7.7.0 2 \specref{block} \term{establishes} a \term{block} named \param{name} and then evaluates \param{forms} as an \term{implicit progn}. % If a \macref{return} or \specref{return-from} that specifies % \param{name} is executed during the execution of some \param{form}, then % the results specified by the \macref{return} or \specref{return-from} % are immediately returned as the value of \specref{block}, % and execution proceeds as if the \specref{block} had terminated % normally. Only a \macref{return} or \specref{return-from} % textually contained in some \param{form} can exit from the \specref{block}. The \term{special operators} \specref{block} and \specref{return-from} work together to provide a structured, lexical, non-local exit facility. At any point lexically contained within \term{forms}, \specref{return-from} can be used with the given \param{name} to return control and values from the \specref{block} \term{form}, except when an intervening \term{block} with the same name has been \term{established}, in which case the outer \term{block} is shadowed by the inner one. The \term{block} named \term{name} has \term{lexical scope} and \term{dynamic extent}. % It is only possible to exit from a given run-time incarnation of a % \specref{block} once, either normally or by explicit return. Once established, a \term{block} may only be exited once, whether by \term{normal return} or \term{explicit return}. %%Barmar didn't think the following was really essential. I agree. -kmp 21-Dec-90 % %% 7.7.0 6 % The fact that \param{name} is lexical % has consequences that might be surprising % to users and implementors. % For example: % % \code % (block loser % (catch 'stuff % (mapcar #'(lambda (x) (if (numberp x) % (hairyfun x) % (return-from loser \nil))) % items))) % \endcode % % A \macref{return} can break up catchers if necessary to get % to the block in question. % It is possible for a \term{closure} created by \specref{function} for % a \term{lambda expression} to refer to a \specref{block} % name as long as the name % is lexically apparent. \label Examples:: \code (block empty) \EV NIL (block whocares (values 1 2) (values 3 4)) \EV 3, 4 (let ((x 1)) (block stop (setq x 2) (return-from stop) (setq x 3)) x) \EV 2 (block early (return-from early (values 1 2)) (values 3 4)) \EV 1, 2 (block outer (block inner (return-from outer 1)) 2) \EV 1 (block twin (block twin (return-from twin 1)) 2) \EV 2 ;; Contrast behavior of this example with corresponding example of CATCH. (block b (flet ((b1 () (return-from b 1))) (block b (b1) (print 'unreachable)) 2)) \EV 1 \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{return}, \specref{return-from}, {\secref\Evaluation} \label Notes:: %%This seems random to me. -kmp % \specref{block} differs from \specref{progn} in that \specref{progn} % has nothing to do with \macref{return}. \endcom %%% ========== CATCH \begincom{catch}\ftype{Special Operator} \label Syntax:: \DefspecWithValues catch {\param{tag} \starparam{form}} {\starparam{result}} \label Arguments and Values:: %% 7.10.0 3 \param{tag}---a \term{catch tag}; \eval. \param{forms}---an \term{implicit progn}. \param{results}---if the \param{forms} exit normally, the \term{values} returned by the \param{forms}; if a throw occurs to the \param{tag}, the \term{values} that are thrown. \label Description:: %!!! % Barmar: Tags are compared using EQ, not EQL. Therefore, the consequences % of using numbers and characters as tags are unspecified. % KMP: Personally, I think we should fix that to simplify the language % description. I don't approve of our using EQ anywhere in the spec. %% 7.10.0 2 \specref{catch} is used as the destination of a non-local control transfer by \specref{throw}. \param{Tags} are used to find the \specref{catch} to which a \specref{throw} is transferring control. \f{(catch 'foo \i{form})} catches a \f{(throw 'foo \i{form})} but not a \f{(throw 'bar \i{form})}. %% 7.10.0 4 The order of execution of \specref{catch} follows:\idxtext{order of evaluation}\idxtext{evaluation order} \beginlist \itemitem{1.} \param{Tag} is evaluated. It serves as the name of the \specref{catch}. \itemitem{2.} \param{Forms} are then evaluated as an implicit \specref{progn}, and the results of the last \param{form} are returned unless a \specref{throw} occurs. \itemitem{3.} If a \specref{throw} occurs during the execution of one of the \param{forms}, control is transferred to the \specref{catch} \term{form} whose \param{tag} is \funref{eq} to the tag argument of the \specref{throw} and which is the most recently established \specref{catch} with that \param{tag}. %The evaluation of \param{forms} is aborted. No further evaluation of \param{forms} occurs. %%Barmar thinks this is not redundant. I agree. -kmp 22-Dec-90 % If several tags match the tag % argument of a \specref{throw}, % control is transferred to the dynamically most recently established % \specref{catch}. \itemitem{4.} The \param{tag} \term{established} by \specref{catch} is \term{disestablished} just before the results are returned. \endlist %% 7.9.2 14 %% 7.9.2 15 %% gray's rewording If during the execution of one of the \param{forms}, a \specref{throw} is executed whose tag is \funref{eq} to the \specref{catch} tag, then the values specified by the \specref{throw} are returned as the result of the dynamically most recently established \specref{catch} form with that tag. % If a \specref{throw} occurs %during the execution of one of the \param{forms}, %and there is a \specref{catch} \param{tag} that is %\funref{eq} to the \specref{throw} tag, %the value or values resulting from %the \specref{throw} are returned. The mechanism for \specref{catch} and \specref{throw} works even if \specref{throw} is not within the lexical scope of \specref{catch}. \specref{throw} must occur within the \term{dynamic extent} of the \term{evaluation} of the body of a \specref{catch} with a corresponding \param{tag}. \label Examples:: \code (catch 'dummy-tag 1 2 (throw 'dummy-tag 3) 4) \EV 3 (catch 'dummy-tag 1 2 3 4) \EV 4 (defun throw-back (tag) (throw tag t)) \EV THROW-BACK (catch 'dummy-tag (throw-back 'dummy-tag) 2) \EV T ;; Contrast behavior of this example with corresponding example of BLOCK. (catch 'c (flet ((c1 () (throw 'c 1))) (catch 'c (c1) (print 'unreachable)) 2)) \EV 2 \endcode \label Affected By:\None. \label Exceptional Situations:: An error \oftype{control-error} is signaled if \specref{throw} is done when there is no suitable \specref{catch} \param{tag}. \label See Also:: \specref{throw}, {\secref\Evaluation} \label Notes:: It is customary for \term{symbols} to be used as \param{tags}, but any \term{object} is permitted. However, numbers should not be used because the comparison is done using \funref{eq}. \specref{catch} differs from \specref{block} in that \specref{catch} tags have dynamic \term{scope} while \specref{block} names have \term{lexical scope}. \endcom %%% ========== GO \begincom{go}\ftype{Special Operator} \label Syntax:: %% 7.8.5 17 \DefspecNoReturn go {tag} \label Arguments and Values:: \param{tag}---a \term{go tag}. % a \term{symbol} or an \term{integer}. \label Description:: %% 7.8.5 16 \specref{go} transfers control to the point in the body of an enclosing \specref{tagbody} form labeled by a tag \funref{eql} to \param{tag}. %!!! Barmar: Which TAGBODY forms was the first sentence talking about?? % GO only examines lexically containing forms. If there is no such \param{tag} in the body, the bodies of lexically containing \specref{tagbody} \term{forms} (if any) are examined as well. If several tags are \funref{eql} to \param{tag}, control is transferred to whichever matching \param{tag} is contained in the innermost \specref{tagbody} form that contains the \specref{go}. The consequences are undefined if there is no matching \param{tag} lexically visible to the point of the \specref{go}. % This is all said in a concept section now. --sjl 7 Mar 92 %\issue{EXIT-EXTENT:MINIMAL} %When a transfer of control is initiated by \specref{go}, %the following events occur in order to accomplish the transfer of control. %Note that for \specref{go}, %the \term{exit point} is the \term{form} within the \specref{tagbody} %that is being executed at the time the \specref{go} is performed. %\beginlist %\itemitem{1.} % Intervening \term{exit points} are ``abandoned'' % (\ie their \term{extent} ends % and it is no longer valid to attempt to transfer control through them). % %\itemitem{2.} % The cleanup clauses of any intervening \specref{unwind-protect} clauses % are evaluated. % %\itemitem{3.} % Intervening dynamic \term{bindings} of \declref{special} variables and % \term{catch tags} are undone. % %\itemitem{4.} % The \term{extent} of the \term{exit point} being invoked ends, % and control is passed to the target. %\endlist % %The extent of an exit being ``abandoned'' because it is being passed over %ends as soon as the transfer of control is initiated. That is, %event 1 occurs at the beginning of the initiation of the transfer of %control. %The consequences are undefined if an attempt is made to transfer control %to an \term{exit point} whose \term{dynamic extent} has ended. % %%Moon had me add the part about "interleaved" -kmp 13-Feb-92 %Events 2 and 3 are actually performed interleaved, in the order %corresponding to the reverse order in which they were established. %The effect of this is that the cleanup clauses of an \specref{unwind-protect} %sees the same dynamic \term{bindings} %of variables and \term{catch tags} as were %visible when the \specref{unwind-protect} was entered. % %Event 4 occurs at the end of the transfer of control. % %\endissue{EXIT-EXTENT:MINIMAL} The transfer of control initiated by \specref{go} is performed as described in \secref\TransferOfControl. \label Examples:: \code (tagbody (setq val 2) (go lp) (incf val 3) lp (incf val 4)) \EV NIL val \EV 6 \endcode \issue{EXIT-EXTENT:MINIMAL} The following is in error because there is a normal exit of the \specref{tagbody} before the \specref{go} is executed. \code (let ((a nil)) (tagbody t (setq a #'(lambda () (go t)))) (funcall a)) \endcode The following is in error because the \specref{tagbody} is passed over before the \specref{go} \term{form} is executed. \code (funcall (block nil (tagbody a (return #'(lambda () (go a)))))) \endcode \endissue{EXIT-EXTENT:MINIMAL} \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{tagbody} \label Notes:\None. %% Moon: Is this just here to confuse people? % \issue{EXIT-EXTENT:MINIMAL} % % Implementations can support longer \term{extents} for % \term{exit points} than is % required here; in particular, an implementation may be extended to % allow a larger extent as follows: % % Events of 1, 2, 3, and 4 are interwoven in the reverse % order in which they were established. In particular, the \term{extent} of % a passed-over \term{exit point} ends when control reaches a % frame that was % established before the \term{exit point} was established. % % In particular, it would be valid, during the evaluation of an % \specref{unwind-protect} % cleanup form executed because of a non-local transfer of control, to % initiate a new transfer of control to an % \term{exit point} intervening between the % \specref{unwind-protect} % and the original target; the original processing of % transfer of control is abandoned. % % \endissue{EXIT-EXTENT:MINIMAL} \endcom %%% ========== RETURN-FROM \begincom{return-from}\ftype{Special Operator} \label Syntax:: %% 7.7.0 7 \DefspecNoReturn return-from {\param{name} \brac{\param{result}}} \label Arguments and Values:: \param{name}---a \term{block tag}; \noeval. \param{result}---a \term{form}; \eval. \Default{\nil} \label Description:: Returns control and \term{multiple values}\meaning{2} from a lexically enclosing \term{block}. A \specref{block} \term{form} named \param{name} must lexically enclose the occurrence of \specref{return-from}; any \term{values} \term{yielded} by the \term{evaluation} of \param{result} are immediately returned from the innermost such lexically enclosing \term{block}. % This is all said in a concept section now. --sjl 7 Mar 92 %\issue{EXIT-EXTENT:MINIMAL} %When a transfer of control is initiated by \specref{return-from}, %the following events occur before the transfer of control is complete. %Note that for \specref{return-from}, the %\term{exit point} is the corresponding %\specref{block} \term{form}. %\beginlist %\itemitem{1.} %Intervening \term{exit points} are ``abandoned'' %(\ie their \term{extent} ends and it is no longer valid to attempt %to transfer control through them). % %\itemitem{2.} %The cleanup clauses of any intervening \specref{unwind-protect} clauses % are evaluated. % %\itemitem{3.} %Intervening dynamic \term{bindings} of \declref{special} variables and %\term{catch tags} are undone. %% what about condition handlers and restarts? --sjl 5 Mar 92 % %\itemitem{4.} %The \term{extent} of the \term{exit point} being invoked ends, %and control is passed to the target. %\endlist % %The extent of an exit being ``abandoned'' because it is being passed over %ends as soon as the transfer of control is initiated. That is, %event 1 occurs at the beginning of the initiation of the transfer of %control. %The consequences are undefined if an attempt is made to transfer control %to an \term{exit point} whose \term{dynamic extent} has ended. % %%Moon had me add the part about "interleaved" -kmp 13-Feb-92 %Events 2 and 3 are actually performed interleaved, in the order %corresponding to the reverse order in which they were established. %The effect of this is that the cleanup clauses of an \specref{unwind-protect} %sees the same dynamic \term{bindings} %of variables and \term{catch tags} as were %visible when the \specref{unwind-protect} was entered. % %Event 4 occurs at the end of the transfer of control. % %%Dussud removed some additional detailed discussion here about longer extents, %% how events are interwoven, etc. %\endissue{EXIT-EXTENT:MINIMAL} The transfer of control initiated by \specref{return-from} is performed as described in \secref\TransferOfControl. \label Examples:: \issue{EXIT-EXTENT:MINIMAL} \code (block alpha (return-from alpha) 1) \EV NIL (block alpha (return-from alpha 1) 2) \EV 1 (block alpha (return-from alpha (values 1 2)) 3) \EV 1, 2 (let ((a 0)) (dotimes (i 10) (incf a) (when (oddp i) (return))) a) \EV 2 (defun temp (x) (if x (return-from temp 'dummy)) 44) \EV TEMP (temp nil) \EV 44 (temp t) \EV DUMMY (block out (flet ((exit (n) (return-from out n))) (block out (exit 1))) 2) \EV 1 (block nil (unwind-protect (return-from nil 1) (return-from nil 2))) \EV 2 (dolist (flag '(nil t)) (block nil (let ((x 5)) (declare (special x)) (unwind-protect (return-from nil) (print x)))) (print 'here)) \OUT 5 \OUT HERE \OUT 5 \OUT HERE \EV NIL (dolist (flag '(nil t)) (block nil (let ((x 5)) (declare (special x)) (unwind-protect (if flag (return-from nil)) (print x)))) (print 'here)) \OUT 5 \OUT HERE \OUT 5 \OUT HERE \EV NIL \endcode The following has undefined consequences because the \specref{block} \term{form} exits normally before the \macref{return-from} \term{form} is attempted. \code (funcall (block nil #'(lambda () (return-from nil)))) is an error. \endcode \endissue{EXIT-EXTENT:MINIMAL} \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{block}, \macref{return}, {\secref\Evaluation} \label Notes:\None. \endcom %%% ========== RETURN \begincom{return}\ftype{Macro} \label Syntax:: %% 7.7.0 7 \DefmacNoReturn return {\brac{\param{result}}} \label Arguments and Values:: \param{result}---a \term{form}; \eval. \Default{\nil} \label Description:: Returns, as if by \specref{return-from}, from the \term{block} named \nil. \label Examples:: \code (block nil (return) 1) \EV NIL (block nil (return 1) 2) \EV 1 (block nil (return (values 1 2)) 3) \EV 1, 2 (block nil (block alpha (return 1) 2)) \EV 1 (block alpha (block nil (return 1)) 2) \EV 2 (block nil (block nil (return 1) 2)) \EV 1 \endcode \label Affected By:\None. \label Conditions:\None. \label See Also:: \specref{block}, \specref{return-from}, {\secref\Evaluation} \label Notes:: \code (return) \EQ (return-from nil) (return \param{form}) \EQ (return-from nil \param{form}) \endcode The \term{implicit blocks} \term{established} by \term{macros} such as \macref{do} are often named \nil, so that \macref{return} can be used to exit from such \term{forms}. \endcom %%% ========== TAGBODY \begincom{tagbody}\ftype{Special Operator} \label Syntax:: \DefspecWithValues tagbody {\star{\curly{\param{tag} | \param{statement}}}} {\nil} \label Arguments and Values:: %% 7.8.5 8 \param{tag}---a \term{go tag}; \noeval. \param{statement}---a \term{compound form}; \evalspecial. \label Description:: Executes zero or more \term{statements} in a %context \term{lexical environment} that provides for control transfers to labels indicated by the \param{tags}. %% 7.8.5 4 %% 7.8.5 5 The \param{statements} in a \specref{tagbody} are \term{evaluated} in order from left to right, and their \term{values} are discarded. If at any time there are no remaining \param{statements}, \specref{tagbody} returns \nil. %% 7.8.5 6 However, if \f{(go \param{tag})} is \term{evaluated}, control jumps to the part of the body labeled with the \param{tag}. (Tags are compared with \funref{eql}.) %!!! Need to introduce the word "lexical" in more places here. A \param{tag} established by \specref{tagbody} has \term{lexical scope} and has \term{dynamic extent}. Once \specref{tagbody} has been exited, it is no longer valid to \specref{go} to a \param{tag} in its body. It is permissible for \specref{go} to jump to a \specref{tagbody} that is not the innermost \specref{tagbody} containing that \specref{go}; the \param{tags} established by a \specref{tagbody} only shadow other \param{tags} of like name. \issue{TAGBODY-TAG-EXPANSION:NO} The determination of which elements of the body are \param{tags} and which are \param{statements} is made prior to any \term{macro expansion} of that element. If a \param{statement} is a \term{macro form} and its \term{macro expansion} is an \term{atom}, that \term{atom} is treated as a \param{statement}, not a \param{tag}. \endissue{TAGBODY-TAG-EXPANSION:NO} %!!! Barmar: Didn't we say something about duplicate tags? %KMP: Apparently not, but maybe something should be added about `explicitly vague'. \label Examples:: \code (let (val) (tagbody (setq val 1) (go point-a) (incf val 16) point-c (incf val 04) (go point-b) (incf val 32) point-a (incf val 02) (go point-c) (incf val 64) point-b (incf val 08)) val) \EV 15 (defun f1 (flag) (let ((n 1)) (tagbody (setq n (f2 flag #'(lambda () (go out)))) out (prin1 n)))) \EV F1 (defun f2 (flag escape) (if flag (funcall escape) 2)) \EV F2 (f1 nil) \OUT 2 \EV NIL (f1 t) \OUT 1 \EV NIL \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{go} \label Notes:: The \term{macros} in \thenextfigure\ have \term{implicit tagbodies}. \displaythree{Macros that have implicit tagbodies.}{ do&do-external-symbols&dotimes\cr do*&do-symbols&prog\cr do-all-symbols&dolist&prog*\cr } \endcom %%% ========== THROW \begincom{throw}\ftype{Special Operator} \label Syntax:: \DefspecNoReturn throw {tag result-form} \label Arguments and Values:: \param{tag}---a \term{catch tag}; \eval. \param{result-form}---a \term{form}; \evalspecial. \label Description:: \specref{throw} causes a non-local control transfer to a \specref{catch} whose tag is \funref{eq} to \param{tag}. %% 7.10.0 11 %% This is said more precisely below. -moon & kmp 13-feb-92 % Dynamic variable \term{bindings} are undone back to the point of the \specref{catch}, % and any intervening \specref{unwind-protect} clean-up code is executed. \param{Tag} is evaluated first to produce an \term{object} called the throw tag; then \param{result-form} is evaluated, and its results are saved. If the \param{result-form} produces multiple values, then all the values are saved. The most recent outstanding \specref{catch} whose \param{tag} is \funref{eq} to the throw tag is exited; the saved results are returned as the value or values of \specref{catch}. % This is all said in a concept section now. --sjl 7 Mar 92 %\issue{EXIT-EXTENT:MINIMAL} %When a transfer of control is initiated by \specref{throw}, %the following events occur before the transfer of control is complete. %Note that for \specref{throw}, the %\term{exit point} is the corresponding %\specref{catch} \term{form}. %\beginlist %\itemitem{1.} %Intervening \term{exit points} are ``abandoned'' %(\ie their \term{extent} ends % and it is no longer valid to attempt to transfer control through them). % %\itemitem{2.} % The cleanup clauses of any intervening \specref{unwind-protect} clauses % are evaluated. % %\itemitem{3.} % Intervening dynamic \term{bindings} of \declref{special} variables % and \term{catch tags} are undone. %% what about condition handlers and restarts? --sjl 5 Mar 92 % %\itemitem{4.} % The \term{extent} of the \term{exit point} being invoked ends, % and control is passed to the target. %\endlist % %The extent of an exit being ``abandoned'' because it is being passed over %ends as soon as the transfer of control is initiated. That is, %event 1 occurs at the beginning of the initiation of the transfer of %control. The consequences are undefined if an attempt is made %to transfer control to an \term{exit point} whose \term{dynamic extent} has %ended. % %%Moon had me add the part about "interleaved" -kmp 13-Feb-92 %Events 2 and 3 are actually performed interleaved, in the order %corresponding to the reverse order %in which they were established. %The effect of this is that the cleanup clauses of an \specref{unwind-protect} %sees the same dynamic \term{bindings} %of variables and \term{catch tags} as were %visible when the \specref{unwind-protect} was entered. % %Event 4 occurs at the end of the transfer of control. % %\endissue{EXIT-EXTENT:MINIMAL} The transfer of control initiated by \specref{throw} is performed as described in \secref\TransferOfControl. \label Examples:: \code (catch 'result (setq i 0 j 0) (loop (incf j 3) (incf i) (if (= i 3) (throw 'result (values i j))))) \EV 3, 9 \endcode \issue{EXIT-EXTENT:MINIMAL} \code (catch nil (unwind-protect (throw nil 1) (throw nil 2))) \EV 2 \endcode The consequences of the following are undefined because the \specref{catch} of \f{b} is passed over by the first \specref{throw}, hence portable programs must assume that its \term{dynamic extent} is terminated. The \term{binding} of the \term{catch tag} is not yet \term{disestablished} and therefore it is the target of the second \specref{throw}. %% Moon: Belongs with redundant and confusing text now commented out in Notes. % If the implementation is extended as outlined above, % the following returns \f{2}. \code (catch 'a (catch 'b (unwind-protect (throw 'a 1) (throw 'b 2)))) \endcode The following prints ``\f{The inner catch returns :SECOND-THROW}'' and then returns \f{:outer-catch}. \code (catch 'foo (format t "The inner catch returns ~s.~%" (catch 'foo (unwind-protect (throw 'foo :first-throw) (throw 'foo :second-throw)))) :outer-catch) \OUT The inner catch returns :SECOND-THROW \EV :OUTER-CATCH \endcode %% Moon: This whole example is redundant. % The consequences of the following are undefined because the \term{extent} of % the {\tt (catch 'bar ...)} \term{exit point} % ends when the {\tt (THROW 'FOO ...)} % commences. % %% Moon: Belongs with redundant and confusing text now commented out in Notes. % % If the implementation is extended as described above, % % the pending \term{exit point} to tag {\tt foo} is discarded by the % % second \specref{throw} to {\tt bar} and the value 4 is transferred to % % {\tt (catch 'bar ...)}, that returns 4. The {\tt (catch 'foo ...)} % % then returns the 4 because its first argument has returned % % normally. {\tt xxx} is not printed. % % \code % (catch 'foo % (catch 'bar % (unwind-protect (throw 'foo 3) % (throw 'bar 4) % (print 'xxx)))) % \endcode \endissue{EXIT-EXTENT:MINIMAL} \label Affected By:\None. \label Exceptional Situations:: %% 7.10.0 12 If there is no outstanding \term{catch tag} that matches the throw tag, no unwinding of the stack is performed, and an error \oftype{control-error} is signaled. When the error is signaled, % the outstanding \specref{catch tags} % the dynamic variable \term{bindings}, ... are those %% Replaced by more general terms. the \term{dynamic environment} is that which was in force at the point of the \specref{throw}. \label See Also:: \specref{block}, \specref{catch}, \specref{return-from}, \specref{unwind-protect}, {\secref\Evaluation} \label Notes:: %% Moon thinks this is just confusing and unnecessary. % Implementations can support longer \term{extents} for % \term{exit points} than is % required here; in particular, an implementation may be extended to % allow a larger extent as follows: % % Events of 1, 2, 3, and 4 are interwoven in the reverse % order in which they were established. In particular, the \term{extent} of % a passed-over \term{exit point} ends when control reaches a % frame that was % established before the \term{exit point} was established. % % In particular, it would be valid, during the evaluation of an % \specref{unwind-protect} % cleanup form executed because of a non-local transfer of control, to % initiate a new transfer of control to an % \term{exit point} intervening between the % \specref{unwind-protect} % and the original target; the original processing of % transfer of control is abandoned. \specref{catch} and \specref{throw} are normally used when the \term{exit point} must have \term{dynamic scope} (\eg the \specref{throw} is not lexically enclosed by the \specref{catch}), while \specref{block} and \specref{return} are used when \term{lexical scope} is sufficient. \endcom %%% ========== UNWIND-PROTECT \begincom{unwind-protect}\ftype{Special Operator} \label Syntax:: \DefspecWithValues unwind-protect {\param{protected-form} \starparam{cleanup-form}} {\starparam{result}} \label Arguments and Values:: \param{protected-form}---a \term{form}. \param{cleanup-form}---a \term{form}. %% 7.9.2 18 \param{results}---the \term{values} of the \term{protected-form}. \label Description:: %% 7.10.0 6 %% 7.10.0 7 \specref{unwind-protect} evaluates \param{protected-form} and guarantees that \param{cleanup-forms} are executed before \specref{unwind-protect} exits, whether it terminates normally or is aborted by a control transfer of some kind. \specref{unwind-protect} is intended to be used to make sure that certain side effects take place after the evaluation of \param{protected-form}. %% 7.10.0 9 If a \term{non-local exit} occurs during execution of \param{cleanup-forms}, no special action is taken. The \param{cleanup-forms} of \specref{unwind-protect} are not protected by that \specref{unwind-protect}. %% Moon and I couldn't figure out what this was about. -kmp 13-Feb-92 % , though they might be % protected if that \specref{unwind-protect} occurs within the protected % form of another \specref{unwind-protect}. %% 7.10.0 10 \specref{unwind-protect} protects against all attempts to exit from \param{protected-form}, including \specref{go}, \macref{handler-case}, \macref{ignore-errors}, \macref{restart-case}, \specref{return-from}, \specref{throw}, and \macref{with-simple-restart}. %!!! Moon: And other stuff -- see previous page. Obviously need to collect all % this stuff into a glossary entry. \issue{EXIT-EXTENT-AND-CONDITION-SYSTEM:LIKE-DYNAMIC-BINDINGS} Undoing of \term{handler} and \term{restart} \term{bindings} during an exit happens in parallel with the undoing of the bindings of \term{dynamic variables} and \specref{catch} tags, in the reverse order in which they were established. The effect of this is that \param{cleanup-form} sees the same \term{handler} and \term{restart} \term{bindings}, as well as \term{dynamic variable} \term{bindings} and \specref{catch} tags, as were visible when the \specref{unwind-protect} was entered. \endissue{EXIT-EXTENT-AND-CONDITION-SYSTEM:LIKE-DYNAMIC-BINDINGS} \label Examples:: \code (tagbody (let ((x 3)) (unwind-protect (if (numberp x) (go out)) (print x))) out ...) \endcode When \specref{go} is executed, the call to \funref{print} is executed first, and then the transfer of control to the tag \f{out} is completed. \code (defun dummy-function (x) (setq state 'running) (unless (numberp x) (throw 'abort 'not-a-number)) (setq state (1+ x))) \EV DUMMY-FUNCTION (catch 'abort (dummy-function 1)) \EV 2 state \EV 2 (catch 'abort (dummy-function 'trash)) \EV NOT-A-NUMBER state \EV RUNNING (catch 'abort (unwind-protect (dummy-function 'trash) (setq state 'aborted))) \EV NOT-A-NUMBER state \EV ABORTED \endcode %% 7.10.0 8 The following code is not correct: \code (unwind-protect (progn (incf *access-count*) (perform-access)) (decf *access-count*)) \endcode If an exit occurs before completion of \macref{incf}, the \macref{decf} \term{form} is executed anyway, resulting in an incorrect value for \f{*access-count*}. The correct way to code this is as follows: \code (let ((old-count *access-count*)) (unwind-protect (progn (incf *access-count*) (perform-access)) (setq *access-count* old-count))) \endcode \issue{EXIT-EXTENT:MINIMAL} \code ;;; The following returns 2. (block nil (unwind-protect (return 1) (return 2))) ;;; The following has undefined consequences. (block a (block b (unwind-protect (return-from a 1) (return-from b 2)))) ;;; The following returns 2. (catch nil (unwind-protect (throw nil 1) (throw nil 2))) ;;; The following has undefined consequences because the catch of B is ;;; passed over by the first THROW, hence portable programs must assume ;;; its dynamic extent is terminated. The binding of the catch tag is not ;;; yet disestablished and therefore it is the target of the second throw. (catch 'a (catch 'b (unwind-protect (throw 'a 1) (throw 'b 2)))) ;;; The following prints "The inner catch returns :SECOND-THROW" ;;; and then returns :OUTER-CATCH. (catch 'foo (format t "The inner catch returns ~s.~%" (catch 'foo (unwind-protect (throw 'foo :first-throw) (throw 'foo :second-throw)))) :outer-catch) ;;; The following returns 10. The inner CATCH of A is passed over, but ;;; because that CATCH is disestablished before the THROW to A is executed, ;;; it isn't seen. (catch 'a (catch 'b (unwind-protect (1+ (catch 'a (throw 'b 1))) (throw 'a 10)))) ;;; The following has undefined consequences because the extent of ;;; the (CATCH 'BAR ...) exit ends when the (THROW 'FOO ...) ;;; commences. (catch 'foo (catch 'bar (unwind-protect (throw 'foo 3) (throw 'bar 4) (print 'xxx)))) ;;; The following returns 4; XXX is not printed. ;;; The (THROW 'FOO ...) has no effect on the scope of the BAR ;;; catch tag or the extent of the (CATCH 'BAR ...) exit. (catch 'bar (catch 'foo (unwind-protect (throw 'foo 3) (throw 'bar 4) (print 'xxx)))) ;;; The following prints 5. (block nil (let ((x 5)) (declare (special x)) (unwind-protect (return) (print x)))) \endcode \endissue{EXIT-EXTENT:MINIMAL} \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{catch}, \specref{go}, \macref{handler-case}, \macref{restart-case}, \macref{return}, \specref{return-from}, \specref{throw}, {\secref\Evaluation} \label Notes:\None. \endcom %-------------------- Truth Values -------------------- %%% ========== NIL \begincom{nil}\ftype{Constant Variable} \label Constant Value:: \nil. \label Description:: %% 6.1.0 1 %% 6.1.0 2 %\nil\ is a \term{symbol} which appears to be treated as a variable when evaluated. %To modify the value of \nil\ is not permitted. %The value of the object \oftype{null} is \nil. %\nil\ represents both the %logical false value and the \term{empty list}. %% 14.0.0 3 %\nil\ is considered to be a \term{sequence} of length zero. \nil\ represents both \term{boolean} (and \term{generalized boolean}) \term{false} and the \term{empty list}. \label Examples:: \code nil \EV NIL \endcode \label See Also:: \conref{t} \label Notes:\None. \endcom %%% ========== NOT \begincom{not}\ftype{Function} \issue{NOT-AND-NULL-RETURN-VALUE:X3J13-MAR-93} \label Syntax:: \DefunWithValues not {x} {boolean} \label Arguments and Values:: \param{x}---a \term{generalized boolean} (\ie any \term{object}). \param{boolean}---a \term{boolean}. \label Description:: %% 6.4.0 3 \StrictPredicate{x}{\term{false}} \label Examples:: \code (not nil) \EV T (not '()) \EV T (not (integerp 'sss)) \EV T (not (integerp 1)) \EV NIL (not 3.7) \EV NIL (not 'apple) \EV NIL \endcode \endissue{NOT-AND-NULL-RETURN-VALUE:X3J13-MAR-93} \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None! \label See Also:: \funref{null} \label Notes:: % \code % (not x) \EQ (null x) % \endcode %% 6.4.0 $ \funref{not} is intended to be used to invert the `truth value' of a \term{boolean} (or \term{generalized boolean}) whereas \funref{null} is intended to be used to test for the \term{empty list}. Operationally, \funref{not} and \funref{null} compute the same result; which to use is a matter of style. \endcom %%% ========== T \begincom{t}\ftype{Constant Variable} \label Constant Value:: %% 6.1.0 3 \misc{t}. \label Description:: The \term{boolean} representing true, and the canonical \term{generalized boolean} representing true. Although any \term{object} other than \nil\ is considered \term{true}, \t\ is generally used when there is no special reason to prefer one such \term{object} over another. The \term{symbol} \t\ is also sometimes used for other purposes as well. For example, as the \term{name} of a \term{class}, as a \term{designator} (\eg a \term{stream designator}) or as a special symbol for some syntactic reason (\eg in \macref{case} and \macref{typecase} to label the \param{otherwise-clause}). \label Examples:: \code t \EV T (eq t 't) \EV \term{true} (find-class 't) \EV # (case 'a (a 1) (t 2)) \EV 1 (case 'b (a 1) (t 2)) \EV 2 (prin1 'hello t) \OUT HELLO \EV HELLO \endcode \label See Also:: \conref{nil} \label Notes:\None. \endcom %-------------------- Identity Equality -------------------- %%% ========== EQ \begincom{eq}\ftype{Function} \label Syntax:: \DefunWithValues eq {x y} {generalized-boolean} \label Arguments and Values:: \param{x}---an \term{object}. \param{y}---an \term{object}. \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: %% 6.3.0 3 Returns \term{true} if its \term{arguments} are the same, identical \term{object}; otherwise, returns \term{false}. \label Examples:: \code (eq 'a 'b) \EV \term{false} (eq 'a 'a) \EV \term{true} (eq 3 3) \EV \term{true} \OV \term{false} (eq 3 3.0) \EV \term{false} (eq 3.0 3.0) \EV \term{true} \OV \term{false} (eq #c(3 -4) #c(3 -4)) \EV \term{true} \OV \term{false} (eq #c(3 -4.0) #c(3 -4)) \EV \term{false} (eq (cons 'a 'b) (cons 'a 'c)) \EV \term{false} (eq (cons 'a 'b) (cons 'a 'b)) \EV \term{false} (eq '(a . b) '(a . b)) \EV \term{true} \OV \term{false} (progn (setq x (cons 'a 'b)) (eq x x)) \EV \term{true} (progn (setq x '(a . b)) (eq x x)) \EV \term{true} (eq #\\A #\\A) \EV \term{true} \OV \term{false} (let ((x "Foo")) (eq x x)) \EV \term{true} (eq "Foo" "Foo") \EV \term{true} \OV \term{false} (eq "Foo" (copy-seq "Foo")) \EV \term{false} (eq "FOO" "foo") \EV \term{false} (eq "string-seq" (copy-seq "string-seq")) \EV \term{false} (let ((x 5)) (eq x x)) \EV \term{true} \OV \term{false} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None! \label See Also:: \funref{eql}, \funref{equal}, \funref{equalp}, \funref{=}, {\secref\Compilation} \label Notes:: %% 6.3.0 4 \term{Objects} that appear the same when printed are not necessarily \funref{eq} to each other. \term{Symbols} that print the same usually are \funref{eq} to each other because of the use of the \funref{intern} function. However, \term{numbers} with the same value need not be \funref{eq}, and two similar \term{lists} are usually not \term{identical}. An implementation is permitted to make ``copies'' of \term{characters} and \term{numbers} at any time. The effect is that \clisp\ makes no guarantee that \funref{eq} is true even when both its arguments are ``the same thing'' if that thing is a \term{character} or \term{number}. Most \clisp\ \term{operators} use \funref{eql} rather than \funref{eq} to compare objects, or else they default to \funref{eql} and only use \funref{eq} if specifically requested to do so. However, the following \term{operators} are defined to use \funref{eq} rather than \funref{eql} in a way that cannot be overridden by the \term{code} which employs them: \displaythree{Operators that always prefer EQ over EQL}{ catch&getf&throw\cr get&remf&\cr get-properties&remprop\cr } \endcom %%% ========== EQL \begincom{eql}\ftype{Function} \label Syntax:: \DefunWithValues eql {x y} {generalized-boolean} \label Arguments and Values:: \param{x}---an \term{object}. \param{y}---an \term{object}. \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: %% 6.3.0 7 The value of \funref{eql} is \term{true} of two objects, \param{x} and \param{y}, in the folowing cases: \beginlist \itemitem{1.} If \param{x} and \param{y} are \funref{eq}. \itemitem{2.} If \param{x} and \param{y} are both \term{numbers} of the same \term{type} and the same value. \itemitem{3.} If they are both \term{characters} that represent the same character. \endlist Otherwise the value of \funref{eql} is \term{false}. %% 6.3.0 8 If an implementation supports positive and negative zeros as \term{distinct} values, then \f{(eql 0.0 -0.0)} returns \term{false}. Otherwise, when the syntax \f{-0.0} is read it is interpreted as the value \f{0.0}, and so \f{(eql 0.0 -0.0)} returns \term{true}. \label Examples:: \code (eql 'a 'b) \EV \term{false} (eql 'a 'a) \EV \term{true} (eql 3 3) \EV \term{true} (eql 3 3.0) \EV \term{false} (eql 3.0 3.0) \EV \term{true} (eql #c(3 -4) #c(3 -4)) \EV \term{true} (eql #c(3 -4.0) #c(3 -4)) \EV \term{false} (eql (cons 'a 'b) (cons 'a 'c)) \EV \term{false} (eql (cons 'a 'b) (cons 'a 'b)) \EV \term{false} (eql '(a . b) '(a . b)) \EV \term{true} \OV \term{false} (progn (setq x (cons 'a 'b)) (eql x x)) \EV \term{true} (progn (setq x '(a . b)) (eql x x)) \EV \term{true} (eql #\\A #\\A) \EV \term{true} (eql "Foo" "Foo") \EV \term{true} \OV \term{false} (eql "Foo" (copy-seq "Foo")) \EV \term{false} (eql "FOO" "foo") \EV \term{false} \endcode Normally \f{(eql 1.0s0 1.0d0)} is false, under the assumption that \f{1.0s0} and \f{1.0d0} are of distinct data types. However, implementations that do not provide four distinct floating-point formats are permitted to ``collapse'' the four formats into some smaller number of them; in such an implementation \f{(eql 1.0s0 1.0d0)} might be true. \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None! \label See Also:: \funref{eq}, \funref{equal}, \funref{equalp}, \funref{=}, \funref{char=} \label Notes:: \funref{eql} is the same as \funref{eq}, except that if the arguments are \term{characters} or \term{numbers} of the same type then their values are compared. Thus \funref{eql} tells whether two \term{objects} are conceptually the same, whereas \funref{eq} tells whether two \term{objects} are implementationally identical. It is for this reason that \funref{eql}, not \funref{eq}, is the default comparison predicate for \term{operators} that take \term{sequences} as arguments. \funref{eql} may not be true of two \term{floats} even when they represent the same value. \funref{=} is used to compare mathematical values. %% 6.3.0 9 Two \term{complex} numbers are considered to be \funref{eql} if their real parts are \funref{eql} and their imaginary parts are \funref{eql}. For example, \f{(eql \#C(4 5) \#C(4 5))} is \term{true} and \f{(eql \#C(4 5) \#C(4.0 5.0))} is \term{false}. Note that while \f{(eql \#C(5.0 0.0) 5.0)} is \term{false}, \f{(eql \#C(5 0) 5)} is \term{true}. In the case of \f{(eql \#C(5.0 0.0) 5.0)} the two arguments are of different types, and so cannot satisfy \funref{eql}. In the case of \f{(eql \#C(5 0) 5)}, \f{\#C(5 0)} is not a \term{complex} number, but is automatically reduced to the \term{integer} \f{5}. \endcom %%% ========== EQUAL \begincom{equal}\ftype{Function} \label Syntax:: \DefunWithValues equal {x y} {generalized-boolean} \label Arguments and Values:: \param{x}---an \term{object}. \param{y}---an \term{object}. \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: %% 6.3.0 12 Returns \term{true} if \param{x} and \param{y} are structurally similar (isomorphic) \term{objects}. \term{Objects} are treated as follows by \funref{equal}. \beginlist \itemitem{\term{Symbols}, \term{Numbers}, and \term{Characters}} %% 6.3.0 13 \funref{equal} is \term{true} of two \term{objects} if they are \term{symbols} that are \funref{eq}, if they are \term{numbers} that are \funref{eql}, or if they are \term{characters} that are \funref{eql}. \itemitem{\term{Conses}} %% 6.3.0 15 For \term{conses}, \funref{equal} is defined recursively as the two \term{cars} being \funref{equal} and the two \term{cdrs} being \funref{equal}. \itemitem{\term{Arrays}} %% 6.3.0 16 Two \term{arrays} are \funref{equal} only if they are \funref{eq}, with one exception: \term{strings} and \term{bit vectors} are compared element-by-element (using \funref{eql}). If either \param{x} or \param{y} has a \term{fill pointer}, the \term{fill pointer} limits the number of elements examined by \funref{equal}. Uppercase and lowercase letters in \term{strings} are considered by \funref{equal} to be different. \itemitem{\term{Pathnames}} %% 6.3.0 18 Two \term{pathnames} are \funref{equal} if and only if all the corresponding components (host, device, and so on) are %!!! Barmar: "equivalent" ??? equivalent. Whether or not uppercase and lowercase letters are considered equivalent in \term{strings} appearing in components is \term{implementation-dependent}. \term{pathnames} that are \funref{equal} should be functionally equivalent. %Barmar didn't think this belonged here. I agree. % %% 23.1.1 19 % For \term{pathnames}, \funref{eql} is the same as \funref{eq}. \issue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \itemitem{\bf Other (Structures, hash-tables, instances, $\ldots$)} Two other \term{objects} are \funref{equal} only if they are \funref{eq}. %% Barmar: "EQUAL" or "EQUALP" in this next ??? %% Moon: Delete this. This is EQUAL, not EQUALP % %% The following was added at the June 1989 meeting % A structure defined by \macref{defstruct} without an explicit % \kwd{type} option is called non-typed; otherwise it is typed. % The definition of \funref{equalp} on \macref{defstruct} % instances is as follows: % \funref{equalp} on two \macref{defstruct} instances \f{s1} and \f{s2}, % where both are non-typed structures, is \term{true} if and only if: % \beginlist % \itemitem{1.} % The \term{type} of \f{s1} is the same as the type of \f{s2}. % \itemitem{2.} % The value of each \term{slot} of \f{s1} % is \funref{equalp} to the value of the same \term{slot} of \f{s2}. % \endlist \endissue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \endlist \issue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \funref{equal} does not descend any \term{objects} other than the ones explicitly specified above. \Thenextfigure\ summarizes the information given in the previous list. % !!! Moon: Strange way to phrase it. In addition, the figure specifies the priority of the behavior of \funref{equal}, with upper entries taking priority over lower ones. \tablefigtwo{Summary and priorities of behavior of \funref{equal}}{Type}{Behavior}{ \term{number} & uses \funref{eql} \cr \term{character} & uses \funref{eql} \cr \term{cons} & descends \cr \term{bit vector} & descends \cr \term{string} & descends \cr \term{pathname} & ``functionally equivalent'' \cr \term{structure} & uses \funref{eq} \cr Other \term{array} & uses \funref{eq} \cr \term{hash table} & uses \funref{eq} \cr % Redundant. -kmp 3-Feb-92 % \term{standard object} & uses \funref{eq} \cr Other \term{object} & uses \funref{eq} \cr } \endissue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} Any two \term{objects} that are \funref{eql} are also \funref{equal}. \funref{equal} may fail to terminate if \param{x} or \param{y} is circular. \label Examples:: %% 6.3.0 19 \code (equal 'a 'b) \EV \term{false} (equal 'a 'a) \EV \term{true} (equal 3 3) \EV \term{true} (equal 3 3.0) \EV \term{false} (equal 3.0 3.0) \EV \term{true} (equal #c(3 -4) #c(3 -4)) \EV \term{true} (equal #c(3 -4.0) #c(3 -4)) \EV \term{false} (equal (cons 'a 'b) (cons 'a 'c)) \EV \term{false} (equal (cons 'a 'b) (cons 'a 'b)) \EV \term{true} (equal #\\A #\\A) \EV \term{true} (equal #\\A #\\a) \EV \term{false} (equal "Foo" "Foo") \EV \term{true} (equal "Foo" (copy-seq "Foo")) \EV \term{true} (equal "FOO" "foo") \EV \term{false} (equal "This-string" "This-string") \EV \term{true} (equal "This-string" "this-string") \EV \term{false} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \funref{eq}, \funref{eql}, \funref{equalp}, \funref{=}, \funref{string=}, \funref{string-equal}, \funref{char=}, \funref{char-equal}, \funref{tree-equal} \label Notes:: \issue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \term{Object} equality is not a concept for which there is a uniquely determined correct algorithm. The appropriateness of an equality predicate can be judged only in the context of the needs of some particular program. Although these functions take any type of argument and their names sound very generic, \funref{equal} and \funref{equalp} are not appropriate for every application. \endissue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} A rough rule of thumb is that two \term{objects} are \funref{equal} if and only if their printed representations are the same. \endcom %%% ========== EQUALP \begincom{equalp}\ftype{Function} \label Syntax:: \DefunWithValues equalp {x y} {generalized-boolean} \label Arguments and Values:: \param{x}---an \term{object}. \param{y}---an \term{object}. \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: %% 6.3.0 21 %% 6.3.0 22 Returns \term{true} if \param{x} and \param{y} are \funref{equal}, or if they have components that are of the same \term{type} as each other and if those components are \funref{equalp}; specifically, \funref{equalp} returns \term{true} in the following cases: \beginlist \itemitem{\term{Characters}} If two \term{characters} are \funref{char-equal}. \itemitem{\term{Numbers}} If two \term{numbers} are the \term{same} under \funref{=}. %% Change made due to v8 of EQUAL-STRUCTURE. -kmp 30-Jan-92 % have the same numerical value (even if they are of different % \term{types}), % or if they have components that are all \funref{equalp}. \itemitem{\term{Conses}} If the two \term{cars} in the \term{conses} are \funref{equalp} and the two \term{cdrs} in the \term{conses} are \funref{equalp}. %% Laubsch thinks this goes without saying (and I agree.) -kmp 19-Jan-92 %(defined recursively). \itemitem{\term{Arrays}} %% 6.3.0 23 If two \term{arrays} have the same number of dimensions, the dimensions match, and the corresponding %"components" => "active elements" -kmp 30-Jan-92 \term{active elements} are \funref{equalp}. The \term{types} for which the \term{arrays} are \term{specialized} need not match; for example, a \term{string} and a general \term{array} that happens to contain the same \term{characters} are \funref{equalp}. %% Not needed with "components" => "active elements" above. -kmp 30-Jan-92 % If either \param{x} or \param{y} has a \term{fill pointer}, % the \term{fill pointer} limits the number of elements examined by \funref{equalp}. Because \funref{equalp} performs \term{element}-by-\term{element} comparisons of \term{strings} and ignores the \term{case} of \term{characters}, \term{case} distinctions are ignored when \funref{equalp} compares \term{strings}. %% Barmar points out these are implied by the remarks about EQUAL in the first paragraph. % \itemitem{\term{Symbols}} % % %% 6.3.0 24 % If two \term{symbols} are \term{identical}. % %\issue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} % \itemitem{\term {Structures}, \term{Instances}, other} % % If two \term{structures}, \term{hash tables}, \term{instances}, % or other \term{objects} are \term{identical}. %\endissue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \issue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \itemitem{\term{Structures}} %% Here's the text of the cleanup issue. % EQUALP on two DEFSTRUCT objects 's1' and 's2', where one is a % non-:TYPEed DEFSTRUCT and the other is typed, is false. % % EQUALP on two DEFSTRUCT objects 's1' and 's2', where both are % non-:TYPEed DEFSTRUCTS is true iff: % % (1) The type of 's1' is the same as the type of 's2' (this is % the same as saying that the defstruct name for 's1' is the same % as that for 's2'). % % (2) The value of each slot of 's1' is EQUALP to the value of the % same slot of 's2' (where "same" means same name) (this is not the % %% This doesn't use the same wording as in the cleanup, but I couldn't figure %% out that wording. -kmp 30-Jan-92 If two \term{structures} $S\sub 1$ and $S\sub 2$ have the same \term{class} and the value of each \term{slot} in $S\sub 1$ is the \term{same} under \funref{equalp} as the value of the corresponding \term{slot} in $S\sub 2$. \itemitem{\term{Hash Tables}} %If two \term{hash tables} are \funref{equalp}. \funref{equalp} descends \term{hash-tables} by first comparing the count of entries and the \kwd{test} function; if those are the same, it compares the keys of the tables using the \kwd{test} function and then the values of the matching keys using \funref{equalp} recursively. \endissue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \endlist \issue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \funref{equalp} does not descend any \term{objects} other than the ones explicitly specified above. \Thenextfigure\ summarizes the information given in the previous list. In addition, the figure specifies the priority of the behavior of \funref{equalp}, with upper entries taking priority over lower ones. \tablefigtwo{Summary and priorities of behavior of \funref{equalp}}{Type}{Behavior}{ \term{number} & uses \funref{=} \cr \term{character} & uses \funref{char-equal} \cr \term{cons} & descends \cr \term{bit vector} & descends \cr \term{string} & descends \cr \term{pathname} & same as \funref{equal} \cr \term{structure} & descends, as described above \cr Other \term{array} & descends \cr \term{hash table} & descends, as described above \cr %% This is redundant. -kmp 25-Aug-91 % \term{standard object} & uses \funref{eq} \cr Other \term{object} & uses \funref{eq} \cr } \endissue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \label Examples:: %% 6.3.0 25 \code (equalp 'a 'b) \EV \term{false} (equalp 'a 'a) \EV \term{true} (equalp 3 3) \EV \term{true} (equalp 3 3.0) \EV \term{true} (equalp 3.0 3.0) \EV \term{true} (equalp #c(3 -4) #c(3 -4)) \EV \term{true} (equalp #c(3 -4.0) #c(3 -4)) \EV \term{true} (equalp (cons 'a 'b) (cons 'a 'c)) \EV \term{false} (equalp (cons 'a 'b) (cons 'a 'b)) \EV \term{true} (equalp #\\A #\\A) \EV \term{true} (equalp #\\A #\\a) \EV \term{true} (equalp "Foo" "Foo") \EV \term{true} (equalp "Foo" (copy-seq "Foo")) \EV \term{true} (equalp "FOO" "foo") \EV \term{true} \endcode \code (setq array1 (make-array 6 :element-type 'integer :initial-contents '(1 1 1 3 5 7))) \EV #(1 1 1 3 5 7) (setq array2 (make-array 8 :element-type 'integer :initial-contents '(1 1 1 3 5 7 2 6) :fill-pointer 6)) \EV #(1 1 1 3 5 7) (equalp array1 array2) \EV \term{true} (setq vector1 (vector 1 1 1 3 5 7)) \EV #(1 1 1 3 5 7) (equalp array1 vector1) \EV \term{true} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \funref{eq}, \funref{eql}, \funref{equal}, \funref{=}, \funref{string=}, \funref{string-equal}, \funref{char=}, \funref{char-equal} \label Notes:: \issue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \term{Object} equality is not a concept for which there is a uniquely determined correct algorithm. The appropriateness of an equality predicate can be judged only in the context of the needs of some particular program. Although these functions take any type of argument and their names sound very generic, \funref{equal} and \funref{equalp} are not appropriate for every application. \endissue{EQUAL-STRUCTURE:MAYBE-STATUS-QUO} \endcom %%% ========== IDENTITY \begincom{identity}\ftype{Function} \label Syntax:: \DefunWithValues identity {object} {object} \label Arguments and Values:: \param{object}---an \term{object}. \label Description:: %% 25.5.0 2 Returns its argument \param{object}. \label Examples:: \code (identity 101) \EV 101 (mapcan #'identity (list (list 1 2 3) '(4 5 6))) \EV (1 2 3 4 5 6) \endcode \label Side Effects:\None! \label Affected By:\None! \label Exceptional Situations:\None! \label See Also:\None. \label Notes:: \funref{identity} is intended for use with functions that require a \term{function} as an argument. \f{(eql x (identity x))} returns \term{true} for all possible values of \param{x}, but \f{(eq x (identity x))} might return \term{false} when \param{x} is a \term{number} or \term{character}. \funref{identity} could be defined by \code (defun identity (x) x) \endcode \endcom %-------------------- Functional Composition -------------------- %%% ========== COMPLEMENT \begincom{complement}\ftype{Function} \issue{FUNCTION-COMPOSITION:JAN89-X3J13} \label Syntax:: \DefunWithValues complement {function} {complement-function} \label Arguments and Values:: \param{function}---a \term{function}. \param{complement-function}---a \term{function}. \label Description:: Returns a \term{function} that takes the same \term{arguments} as \param{function}, and has the same side-effect behavior as \param{function}, but returns only a single value: a \term{generalized boolean} with the opposite truth value of that which would be returned as the \term{primary value} of \param{function}. That is, when the \param{function} would have returned \term{true} as its \term{primary value} the \param{complement-function} returns \term{false}, and when the \param{function} would have returned \term{false} as its \term{primary value} the \param{complement-function} returns \term{true}. \label Examples:: \code (funcall (complement #'zerop) 1) \EV \term{true} (funcall (complement #'characterp) #\\A) \EV \term{false} (funcall (complement #'member) 'a '(a b c)) \EV \term{false} (funcall (complement #'member) 'd '(a b c)) \EV \term{true} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \funref{not} \label Notes:: \code (complement \i{x}) \EQ #'(lambda (&rest arguments) (not (apply \i{x} arguments))) \endcode In \clisp, functions with names like ``\f{\i{xxx}-if-not}'' are related to functions with names like ``\f{{\it xxx}-if}'' in that \code (\i{xxx}-if-not \i{f} . \i{arguments}) \EQ (\i{xxx}-if (complement \i{f}) . \i{arguments}) \endcode For example, \code (find-if-not #'zerop '(0 0 3)) \EQ (find-if (complement #'zerop) '(0 0 3)) \EV 3 \endcode Note that since the ``\f{\i{xxx}-if-not}'' \term{functions} and the \kwd{test-not} arguments have been deprecated, uses of ``\f{\i{xxx}-if}'' \term{functions} or \kwd{test} arguments with \funref{complement} are preferred. \endissue{FUNCTION-COMPOSITION:JAN89-X3J13} \endcom %%% ========== CONSTANTLY \begincom{constantly}\ftype{Function} \issue{FUNCTION-COMPOSITION:JAN89-X3J13} \label Syntax:: \DefunWithValues constantly {value} {function} \label Arguments and Values:: \param{value}---an \term{object}. \param{function}---a \term{function}. \label Description:: \funref{constantly} returns a \term{function} that accepts any number of arguments, that has no side-effects, and that always returns \param{value}. \label Examples:: \code (mapcar (constantly 3) '(a b c d)) \EV (3 3 3 3) (defmacro with-vars (vars &body forms) `((lambda ,vars ,@forms) ,@(mapcar (constantly nil) vars))) \EV WITH-VARS (macroexpand '(with-vars (a b) (setq a 3 b (* a a)) (list a b))) \EV ((LAMBDA (A B) (SETQ A 3 B (* A A)) (LIST A B)) NIL NIL), \term{true} \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: %% "not" => "identity" per Boyer/Kaufmann/Moore #10 (by X3J13 vote at May 4-5, 1994 meeting) %% -kmp 9-May-94 \funref{identity} \label Notes:: \funref{constantly} could be defined by: \code (defun constantly (object) #'(lambda (&rest arguments) object)) \endcode \endissue{FUNCTION-COMPOSITION:JAN89-X3J13} \endcom %-------------------- Boolean Composition -------------------- %%% ========== EVERY %%% ========== SOME %%% ========== NOTEVERY %%% ========== NOTANY \begincom{every, some, notevery, notany}\ftype{Function} \label Syntax:: %Moon: "result"=>"boolean" in NOTEVERY \DefunWithValues every {predicate {\rest} \plus{sequences}} {generalized-boolean} \DefunWithValues some {predicate {\rest} \plus{sequences}} {result} \DefunWithValues notevery {predicate {\rest} \plus{sequences}} {generalized-boolean} \DefunWithValues notany {predicate {\rest} \plus{sequences}} {generalized-boolean} \label Arguments and Values:: \param{predicate}---a \term{designator} for a \term{function} of as many \term{arguments} as there are \param{sequences}. \param{sequence}---a \term{sequence}. \param{result}---an \term{object}. \param{generalized-boolean}---a \term{generalized boolean}. \label Description:: %% 14.2.0 10 %% 14.2.0 11 \funref{every}, \funref{some}, \funref{notevery}, and \funref{notany} test \term{elements} of \param{sequences} for satisfaction of a given \param{predicate}. %% Redundant with arg info. % These \term{functions} % operate on as many \param{sequences} as the given \param{predicate} % takes \term{arguments}. The first argument to \param{predicate} is an \term{element} of the first \param{sequence}; each succeeding argument is an \term{element} of a succeeding \param{sequence}. \param{Predicate} is first applied to the elements with index \f{0} in each of the \param{sequences}, and possibly then to the elements with index \f{1}, and so on, until a termination criterion is met or the end of the shortest of the \param{sequences} is reached. %% 14.2.0 13 \funref{every} returns \term{false} as soon as any invocation of \param{predicate} returns \term{false}. If the end of a \param{sequence} is reached, \funref{every} returns \term{true}. Thus, \funref{every} returns \term{true} if and only if every invocation of \param{predicate} returns \term{true}. \funref{some} returns the first \term{non-nil} value which is returned by an invocation of \param{predicate}. If the end of a \param{sequence} is reached without any invocation of the \param{predicate} returning \term{true}, \funref{some} returns \term{false}. Thus, \funref{some} returns \term{true} if and only if some invocation of \param{predicate} returns \term{true}. %% 14.2.0 14 \funref{notany} returns \term{false} as soon as any invocation of \param{predicate} returns \term{true}. If the end of a \param{sequence} is reached, \funref{notany} returns \term{true}. Thus, \funref{notany} returns \term{true} if and only if it is not the case that any invocation of \param{predicate} returns \term{true}. %% 14.2.0 15 \funref{notevery} returns \term{true} as soon as any invocation of \param{predicate} returns \term{false}. If the end of a \param{sequence} is reached, \funref{notevery} returns \term{false}. Thus, \funref{notevery} returns \term{true} if and only if it is not the case that every invocation of \param{predicate} returns \term{true}. \label Examples:: \code (every #'characterp "abc") \EV \term{true} (some #'= '(1 2 3 4 5) '(5 4 3 2 1)) \EV \term{true} (notevery #'< '(1 2 3 4) '(5 6 7 8) '(9 10 11 12)) \EV \term{false} (notany #'> '(1 2 3 4) '(5 6 7 8) '(9 10 11 12)) \EV \term{true} \endcode \label Affected By:\None. \label Exceptional Situations:: Should signal \typeref{type-error} if its first argument is neither a \term{symbol} nor a \term{function} or if any subsequent argument is not a \term{proper sequence}. Other exceptional situations are possible, depending on the nature of the \param{predicate}. \label See Also:: \macref{and}, \macref{or}, \issue{MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE} {\secref\TraversalRules} \endissue{MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE} \label Notes:: \code (notany \param{predicate} \starparam{sequence}) \EQ (not (some \param{predicate} \starparam{sequence})) (notevery \param{predicate} \starparam{sequence}) \EQ (not (every \param{predicate} \starparam{sequence})) \endcode \endcom %-------------------- Conditionals -------------------- %%% ========== AND \begincom{and}\ftype{Macro} \label Syntax:: \DefmacWithValues and {\starparam{form}} {\starparam{result}} \label Arguments and Values:: \param{form}---a \term{form}. %!!! Look more at this. \param{results}---the \term{values} resulting from the evaluation of the last \param{form}, or the symbols \nil\ or \t. \label Description:: %% 6.4.0 5 The macro \macref{and} evaluates each \param{form} one at a time from left to right. As soon as any \param{form} evaluates to \nil, \macref{and} returns \nil\ without evaluating the remaining \param{forms}. If all \param{forms} but the last evaluate to \term{true} values, \macref{and} returns the results produced by evaluating the last \param{form}. If no \param{forms} are supplied, \f{(and)} returns \t. %% 7.9.2 9 \macref{and} passes back multiple values from the last \term{subform} but not from subforms other than the last. \label Examples:: \code (if (and (>= n 0) (< n (length a-simple-vector)) (eq (elt a-simple-vector n) 'foo)) (princ "Foo!")) \endcode The above expression prints \f{Foo!} if element \f{n} of \f{a-simple-vector} is the symbol \f{foo}, provided also that \f{n} is indeed a valid index for \f{a-simple-vector}. Because \macref{and} guarantees left-to-right testing of its parts, \funref{elt} is not called if \f{n} is out of range. \code (setq temp1 1 temp2 1 temp3 1) \EV 1 (and (incf temp1) (incf temp2) (incf temp3)) \EV 2 (and (eql 2 temp1) (eql 2 temp2) (eql 2 temp3)) \EV \term{true} (decf temp3) \EV 1 (and (decf temp1) (decf temp2) (eq temp3 'nil) (decf temp3)) \EV NIL (and (eql temp1 temp2) (eql temp2 temp3)) \EV \term{true} (and) \EV T \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{cond}, \funref{every}, \specref{if}, \macref{or}, \macref{when} \label Notes:: % The first example is wrong because it violates issue % MACRO-SUBFORMS-TOP-LEVEL-P. --sjl 5 Mar 92 % \code % (and \param{form}) \EQ \param{form} % (and \param{form1} \param{form2} ...) \EQ (when \param{form1} (and \param{form2} ...)) %\endcode \code (and \param{form}) \EQ (let () \param{form}) (and \param{form1} \param{form2} ...) \EQ (when \param{form1} (and \param{form2} ...)) \endcode \endcom %%% ========== COND \begincom{cond}\ftype{Macro} \label Syntax:: %% 7.6.0 7 \DefmacWithValues cond {\stardown{clause}} {\starparam{result}} \auxbnf{clause}{\paren{test-form \starparam{form}}} \label Arguments and Values:: \param{test-form}---a \term{form}. \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} of the \param{forms} in the first \param{clause} whose \param{test-form} \term{yields} \term{true}, or the \term{primary value} of the \param{test-form} if there are no \param{forms} in that \param{clause}, or else \nil\ if no \param{test-form} \term{yields} \term{true}. \label Description:: \macref{cond} allows the execution of \param{forms} to be dependent on \param{test-form}. \param{Test-forms} are evaluated one at a time in the order in which they are given in the argument list until a \param{test-form} is found that evaluates to \term{true}. %% 7.6.0 8 If there are no \term{forms} in that clause, the \term{primary value} of the \param{test-form} is returned by the \macref{cond} \term{form}. Otherwise, the \param{forms} associated with this \param{test-form} are evaluated in order, left to right, as an \term{implicit progn}, and the \term{values} returned by the last \param{form} are returned by the \macref{cond} \term{form}. Once one \param{test-form} has \term{yielded} \term{true}, no additional \param{test-forms} are \term{evaluated}. If no \param{test-form} \term{yields} \term{true}, \nil\ is returned. \label Examples:: \code (defun select-options () (cond ((= a 1) (setq a 2)) ((= a 2) (setq a 3)) ((and (= a 3) (floor a 2))) (t (floor a 3)))) \EV SELECT-OPTIONS (setq a 1) \EV 1 (select-options) \EV 2 a \EV 2 (select-options) \EV 3 a \EV 3 (select-options) \EV 1 (setq a 5) \EV 5 (select-options) \EV 1, 2 \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{if}, \macref{case}. \label Notes:\None. \endcom %%% ========== IF \begincom{if}\ftype{Special Operator} \label Syntax:: \DefspecWithValues if {\param{test-form} \param{then-form} \brac{\param{else-form}}} {\starparam{result}} \label Arguments and Values:: \param{Test-form}---a \term{form}. \param{Then-form}---a \term{form}. %% 7.6.0 4 \param{Else-form}---a \term{form}. \Default{\nil} %% 7.9.2 7 %% 7.9.2 8 \param{results}---if the \param{test-form} \term{yielded} \term{true}, the \term{values} returned by the \param{then-form}; otherwise, the \term{values} returned by the \param{else-form}. \label Description:: \specref{if} allows the execution of a \term{form} to be dependent on a single \param{test-form}. %% 7.6.0 3 First \param{test-form} is evaluated. If the result is \term{true}, then \param{then-form} is selected; otherwise \param{else-form} is selected. Whichever form is selected is then evaluated. \label Examples:: \code (if t 1) \EV 1 (if nil 1 2) \EV 2 (defun test () (dolist (truth-value '(t nil 1 (a b c))) (if truth-value (print 'true) (print 'false)) (prin1 truth-value))) \EV TEST (test) \OUT TRUE T \OUT FALSE NIL \OUT TRUE 1 \OUT TRUE (A B C) \EV NIL \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{cond}, \macref{unless}, \macref{when} \label Notes:: %!!! Barmar thinks we should encourage implementations to signal an error or issue a % warning if additional subforms are detected. \code (if \param{test-form} \param{then-form} \param{else-form}) \EQ (cond (\param{test-form} \param{then-form}) (t \param{else-form})) \endcode \endcom %%% ========== OR \begincom{or}\ftype{Macro} \label Syntax:: \DefmacWithValues or {\starparam{form}} {\starparam{results}} \label Arguments and Values:: \param{form}---a \term{form}. %!!! Look more at this. \param{results}---the \term{values} or \term{primary value} (see below) resulting from the evaluation of the last \param{form} executed or \nil. \label Description:: %% 6.4.0 11 \macref{or} evaluates each \param{form}, one at a time, from left to right. The evaluation of all \param{forms} terminates when a \param{form} evaluates to \term{true} (\ie something other than \nil). If the \term{evaluation} of any \param{form} other than the last returns a \term{primary value} that is \term{true}, \macref{or} immediately returns that \term{value} (but no additional \term{values}) without evaluating the remaining \param{forms}. If every \param{form} but the last returns \term{false} as its \term{primary value}, \macref{or} returns all \term{values} returned by the last \param{form}. If no \param{forms} are supplied, \macref{or} returns \nil. % I've rewritten the above so that this is now implied. -kmp 1-Jan-91 % %% 7.9.2 9 % \macref{or} returns multiple values from % the last \param{form} % but not from \param{forms} other than the last. \label Examples:: \code (or) \EV NIL (setq temp0 nil temp1 10 temp2 20 temp3 30) \EV 30 (or temp0 temp1 (setq temp2 37)) \EV 10 temp2 \EV 20 (or (incf temp1) (incf temp2) (incf temp3)) \EV 11 temp1 \EV 11 temp2 \EV 20 temp3 \EV 30 (or (values) temp1) \EV 11 (or (values temp1 temp2) temp3) \EV 11 (or temp0 (values temp1 temp2)) \EV 11, 20 (or (values temp0 temp1) (values temp2 temp3)) \EV 20, 30 \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{and}, \macref{some}, \macref{unless} \label Notes:\None. \endcom %%% ========== WHEN \begincom{when, unless}\ftype{Macro} \label Syntax:: \DefmacWithValues when {test-form \starparam{form}} {\starparam{result}} \DefmacWithValues unless {test-form \starparam{form}} {\starparam{result}} \label Arguments and Values:: \param{test-form}---a \term{form}. \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} of the \term{forms} in a \macref{when} \term{form} if the \param{test-form} \term{yields} \term{true} or in an \macref{unless} \term{form} if the \param{test-form} \term{yields} \term{false}; otherwise \nil. \label Description:: \macref{when} and \macref{unless} allow the execution of \param{forms} to be dependent on a single \param{test-form}. %% 7.6.0 5 In a \macref{when} \term{form}, if the \param{test-form} \term{yields} \term{true}, the \param{forms} are \term{evaluated} in order from left to right and the \term{values} returned by the \param{forms} are returned from the \macref{when} \term{form}. Otherwise, if the \param{test-form} \term{yields} \term{false}, the \param{forms} are not \term{evaluated}, and the \macref{when} \term{form} returns \nil. %% 7.6.0 6 In an \macref{unless} \term{form}, if the \param{test-form} \term{yields} \term{false}, the \param{forms} are \term{evaluated} in order from left to right and the \term{values} returned by the \param{forms} are returned from the \macref{unless} \term{form}. Otherwise, if the \param{test-form} \term{yields} \term{false}, the \param{forms} are not \term{evaluated}, and the \macref{unless} \term{form} returns \nil. \label Examples:: \code (when t 'hello) \EV HELLO (unless t 'hello) \EV NIL (when nil 'hello) \EV NIL (unless nil 'hello) \EV HELLO (when t) \EV NIL (unless nil) \EV NIL (when t (prin1 1) (prin1 2) (prin1 3)) \OUT 123 \EV 3 (unless t (prin1 1) (prin1 2) (prin1 3)) \EV NIL (when nil (prin1 1) (prin1 2) (prin1 3)) \EV NIL (unless nil (prin1 1) (prin1 2) (prin1 3)) \OUT 123 \EV 3 (let ((x 3)) (list (when (oddp x) (incf x) (list x)) (when (oddp x) (incf x) (list x)) (unless (oddp x) (incf x) (list x)) (unless (oddp x) (incf x) (list x)) (if (oddp x) (incf x) (list x)) (if (oddp x) (incf x) (list x)) (if (not (oddp x)) (incf x) (list x)) (if (not (oddp x)) (incf x) (list x)))) \EV ((4) NIL (5) NIL 6 (6) 7 (7)) \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{and}, \macref{cond}, \macref{if}, \macref{or} \label Notes:: \code (when \param{test} \plus{\curly{\param{form}}}) \EQ (and \param{test} (progn \plus{\curly{\param{form}}})) (when \param{test} \plus{\curly{\param{form}}}) \EQ (cond (\param{test} \plus{\curly{\param{form}}})) (when \param{test} \plus{\curly{\param{form}}}) \EQ (if \param{test} (progn \plus{\curly{\param{form}}}) nil) (when \param{test} \plus{\curly{\param{form}}}) \EQ (unless (not \param{test}) \plus{\curly{\param{form}}}) (unless \param{test} \plus{\curly{\param{form}}}) \EQ (cond ((not \param{test}) \plus{\curly{\param{form}}})) (unless \param{test} \plus{\curly{\param{form}}}) \EQ (if \param{test} nil (progn \plus{\curly{\param{form}}})) (unless \param{test} \plus{\curly{\param{form}}}) \EQ (when (not \param{test}) \plus{\curly{\param{form}}}) \endcode \endcom %-------------------- Dispatch -------------------- %%% ========== CASE %%% ========== CCASE %%% ========== ECASE %%% ========== OTHERWISE %%% ========== T \begincom{case, ccase, ecase}\ftype{Macro} \label Syntax:: \DefmacWithValues case {keyform \stardown{normal-clause} \brac{\down{otherwise-clause}}} {\starparam{result}} \DefmacWithValues ccase {keyplace \stardown{normal-clause}} {\starparam{result}} \DefmacWithValues ecase {keyform \stardown{normal-clause}} {\starparam{result}} \auxbnf{normal-clause}{\paren{keys \starparam{form}}} \auxbnf{otherwise-clause}{\paren{\curly{otherwise | t} \starparam{form}}} \auxbnf{clause}{normal-clause | otherwise-clause} \idxref{otherwise}\idxref{t} \label Arguments and Values:: %% 7.6.0 13 %% 7.6.0 14 \param{keyform}---a \term{form}; evaluated to produce a \param{test-key}. \param{keyplace}---a \term{form}; evaluated initially to produce a \param{test-key}. Possibly also used later as a \term{place} if no \param{keys} match. \param{test-key}---an object produced by evaluating \param{keyform} or \param{keyplace}. \param{keys}---a \term{designator} for a \term{list} of \term{objects}. In the case of \macref{case}, the \term{symbols} \t\ and \misc{otherwise} may not be used as the \param{keys} \term{designator}. To refer to these \term{symbols} by themselves as \param{keys}, the designators \f{(t)} and \f{(otherwise)}, respectively, must be used instead. \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} returned by the \param{forms} in the matching \param{clause}. \label Description:: %% 7.6.0 11 These \term{macros} allow the conditional execution of a body of \param{forms} in a \param{clause} that is selected by matching the \param{test-key} on the basis of its identity. %% 7.6.0 12 The \param{keyform} or \param{keyplace} is \term{evaluated} to produce the \param{test-key}. Each of the \param{normal-clauses} is then considered in turn. If the \param{test-key} is the \term{same} as any \term{key} for that \param{clause}, the \param{forms} in that \param{clause} are \param{evaluated} as an \term{implicit progn}, and the \term{values} it returns are returned as the value of the \macref{case}, \macref{ccase}, or \macref{ecase} \term{form}. These \term{macros} differ only in their \term{behavior} when no \param{normal-clause} matches; specifically: \beginlist \itemitem{\macref{case}} If no \param{normal-clause} matches, and there is an \param{otherwise-clause}, then that \param{otherwise-clause} automatically matches; the \param{forms} in that \param{clause} are \param{evaluated} as an \term{implicit progn}, and the \term{values} it returns are returned as the value of the \macref{case}. If there is no \param{otherwise-clause}, \macref{case} returns \nil. \itemitem{\macref{ccase}} %% 7.6.0 15 If no \param{normal-clause} matches, a \term{correctable} \term{error} \oftype{type-error} is signaled. The offending datum is the \param{test-key} and the expected type is \term{type equivalent} to \f{(member \param{key1} \param{key2} ...)}. \Therestart{store-value} can be used to correct the error. If \therestart{store-value} is invoked, its \term{argument} becomes the new \param{test-key}, and is stored in \param{keyplace} as if by \f{(setf \param{keyplace} \param{test-key})}. Then \macref{ccase} starts over, considering each \param{clause} anew. \reviewer{Barmar: Will it prompt for multiple values if keyplace is a VALUES general ref?}%!!! The subforms of \param{keyplace} might be evaluated again if none of the cases holds. \itemitem{\macref{ecase}} If no \param{normal-clause} matches, a \term{non-correctable} \term{error} \oftype{type-error} is signaled. The offending datum is the \param{test-key} and the expected type is \term{type equivalent} to \f{(member \param{key1} \param{key2} ...)}. Note that in contrast with \macref{ccase}, the caller of \macref{ecase} may rely on the fact that \macref{ecase} does not return if a \param{normal-clause} does not match. \endlist \label Examples:: \code (dolist (k '(1 2 3 :four #\\v () t 'other)) (format t "~S " (case k ((1 2) 'clause1) (3 'clause2) (nil 'no-keys-so-never-seen) ((nil) 'nilslot) ((:four #\\v) 'clause4) ((t) 'tslot) (otherwise 'others)))) \OUT CLAUSE1 CLAUSE1 CLAUSE2 CLAUSE4 CLAUSE4 NILSLOT TSLOT OTHERS \EV NIL (defun add-em (x) (apply #'+ (mapcar #'decode x))) \EV ADD-EM (defun decode (x) (ccase x ((i uno) 1) ((ii dos) 2) ((iii tres) 3) ((iv cuatro) 4))) \EV DECODE (add-em '(uno iii)) \EV 4 (add-em '(uno iiii)) \OUT Error: The value of X, IIII, is not I, UNO, II, DOS, III, \OUT TRES, IV, or CUATRO. \OUT 1: Supply a value to use instead. \OUT 2: Return to Lisp Toplevel. \OUT Debug> \IN{:CONTINUE 1} \OUT Value to evaluate and use for X: \IN{'IV} \EV 5 \endcode \label Side Effects:: The debugger might be entered. If \therestart{store-value} is invoked, the \term{value} of \param{keyplace} might be changed. \label Affected By:: \macref{ccase} and \macref{ecase}, since they might signal an error, are potentially affected by existing \param{handlers} and \varref{*debug-io*}. \label Exceptional Situations:: \macref{ccase} and \macref{ecase} signal an error \oftype{type-error} if no \param{normal-clause} matches. \label See Also:: \macref{cond}, \macref{typecase}, \macref{setf}, {\secref\GeneralizedReference} \label Notes:: \code (case \param{test-key} \star{\curly{((\starparam{key}) \starparam{form})}}) \EQ (let ((#1=#:g0001 \param{test-key})) (cond \star{\curly{((member #1# '(\starparam{key})) \starparam{form})}})) \endcode The specific error message used by \macref{ecase} and \macref{ccase} can vary between implementations. In situations where control of the specific wording of the error message is important, it is better to use \macref{case} with an \param{otherwise-clause} that explicitly signals an error with an appropriate message. \endcom %%% ========== TYPECASE %%% ========== CTYPECASE %%% ========== ETYPECASE %%% ========== OTHERWISE %%% ========== T \begincom{typecase, ctypecase, etypecase}\ftype{Macro} \label Syntax:: \DefmacWithValues {typecase} {keyform \stardown{normal-clause} \brac{\down{otherwise-clause}}} {\starparam{result}} \DefmacWithValues {ctypecase} {keyplace \stardown{normal-clause}} {\starparam{result}} \DefmacWithValues {etypecase} {keyform \stardown{normal-clause}} {\starparam{result}} \auxbnf{normal-clause}{\paren{type \starparam{form}}} \auxbnf{otherwise-clause}{\paren{\curly{otherwise | t} \starparam{form}}} \auxbnf{clause}{normal-clause | otherwise-clause} \idxref{otherwise}\idxref{t} \label Arguments and Values:: %% 7.6.0 13 %% 7.6.0 14 \param{keyform}---a \term{form}; evaluated to produce a \param{test-key}. \param{keyplace}---a \term{form}; evaluated initially to produce a \param{test-key}. Possibly also used later as a \term{place} if no \param{types} match. \param{test-key}---an object produced by evaluating \param{keyform} or \param{keyplace}. \param{type}---a \term{type specifier}. \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} returned by the \param{forms} in the matching \param{clause}. \label Description:: %% 7.6.0 18 %% 7.6.0 19 %% 7.6.0 20 These \term{macros} allow the conditional execution of a body of \param{forms} in a \param{clause} that is selected by matching the \param{test-key} on the basis of its \term{type}. The \param{keyform} or \param{keyplace} is \term{evaluated} to produce the \param{test-key}. Each of the \param{normal-clauses} is then considered in turn. If the \param{test-key} is of the \term{type} given by the \param{clauses}'s \param{type}, the \param{forms} in that \param{clause} are \param{evaluated} as an \term{implicit progn}, and the \term{values} it returns are returned as the value of the \macref{typecase}, \macref{ctypecase}, or \macref{etypecase} \term{form}. These \term{macros} differ only in their \term{behavior} when no \param{normal-clause} matches; specifically: \beginlist \itemitem{\macref{typecase}} If no \param{normal-clause} matches, and there is an \param{otherwise-clause}, then that \param{otherwise-clause} automatically matches; the \param{forms} in that \param{clause} are \param{evaluated} as an \term{implicit progn}, and the \term{values} it returns are returned as the value of the \macref{typecase}. If there is no \param{otherwise-clause}, \macref{typecase} returns \nil. \itemitem{\macref{ctypecase}} If no \param{normal-clause} matches, a \term{correctable} \term{error} \oftype{type-error} is signaled. The offending datum is the \param{test-key} and the expected type is \term{type equivalent} to \f{(or \param{type1} \param{type2} ...)}. \Therestart{store-value} can be used to correct the error. If \therestart{store-value} is invoked, its \term{argument} becomes the new \param{test-key}, and is stored in \param{keyplace} as if by \f{(setf \param{keyplace} \param{test-key})}. Then \macref{ctypecase} starts over, considering each \param{clause} anew. If \therestart{store-value} is invoked interactively, the user is prompted for a new \param{test-key} to use. The subforms of \param{keyplace} might be evaluated again if none of the cases holds. \itemitem{\macref{etypecase}} If no \param{normal-clause} matches, a \term{non-correctable} \term{error} \oftype{type-error} is signaled. The offending datum is the \param{test-key} and the expected type is \term{type equivalent} to \f{(or \param{type1} \param{type2} ...)}. Note that in contrast with \macref{ctypecase}, the caller of \macref{etypecase} may rely on the fact that \macref{etypecase} does not return if a \param{normal-clause} does not match. \endlist %% 7.6.0 22 In all three cases, is permissible for more than one \param{clause} to specify a matching \term{type}, particularly if one is a \term{subtype} of another; the earliest applicable \param{clause} is chosen. \label Examples:: \code ;;; (Note that the parts of this example which use TYPE-OF ;;; are implementation-dependent.) (defun what-is-it (x) (format t "~&~S is ~A.~%" x (typecase x (float "a float") (null "a symbol, boolean false, or the empty list") (list "a list") (t (format nil "a(n) ~(~A~)" (type-of x)))))) \EV WHAT-IS-IT (map 'nil #'what-is-it '(nil (a b) 7.0 7 box)) \OUT NIL is a symbol, boolean false, or the empty list. \OUT (A B) is a list. \OUT 7.0 is a float. \OUT 7 is a(n) integer. \OUT BOX is a(n) symbol. \EV NIL (setq x 1/3) \EV 1/3 (ctypecase x (integer (* x 4)) (symbol (symbol-value x))) \OUT Error: The value of X, 1/3, is neither an integer nor a symbol. \OUT To continue, type :CONTINUE followed by an option number: \OUT 1: Specify a value to use instead. \OUT 2: Return to Lisp Toplevel. \OUT Debug> \IN{:CONTINUE 1} \OUT Use value: \IN{3.7} \OUT Error: The value of X, 3.7, is neither an integer nor a symbol. \OUT To continue, type :CONTINUE followed by an option number: \OUT 1: Specify a value to use instead. \OUT 2: Return to Lisp Toplevel. \OUT Debug> \IN{:CONTINUE 1} \OUT Use value: \IN{12} \EV 48 x \EV 12 \endcode \label Affected By:: \macref{ctypecase} and \macref{etypecase}, since they might signal an error, are potentially affected by existing \param{handlers} and \varref{*debug-io*}. \label Exceptional Situations:: \macref{ctypecase} and \macref{etypecase} signal an error \oftype{type-error} if no \param{normal-clause} matches. The \term{compiler} may choose to issue a warning \oftype{style-warning} if a \param{clause} will never be selected because it is completely shadowed by earlier clauses. \label See Also:: \macref{case}, \macref{cond}, \macref{setf}, {\secref\GeneralizedReference} \label Notes:: \code (typecase \param{test-key} \star{\curly{(\param{type} \starparam{form})}}) \EQ (let ((#1=#:g0001 \param{test-key})) (cond \star{\curly{((typep #1# '\param{type}) \starparam{form})}})) \endcode The specific error message used by \macref{etypecase} and \macref{ctypecase} can vary between implementations. In situations where control of the specific wording of the error message is important, it is better to use \macref{typecase} with an \param{otherwise-clause} that explicitly signals an error with an appropriate message. \endcom %-------------------- Multiple Values -------------------- %%% ========== MULTIPLE-VALUE-BIND \begincom{multiple-value-bind}\ftype{Macro} \issue{DECLS-AND-DOC} \label Syntax:: \DefmacWithValuesNewline multiple-value-bind {\paren{\starparam{var}} \param{values-form} \starparam{declaration} \starparam{form}} {\starparam{result}} \label Arguments and Values:: \param{var}---a \term{symbol} naming a variable; \noeval. \param{values-form}---a \term{form}; \eval. \param{declaration}---a \misc{declare} \term{expression}; \noeval. \param{forms}---an \term{implicit progn}. \param{results}---the \term{values} returned by the \param{forms}. \label Description:: Creates new variable \term{bindings} for the \param{vars} and executes a series of \param{forms} that use these \term{bindings}. The variable \term{bindings} created are lexical unless \declref{special} declarations are specified. %% 7.9.1 13 \param{Values-form} is evaluated, and each of the \param{vars} is bound to the respective value returned by that \term{form}. If there are more \param{vars} than values returned, extra values of \nil\ are given to the remaining \param{vars}. If there are more values than \param{vars}, the excess values are discarded. The \param{vars} are bound to the values over the execution of the \param{forms}, which make up an implicit \specref{progn}. The consequences are unspecified if a type \param{declaration} is specified for a \param{var}, but the value to which that \param{var} is bound is not consistent with the type \param{declaration}. The \term{scopes} of the name binding and \param{declarations} do not include the \param{values-form}. % KMP: Surely this must refer only to bound declarations. % Moon: No, the stupid DECLARATION-SCOPE:NO-HOISTING vote made it this way. \label Examples:: \code (multiple-value-bind (f r) (floor 130 11) (list f r)) \EV (11 9) \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{let}, \specref{multiple-value-call} \label Notes:: \code (multiple-value-bind (\starparam{var}) \param{values-form} \starparam{form}) \EQ (multiple-value-call #'(lambda (&optional \starparam{var} &rest #1=#:ignore) (declare (ignore #1#)) \starparam{form}) \param{values-form}) \endcode \endissue{DECLS-AND-DOC} \endcom %%% ========== MULTIPLE-VALUE-CALL \begincom{multiple-value-call}\ftype{Special Operator} \label Syntax:: \DefspecWithValues multiple-value-call {\param{function-form} \star{\param{form}}} {\starparam{result}} \label Arguments and Values:: \param{function-form}---a \term{form}; evaluated to produce \param{function}. \param{function}---a \term{function designator} resulting from the evaluation of \param{function-form}. \param{form}---a \term{form}. %% 7.9.2 5 \param{results}---the \term{values} returned by the \param{function}. \label Description:: Applies \param{function} to a \term{list} of the \term{objects} collected from groups of \term{multiple values}\meaning{2}. %% 7.9.1 11 \specref{multiple-value-call} first evaluates the \param{function-form} to obtain \param{function}, and then evaluates each \param{form}. All the values of each \param{form} are gathered together (not just one value from each) and given as arguments to the \param{function}. \label Examples:: \code (multiple-value-call #'list 1 '/ (values 2 3) '/ (values) '/ (floor 2.5)) \EV (1 / 2 3 / / 2 0.5) (+ (floor 5 3) (floor 19 4)) \EQ (+ 1 4) \EV 5 (multiple-value-call #'+ (floor 5 3) (floor 19 4)) \EQ (+ 1 2 4 3) \EV 10 \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{multiple-value-list}, \macref{multiple-value-bind} \label Notes:\None. \endcom %%% ========== MULTIPLE-VALUE-LIST \begincom{multiple-value-list}\ftype{Macro} \label Syntax:: \DefmacWithValues multiple-value-list {form} {list} \label Arguments and Values:: \param{form}---a \term{form}; \evalspecial. \param{list}---a \term{list} of the \term{values} returned by \param{form}. \label Description:: %% 7.9.1 10 \macref{multiple-value-list} evaluates \param{form} and creates a \term{list} of the \term{multiple values}\meaning{2} it returns. \label Examples:: \code (multiple-value-list (floor -3 4)) \EV (-1 1) \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \funref{values-list}, \specref{multiple-value-call} \label Notes:: \macref{multiple-value-list} and \funref{values-list} are inverses of each other. \code (multiple-value-list form) \EQ (multiple-value-call #'list form) \endcode \endcom %%% ========== MULTIPLE-VALUE-PROG1 \begincom{multiple-value-prog1}\ftype{Special Operator} \label Syntax:: \DefspecWithValues multiple-value-prog1 {first-form \starparam{form}} {first-form-results} \label Arguments and Values:: \param{first-form}---a \term{form}; \evalspecial. \param{form}---a \term{form}; \evalspecial. %% 7.9.2 17 \param{first-form-results}---the \term{values} resulting from the \term{evaluation} of \param{first-form}. \label Description:: %% 7.9.1 12 \macref{multiple-value-prog1} evaluates \param{first-form} and saves all the values produced by that \term{form}. It then evaluates each \param{form} from left to right, discarding their values. \label Examples:: \code (setq temp '(1 2 3)) \EV (1 2 3) (multiple-value-prog1 (values-list temp) (setq temp nil) (values-list temp)) \EV 1, 2, 3 \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{prog1} \label Notes:\None. \endcom %%% ========== MULTIPLE-VALUE-SETQ \begincom{multiple-value-setq}\ftype{Macro} \label Syntax:: \DefmacWithValues multiple-value-setq {vars form} {result} \label Arguments and Values:: \param{vars}---a \term{list} of \term{symbols} that are either \term{variable} \term{names} or \term{names} of \term{symbol macros}. \param{form}---a \term{form}. %% 7.9.1 17 \param{result}---The \term{primary value} returned by the \param{form}. \label Description:: \macref{multiple-value-setq} assigns values to \param{vars}. %% 7.9.1 15 The \param{form} is evaluated, and each \param{var} is \term{assigned} to the corresponding \term{value} returned by that \term{form}. If there are more \param{vars} than \term{values} returned, \nil\ is \term{assigned} to the extra \param{vars}. If there are more \term{values} than \param{vars}, the extra \term{values} are discarded. \issue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM} If any \param{var} is the \term{name} of a \term{symbol macro}, then it is \term{assigned} as if by \macref{setf}. Specifically, \issue{MULTIPLE-VALUE-SETQ-ORDER:LIKE-SETF-OF-VALUES} \begingroup \def\subOne{$\sub1$} \def\subN{$\sub{n}$} \code (multiple-value-setq (\i{symbol}\subOne ... \i{symbol}\subN) \i{value-producing-form}) \endcode is defined to always behave in the same way as \code (values (setf (values \i{symbol}\subOne ... \i{symbol}\subN) \i{value-producing-form})) \endcode \endgroup in order that the rules for order of evaluation and side-effects be consistent with those used by \macref{setf}.\idxtext{order of evaluation}\idxtext{evaluation order} % added --sjl 4 Mar 92 \Seesection\SETFofVALUES. \endissue{MULTIPLE-VALUE-SETQ-ORDER:LIKE-SETF-OF-VALUES} \endissue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM} \label Examples:: \code (multiple-value-setq (quotient remainder) (truncate 3.2 2)) \EV 1 quotient \EV 1 remainder \EV 1.2 (multiple-value-setq (a b c) (values 1 2)) \EV 1 a \EV 1 b \EV 2 c \EV NIL (multiple-value-setq (a b) (values 4 5 6)) \EV 4 a \EV 4 b \EV 5 \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{setq}, \specref{symbol-macrolet} \label Notes:\None. \endcom %%% ========== VALUES % incorporated issue SETF-OF-VALUES --sjl 4 Mar 92 \begincom{values}\ftype{Accessor} \label Syntax:: \DefunWithValues values {{\rest} object} {\starparam{object}} \issue{SETF-OF-VALUES:ADD} \Defsetf values {{\rest} place} {new-values} \endissue{SETF-OF-VALUES:ADD} \label Arguments and Values:: \param{object}---an \term{object}. \issue{SETF-OF-VALUES:ADD} \param{place}---a \term{place}. \param{new-value}---an \term{object}. \endissue{SETF-OF-VALUES:ADD} \label Description:: %% 7.9.1 4 %% 7.9.1 5 \funref{values} returns the \param{objects} as \term{multiple values}\meaning{2}. \issue{SETF-OF-VALUES:ADD} \macref{setf} of \funref{values} is used to store the \term{multiple values}\meaning{2} \param{new-values} into the \param{places}. \Seesection\SETFofVALUES. \endissue{SETF-OF-VALUES:ADD} \label Examples:: \code (values) \EV \novalues (values 1) \EV 1 (values 1 2) \EV 1, 2 (values 1 2 3) \EV 1, 2, 3 (values (values 1 2 3) 4 5) \EV 1, 4, 5 (defun polar (x y) (values (sqrt (+ (* x x) (* y y))) (atan y x))) \EV POLAR (multiple-value-bind (r theta) (polar 3.0 4.0) (vector r theta)) \EV #(5.0 0.927295) \endcode %% 7.9.1 6 Sometimes it is desirable to indicate explicitly that a function returns exactly one value. For example, the function \code (defun foo (x y) (floor (+ x y) y)) \EV FOO \endcode returns two values because \funref{floor} returns two values. It may be that the second value makes no sense, or that for efficiency reasons it is desired not to compute the second value. \funref{values} is the standard idiom for indicating that only one value is to be returned: \code (defun foo (x y) (values (floor (+ x y) y))) \EV FOO \endcode This works because \funref{values} returns exactly one value for each of \param{args}; as for any function call, if any of \param{args} produces more than one value, all but the first are discarded. \label Affected By:\None! \label Exceptional Situations:\None! \label See Also:: \funref{values-list}, \macref{multiple-value-bind}, \conref{multiple-values-limit}, {\secref\Evaluation} \label Notes:: Since \funref{values} is a \term{function}, not a \term{macro} or \term{special form}, it receives as \term{arguments} only the \term{primary values} of its \term{argument} \term{forms}. \endcom %%% ========== VALUES-LIST \begincom{values-list}\ftype{Function} \label Syntax:: \DefunWithValues values-list {list} {\starparam{element}} \label Arguments and Values:: \param{list}---a \term{list}. \param{elements}---the \term{elements} of the \param{list}. \label Description:: %% 7.9.1 9 Returns the \term{elements} of the \param{list} as \term{multiple values}\meaning{2}. \label Examples:: \code (values-list nil) \EV \novalues (values-list '(1)) \EV 1 (values-list '(1 2)) \EV 1, 2 (values-list '(1 2 3)) \EV 1, 2, 3 \endcode \label Affected By:\None. \label Exceptional Situations:: Should signal \typeref{type-error} if its argument is not a \term{proper list}. %KMP: Isn't there also some issue to do with max number of values? %Moon: No different than in VALUES if (> CALL-ARGUMENTS-LIMIT MULTIPLE-VALUES-LIMIT). \label See Also:: \macref{multiple-value-bind}, \conref{multiple-value-list}, \conref{multiple-values-limit}, \funref{values} \label Notes:: \code (values-list \param{list}) \EQ (apply #'values \param{list}) \endcode \f{(equal \param{x} (multiple-value-list (values-list \param{x})))} returns \term{true} for all \term{lists} \param{x}. \endcom %%% ========== MULTIPLE-VALUES-LIMIT \begincom{multiple-values-limit}\ftype{Constant Variable} \label Constant Value:: An \term{integer} not smaller than \f{20}, the exact magnitude of which is \term{implementation-dependent}. \label Description:: %% 7.9.1 8 The upper exclusive bound on the number of \term{values} that may be returned from a \term{function}, \issue{MULTIPLE-VALUES-LIMIT-ON-VARIABLES:UNDEFINED} bound or assigned by \macref{multiple-value-bind} or \macref{multiple-value-setq}, or passed as a first argument to \macref{nth-value}. (If these individual limits might differ, the minimum value is used.) \endissue{MULTIPLE-VALUES-LIMIT-ON-VARIABLES:UNDEFINED} \label Examples:\None. \label See Also:: \conref{lambda-parameters-limit}, \conref{call-arguments-limit} \label Notes:: Implementors are encouraged to make this limit as large as possible. \endcom %%% ========== NTH-VALUE \begincom{nth-value}\ftype{Macro} \issue{NTH-VALUE:ADD} \label Syntax:: \DefmacWithValues nth-value {n form} {object} \label Arguments and Values:: \param{n}---a non-negative \term{integer}; \eval. \param{form}---a \term{form}; \evalspecial. \param{object}---an \term{object}. \label Description:: Evaluates \param{n} and then \param{form}, returning as its only value the \param{n}th value \term{yielded} by \param{form}, or \nil\ if \param{n} is greater than or equal to the number of \term{values} returned by \param{form}. (The first returned value is numbered \f{0}.) \label Examples:: \code (nth-value 0 (values 'a 'b)) \EV A (nth-value 1 (values 'a 'b)) \EV B (nth-value 2 (values 'a 'b)) \EV NIL (let* ((x 83927472397238947423879243432432432) (y 32423489732) (a (nth-value 1 (floor x y))) (b (mod x y))) (values a b (= a b))) \EV 3332987528, 3332987528, \term{true} \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{multiple-value-list}, \funref{nth} \label Notes:: Operationally, the following relationship is true, although \specref{nth-value} might be more efficient in some \term{implementations} because, for example, some \term{consing} might be avoided. \code (nth-value \param{n} \param{form}) \EQ (nth \param{n} (multiple-value-list \param{form})) \endcode \endissue{NTH-VALUE:ADD} \endcom %-------------------- Data and Control -------------------- %%% ========== PROG %%% ========== PROG* \begincom{prog, prog*}\ftype{Macro} \issue{DECLS-AND-DOC} \label Syntax:: \DefmacWithValuesNewline prog {\paren{\star{\curly{\param{var} $\vert$ \paren{\param{var} \brac{\param{init-form}}}}}} \starparam{declaration} \star{\curly{\param{tag} $\vert$ \param{statement}}}} {\starparam{result}} \DefmacWithValuesNewline {prog*} {\paren{\star{\curly{\param{var} $\vert$ \paren{\param{var} \brac{\param{init-form}}}}}} \starparam{declaration} \star{\curly{\param{tag} $\vert$ \param{statement}}}} {\starparam{result}} \label Arguments and Values:: \param{var}---variable name. \param{init-form}---a \term{form}. \param{declaration}---a \misc{declare} \term{expression}; \noeval. \param{tag}---a \term{go tag}; \noeval. \param{statement}---a \term{compound form}; \evalspecial. \param{results}---\nil\ if a \term{normal return} occurs, or else, if an \term{explicit return} occurs, the \term{values} that were transferred. \label Description:: %% 7.8.5 3 Three distinct operations are performed by \macref{prog} and \macref{prog*}: they bind local variables, they permit use of the \macref{return} statement, and they permit use of the \specref{go} statement. A typical \macref{prog} looks like this: \code (prog (var1 var2 (var3 init-form-3) var4 (var5 init-form-5)) \starparam{declaration} statement1 tag1 statement2 statement3 statement4 tag2 statement5 ... ) \endcode For \macref{prog}, \param{init-forms} are evaluated first, in the order in which they are supplied. The \param{vars} are then bound to the corresponding values in parallel. If no \param{init-form} is supplied for a given \param{var}, that \param{var} is bound to \nil. %% 7.8.5 11 The body of \macref{prog} is executed as if it were a \specref{tagbody} \term{form}; the \specref{go} statement can be used to transfer control to a \param{tag}. \param{Tags} label \param{statements}. %% 7.8.5 12 \macref{prog} implicitly establishes a \specref{block} named \nil\ around the entire \macref{prog} \term{form}, so that \macref{return} can be used at any time to exit from the \macref{prog} \term{form}. %% 7.8.5 15 The difference between \macref{prog*} and \macref{prog} is that in \macref{prog*} the \term{binding} and initialization of the \param{vars} is done \term{sequentially}, so that the \param{init-form} for each one can use the values of previous ones. % I don't think anything in this next paragraph hasn't been stated % elsewhere. --sjl 5 Mar 92 %Any \param{declaration} appearing in the \macref{prog} is used as %if appearing at the top of \specref{let}. %It is an error if a \term{type declaration} is supplied for a %\param{var} and the initial value of %that \param{var} is not consistent with the \param{declaration}. %Similarly, declarations in \macref{prog*} are like in \macref{let*}. %% Moon: Redundant. % For \macref{prog}, the % \term{scope} of the name binding does not include any % \param{init-form}. % For \macref{prog*}, a variable's \term{scope} also includes the % remaining \param{init-forms} for subsequent variable bindings. \label Examples:: \code (prog* ((y z) (x (car y))) (return x)) \endcode returns the \term{car} of the value of \f{z}. \code (setq a 1) \EV 1 (prog ((a 2) (b a)) (return (if (= a b) '= '/=))) \EV /= (prog* ((a 2) (b a)) (return (if (= a b) '= '/=))) \EV = (prog () 'no-return-value) \EV NIL \endcode %% 7.8.5 13 \code (defun king-of-confusion (w) "Take a cons of two lists and make a list of conses. Think of this function as being like a zipper." (prog (x y z) ;Initialize x, y, z to NIL (setq y (car w) z (cdr w)) loop (cond ((null y) (return x)) ((null z) (go err))) rejoin (setq x (cons (cons (car y) (car z)) x)) (setq y (cdr y) z (cdr z)) (go loop) err (cerror "Will self-pair extraneous items" "Mismatch - gleep! ~S" y) (setq z y) (go rejoin))) \EV KING-OF-CONFUSION \endcode This can be accomplished more perspicuously as follows: \code (defun prince-of-clarity (w) "Take a cons of two lists and make a list of conses. Think of this function as being like a zipper." (do ((y (car w) (cdr y)) (z (cdr w) (cdr z)) (x '\empty (cons (cons (car y) (car z)) x))) ((null y) x) (when (null z) (cerror "Will self-pair extraneous items" "Mismatch - gleep! ~S" y) (setq z y)))) \EV PRINCE-OF-CLARITY \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{block}, \specref{let}, \specref{tagbody}, \specref{go}, \macref{return}, {\secref\Evaluation} \label Notes:: %% 7.8.5 14 \macref{prog} can be explained in terms of \specref{block}, \specref{let}, and \specref{tagbody} as follows: \code (prog \param{variable-list} \param{declaration} . \param{body}) \EQ (block nil (let \param{variable-list} \param{declaration} (tagbody . \param{body}))) \endcode \endissue{DECLS-AND-DOC} \endcom %%% ========== PROG1 %%% ========== PROG2 \begincom{prog1, prog2}\ftype{Macro} \label Syntax:: \DefmacWithValues prog1 {first-form \starparam{form}} {result-1} \DefmacWithValues prog2 {first-form second-form \starparam{form}} {result-2} \label Arguments and Values:: \param{first-form}---a \term{form}; \evalspecial. \param{second-form}---a \term{form}; \evalspecial. \param{forms}---an \term{implicit progn}; \evalspecial. %% 7.4.0 8 \param{result-1}---the \term{primary value} resulting from the \term{evaluation} of \param{first-form}. %% 7.4.0 11 \param{result-2}---the \term{primary value} resulting from the \term{evaluation} of \param{second-form}. \label Description:: %% 7.4.0 6 \macref{prog1} \term{evaluates} \param{first-form} and then \param{forms}, \term{yielding} as its only \term{value} the \term{primary value} \term{yielded} by \param{first-form}. %% 7.4.0 9 \macref{prog2} \term{evaluates} \param{first-form}, then \param{second-form}, and then \param{forms}, \term{yielding} as its only \term{value} the \term{primary value} \term{yielded} by \param{first-form}. %% I hope this is implied by the above. -kmp 22-Oct-91 %The arguments are evaluated in the order in which they are given. \label Examples:: \code (setq temp 1) \EV 1 (prog1 temp (print temp) (incf temp) (print temp)) \OUT 1 \OUT 2 \EV 1 (prog1 temp (setq temp nil)) \EV 2 temp \EV NIL (prog1 (values 1 2 3) 4) \EV 1 (setq temp (list 'a 'b 'c)) (prog1 (car temp) (setf (car temp) 'alpha)) \EV A temp \EV (ALPHA B C) (flet ((swap-symbol-values (x y) (setf (symbol-value x) (prog1 (symbol-value y) (setf (symbol-value y) (symbol-value x)))))) (let ((*foo* 1) (*bar* 2)) (declare (special *foo* *bar*)) (swap-symbol-values '*foo* '*bar*) (values *foo* *bar*))) \EV 2, 1 (setq temp 1) \EV 1 (prog2 (incf temp) (incf temp) (incf temp)) \EV 3 temp \EV 4 (prog2 1 (values 2 3 4) 5) \EV 2 \endcode \label Side Effects:\None. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \specref{multiple-value-prog1}, \specref{progn} \label Notes:: %% 7.4.0 7 \macref{prog1} and \macref{prog2} are typically used to \term{evaluate} one or more \term{forms} with side effects and return a \term{value} that must be computed before some or all of the side effects happen. % The second example is wrong because it passes top-level-ness to form1, % which is forbidden by issue MACRO-SUBFORMS-TOP-LEVEL-P. --sjl 5 Mar 92 %\code % (prog1 \starparam{form}) \EQ (values (multiple-value-prog1 \starparam{form})) % (prog2 \param{form1} \starparam{form}) \EQ (progn \param{form1} (prog1 \starparam{form})) %\endcode \code (prog1 \starparam{form}) \EQ (values (multiple-value-prog1 \starparam{form})) (prog2 \param{form1} \starparam{form}) \EQ (let () \param{form1} (prog1 \starparam{form})) \endcode \endcom %%% ========== PROGN \begincom{progn}\ftype{Special Operator} \label Syntax:: \DefspecWithValues progn {\starparam{form}} {\starparam{result}} \label Arguments and Values:: \param{forms}---an \term{implicit progn}. %% 7.9.2 6 %% 7.4.0 5 \param{results}---the \term{values} of the \term{forms}. \label Description:: %% 7.4.0 3 \specref{progn} evaluates \param{forms}, in the order in which they are given. The values of each \param{form} but the last are discarded. %% 5.3 2 If \specref{progn} appears as a \term{top level form}, then all \term{forms} within that \specref{progn} are considered by the compiler to be \term{top level forms}. \label Examples:: \code (progn) \EV NIL (progn 1 2 3) \EV 3 (progn (values 1 2 3)) \EV 1, 2, 3 (setq a 1) \EV 1 (if a (progn (setq a nil) 'here) (progn (setq a t) 'there)) \EV HERE a \EV NIL \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{prog1}, \macref{prog2}, {\secref\Evaluation} \label Notes:: %% 7.4.0 4 Many places in \clisp\ involve syntax that uses \term{implicit progns}. That is, part of their syntax allows many \term{forms} to be written that are to be evaluated sequentially, discarding the results of all \term{forms} but the last and returning the results of the last \term{form}. Such places include, but are not limited to, the following: the body of a \term{lambda expression}; the bodies of various control and conditional \term{forms} (\eg \macref{case}, \specref{catch}, \specref{progn}, and \macref{when}). %% This list could go on and on. Just keep it simple. -kmp&moon 13-Feb-92 % \specref{block}, % \specref{catch}, % \specref{evalwhen}, % \specref{let}, % \specref{let*}, % \macref{multiple-value-bind}, % \specref{progv}, % \macref{unless}, % and \macref{when}; % % % (\eg \specref{block}, \specref{catch}, \specref{eval-when}) % and clauses in the % \macref{case}, % \macref{ccase}, % \macref{cond}, % \macref{ctypecase}, % \macref{ecase}, % \macref{etypecase}, % and \macref{typecase} % conditional \term{forms}. \endcom %-------------------- Setf -------------------- %%% ========== DEFINE-MODIFY-MACRO \begincom{define-modify-macro}\ftype{Macro} \label Syntax:: \DefmacWithValues define-modify-macro {name lambda-list function \brac{documentation}} {name} \label Arguments and Values:: \param{name}---a \term{symbol}. % The lambda-list here was screwed up. GET-SETF-METHOD-ENVIRONMENT:ADD-ARG % did *not* add an &environment argument to define-modify-macro. % I moved the details of the lambda-list syntax to chapter 3, for % consistency with everything else. --sjl 5 Mar 92 %\issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} %\param{lambda-list}---a \term{lambda list} % containing the % \keyref{environment}, % \keyref{optional}, % and % \keyref{rest} % keywords only. %\endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \param{lambda-list}---a \term{define-modify-macro lambda list} \param{function}---a \term{symbol}. \param{documentation}---a \term{string}; \noeval. \label Description:: %% 7.2.0 42 \macref{define-modify-macro} defines a \term{macro} named \param{name} to \term{read} and \term{write} a \term{place}. The arguments to the new \term{macro} are a \term{place}, followed by the arguments that are supplied in \param{lambda-list}. \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \term{Macros} defined with \macref{define-modify-macro} correctly pass the \term{environment parameter} to \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \funref{get-setf-expansion}. \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} % I see no &environment argument here. --sjl 5 Mar 92 %\issue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC} % The \keyref{environment} argument has \term{dynamic extent}; %the consequences are undefined if the \keyref{environment} argument is %referred to outside the \term{dynamic extent} of the macro call. %\endissue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC} When the \term{macro} is invoked, \param{function} is applied to the old contents of the \term{place} and the \param{lambda-list} arguments to obtain the new value, and the \term{place} is updated to contain the result. %% 7.2.0 43 Except for the issue of avoiding multiple evaluation (see below), the expansion of a \macref{define-modify-macro} is equivalent to the following: \code (defmacro \param{name} (reference . \param{lambda-list}) \param{documentation} \bq(setf ,reference (\param{function} ,reference ,\i{arg1} ,\i{arg2} ...))) \endcode where \i{arg1}, \i{arg2}, ..., are the parameters appearing in \param{lambda-list}; appropriate provision is made for a \term{rest parameter}. \issue{PUSH-EVALUATION-ORDER:FIRST-ITEM} The \term{subforms} of the macro calls defined by \macref{define-modify-macro} are evaluated as specified in \secref\GenRefSubFormEval. \endissue{PUSH-EVALUATION-ORDER:FIRST-ITEM} \issue{DOCUMENTATION-FUNCTION-BUGS:FIX} \param{Documentation} is attached as a \term{documentation string} to \param{name} (as kind \specref{function}) and to the \term{macro function}. \endissue{DOCUMENTATION-FUNCTION-BUGS:FIX} % Added. --sjl 5 Mar 92 \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} % added qualification about top-level-ness --sjl 5 Mar 92 If a \macref{define-modify-macro} \term{form} appears as a \term{top level form}, the \term{compiler} must store the \term{macro} definition at compile time, so that occurrences of the macro later on in the file can be expanded correctly. \endissue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} \label Examples:: %% 7.2.0 44 %% 7.2.0 45 \code (define-modify-macro appendf (&rest args) append "Append onto list") \EV APPENDF (setq x '(a b c) y x) \EV (A B C) (appendf x '(d e f) '(1 2 3)) \EV (A B C D E F 1 2 3) x \EV (A B C D E F 1 2 3) y \EV (A B C) (define-modify-macro new-incf (&optional (delta 1)) +) (define-modify-macro unionf (other-set &rest keywords) union) \endcode \label Side Effects:: A macro definition is assigned to \param{name}. \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{defsetf}, \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \macref{define-setf-expander}, \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \funref{documentation}, {\secref\DocVsDecls} \label Notes:\None. \endcom %%% ========== DEFSETF \begincom{defsetf}\ftype{Macro} \issue{DECLS-AND-DOC} \label Syntax:: The ``short form'': \DefmacWithValuesNewline defsetf {access-fn update-fn \brac{documentation}} {access-fn} The ``long form'': \DefmacWithValuesNewline defsetf {access-fn lambda-list \paren{\starparam{store-variable}} {\DeclsAndDoc} \starparam{form}} {access-fn} \label Arguments and Values:: %!!! Barmar: Does the function or macro needs to already be defined? \param{access-fn}---a \term{symbol} which names a \term{function} or a \term{macro}. \param{update-fn}---a \term{symbol} naming a \term{function} or \term{macro}. \param{lambda-list}---a \term{defsetf lambda list}. \param{store-variable}---a \term{symbol} (a \term{variable} \term{name}). \param{declaration}---a \misc{declare} \term{expression}; \noeval. \param{documentation}---a \term{string}; \noeval. \param{form}---a \term{form}. \label Description:: %% 7.2.0 46 \macref{defsetf} defines how to \macref{setf} a \term{place} of the form \f{(\i{access-fn} ...)} for relatively simple cases. (See \macref{define-setf-expander} for more general access to this facility.) \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} % These next two paragraphs apply only to the short form. This information % is presented more succinctly below anyway. --sjl 5 Mar 92 % % When \macref{setf} is given a \term{place} that is % specified in terms of \param{access-fn} and a new value for the % \term{place}, % it is expanded into a call on \param{update-fn}. % The arguments of \param{access-fn} and the new value are passed to % \param{update-fn}, % and \param{update-fn} is invoked to modify the value of the % \term{place}. % % The \term{function} or \term{macro} named by \param{access-fn} % evaluates all of its arguments. % %Barmar: Why? % %Barmar (later): Answer is CLtL2, p138, para 2. % \param{Update-fn} must take one more argument than % \param{access-fn}. This last argument corresponds to the new value that is % to be assigned to the \term{place}. \param{Update-fn} must return % the new value as its result. It must be the case that the \term{function} or \term{macro} named by \param{access-fn} evaluates all of its arguments. \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} %% 7.2.0 49 \macref{defsetf} may take one of two forms, called the ``short form'' and the ``long form,'' which are distinguished by the \term{type} of the second \term{argument}. When the short form is used, % The simple form % % \code % (defsetf access-fn update-fn \lbracket\ doc-string\rbracket) % \endcode \param{update-fn} must name a \term{function} (or \term{macro}) that takes one more argument than \param{access-fn} takes. When \macref{setf} is given a \term{place} that is a call on \param{access-fn}, it expands into a call on \param{update-fn} that is given all the arguments to \param{access-fn} and also, as its last argument, the new value (which must be returned by \param{update-fn} as its value). %% 7.2.0 51 The long form \macref{defsetf} % looks like % % \code % (defsetf access-fn lambda-list (store-variable) . body) % \endcode % and resembles \macref{defmacro}. %% 7.2.0 52 The \param{lambda-list} describes the arguments of \param{access-fn}. The \param{store-variables} describe the value \issue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} or values \endissue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} to be stored into the \term{place}. The \param{body} must compute the expansion of a \macref{setf} of a call on \param{access-fn}. \issue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} % Reworded garbled text. --sjl 7 Mar 92 % When the expansion function is called, the \param{forms} are evaluated % in the lexical environment in which the \macref{defsetf} \term{form} was evaluated. The expansion function is defined in the same \term{lexical environment} in which the \macref{defsetf} \term{form} appears. \endissue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} %% 7.2.0 54 During the evaluation of the \param{forms}, the variables in the \param{lambda-list} and the %Ikky. --sjl 5 Mar 92 %\param{store-variable} %\issue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} %or \param{store-variables} %\endissue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} \param{store-variables} are bound to names of temporary variables, generated as if by \funref{gensym} % !!! Moon doesn't like this. Neither do I. He's sent mail about this. -kmp 13-Feb-92 or \funref{gentemp}, that will be bound by the expansion of \macref{setf} to the values of those \term{subforms}. This binding permits the \param{forms} to be written without regard for order-of-evaluation issues. \macref{defsetf} arranges for the temporary variables to be optimized out of the final result in cases where that is possible. \issue{FLET-IMPLICIT-BLOCK:YES} The body code in \macref{defsetf} is implicitly enclosed in a \term{block} whose name is %the same as the accessor. \param{access-fn} \endissue{FLET-IMPLICIT-BLOCK:YES} %% 7.2.0 47 \macref{defsetf} ensures that \term{subforms} of the \term{place} are evaluated exactly once. \param{Documentation} is attached to \param{access-fn} as a \term{documentation string} of kind \misc{setf}. \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} % added qualification about top-level-ness --sjl 5 Mar 92 If a \macref{defsetf} \term{form} appears as a \term{top level form}, the \term{compiler} must make the \term{setf expander} available so that it may be used to expand calls to \macref{setf} later on in the \term{file}. Users must ensure that the \param{forms}, if any, can be evaluated at compile time if the \param{access-fn} is used in a \term{place} later in the same \term{file}. The \term{compiler} must make these \term{setf expanders} available to compile-time calls to \funref{get-setf-expansion} when its \param{environment} argument is a value received as the \term{environment parameter} of a \term{macro}. \endissue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} \label Examples:: The effect of \code (defsetf symbol-value set) \endcode is built into the \clisp\ system. This causes the form \f{(setf (symbol-value foo) fu)} to expand into \f{(set foo fu)}. %% 7.2.0 50 Note that \code (defsetf car rplaca) \endcode would be incorrect because \funref{rplaca} does not return its last argument. \code (defun middleguy (x) (nth (truncate (1- (list-length x)) 2) x)) \EV MIDDLEGUY (defun set-middleguy (x v) (unless (null x) (rplaca (nthcdr (truncate (1- (list-length x)) 2) x) v)) v) \EV SET-MIDDLEGUY (defsetf middleguy set-middleguy) \EV MIDDLEGUY (setq a (list 'a 'b 'c 'd) b (list 'x) c (list 1 2 3 (list 4 5 6) 7 8 9)) \EV (1 2 3 (4 5 6) 7 8 9) (setf (middleguy a) 3) \EV 3 (setf (middleguy b) 7) \EV 7 (setf (middleguy (middleguy c)) 'middleguy-symbol) \EV MIDDLEGUY-SYMBOL a \EV (A 3 C D) b \EV (7) c \EV (1 2 3 (4 MIDDLEGUY-SYMBOL 6) 7 8 9) \endcode %% 7.2.0 56 An example of the use of the long form of \macref{defsetf}: \code (defsetf subseq (sequence start &optional end) (new-sequence) `(progn (replace ,sequence ,new-sequence :start1 ,start :end1 ,end) ,new-sequence)) \EV SUBSEQ \endcode %% People thought this comment was stupid. -kmp 10-Feb-92 % Experience with Common Lisp prior to this specification suggests that % use of the fully general notation for \term{keyword parameters} in \term{function} % definitions is rare, and that its use in \macref{defsetf} \term{forms} % is even more rare. In spite of its obscure nature, % the following is an illustration of \term{conforming code}: \code (defvar *xy* (make-array '(10 10))) (defun xy (&key ((x x) 0) ((y y) 0)) (aref *xy* x y)) \EV XY (defun set-xy (new-value &key ((x x) 0) ((y y) 0)) (setf (aref *xy* x y) new-value)) \EV SET-XY (defsetf xy (&key ((x x) 0) ((y y) 0)) (store) `(set-xy ,store 'x ,x 'y ,y)) \EV XY (get-setf-expansion '(xy a b)) \EV (#:t0 #:t1), (a b), (#:store), ((lambda (&key ((x #:x)) ((y #:y))) (set-xy #:store 'x #:x 'y #:y)) #:t0 #:t1), (xy #:t0 #:t1) (xy 'x 1) \EV NIL (setf (xy 'x 1) 1) \EV 1 (xy 'x 1) \EV 1 (let ((a 'x) (b 'y)) (setf (xy a 1 b 2) 3) (setf (xy b 5 a 9) 14)) \EV 14 (xy 'y 0 'x 1) \EV 1 (xy 'x 1 'y 2) \EV 3 \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \funref{documentation}, \macref{setf}, \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \macref{define-setf-expander}, \funref{get-setf-expansion}, \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} {\secref\GeneralizedReference}, {\secref\DocVsDecls} \label Notes:: %% 7.2.0 55 \param{forms} must include provision for returning the correct value (the value \issue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} or values \endissue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} of \param{store-variable}). This is handled by \param{forms} rather than by \macref{defsetf} because in many cases this value can be returned at no extra cost, by calling a function that simultaneously stores into the \term{place} and returns the correct value. A \macref{setf} of a call on \param{access-fn} also evaluates all of \param{access-fn}'s arguments; it cannot treat any of them specially. %!!! %Barmar: What if update-fn is a macro? %Moon: That technique won't work because DEFSETF is allowed to introduce temporary % variable bindings. I guess that ought to be explained in this note. This means that \macref{defsetf} cannot be used to describe how to store into a \term{generalized reference} to a byte, such as \f{(ldb field reference)}. \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \macref{define-setf-expander} \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} is used to handle situations that do not fit the restrictions imposed by \macref{defsetf} and gives the user additional control. \endissue{DECLS-AND-DOC} \endcom %%% ========== DEFINE-SETF-METHOD \begincom{define-setf-expander}\ftype{Macro} \issue{DECLS-AND-DOC} \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \label Syntax:: \DefmacWithValuesNewline define-setf-expander {\vtop{\hbox{access-fn lambda-list} \hbox{{\DeclsAndDoc} \starparam{form}}}} {access-fn} \label Arguments and Values:: \param{access-fn}---a \term{symbol} that \term{names} a \term{function} or \term{macro}. % tweaked. --sjl 5 Mar 92 %\issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} %\param{lambda-list} -- \term{lambda list}; % can contain the \term{lambda list keywords} % \keyref{optional}, \keyref{rest}, \keyref{key}, \keyref{allow-other-keys}, \keyref{aux}, % and \keyref{environment}. %\endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \param{lambda-list} -- \term{macro lambda list}. \param{declaration}---a \misc{declare} \term{expression}; \noeval. \param{documentation}---a \term{string}; \noeval. \param{forms}---an \term{implicit progn}. \label Description:: %% 7.2.0 72 \macref{define-setf-expander} specifies the means by which \macref{setf} updates a \term{place} that is referenced by \param{access-fn}. When \macref{setf} is given a \term{place} that is specified in terms of \param{access-fn} and a new value for the \term{place}, it is expanded into a form that performs the appropriate update. %% Moon doesn't think this belongs. % Neither do I. It's all described in gory detail in chapter 3 already. % --sjl 5 Mar 92 % %When \macref{setf} is called with the \param{access-fn}, % \param{lambda-list} % parameters are bound to the % corresponding \param{access-fn} arguments in the \term{place}. % %% 7.2.0 73 % \param{lambda-list} specifies the arguments of \param{access-fn} by % describing the \term{subforms} of the \term{place}. % \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} % %% 8.1.0 12 % \keyref{environment} % is followed by a single variable that is bound % to an \term{environment} representing the lexical environment in which the % \term{macro form} is to be interpreted. This \term{environment} might not be the % complete lexical environment; it should be used only with % \funref{macroexpand} or \funref{get-setf-expansion} for the sake of any local % macro definitions that the \specref{macrolet} \term{form} could have % established within that lexical environment. % \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} % \issue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC} % The \keyref{environment} argument has \term{dynamic extent}; % the consequences are undefined if the \keyref{environment} argument is % referred to outside the \term{dynamic extent} of the \term{macro form}. % \endissue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC} % % Destructuring can be used, as in \macref{defmacro}. The \param{lambda-list} supports destructuring. \Seesection\MacroLambdaLists. \issue{DOCUMENTATION-FUNCTION-BUGS:FIX} \param{Documentation} is attached to \param{access-fn} as a \term{documentation string} of kind \misc{setf}. \endissue{DOCUMENTATION-FUNCTION-BUGS:FIX} \param{Forms} constitute the body of the \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \term{setf expander} \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} definition and must compute the \term{setf expansion} for a call on \macref{setf} that references the \term{place} by means of the given \param{access-fn}. \issue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} % Reworded garbled text. --sjl 7 Mar 92 %When the expansion function is called, the \param{forms} are %evaluated in the lexical environment in which the %\macref{define-setf-expander} form was evaluated. The \term{setf expander} function is defined in the same \term{lexical environment} in which the \macref{define-setf-expander} \term{form} appears. \endissue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW} While \param{forms} are being executed, the variables in \param{lambda-list} are bound to parts of the \term{place} \term{form}. \issue{FLET-IMPLICIT-BLOCK:YES} \issue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS} The body \param{forms} (but not the \param{lambda-list}) \endissue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS} in a \macref{define-setf-expander} \term{form} are implicitly enclosed in a \term{block} whose name is %the same as the accessor. \param{access-fn}. \endissue{FLET-IMPLICIT-BLOCK:YES} % We don't need to duplicate all this verbiage again here. --sjl 5 Mar 92 % The evaluation of \term{forms} must result in the following % five values: % % \beginlist % \itemitem{1.} A \term{list} of the temporary variables used. % % \itemitem{2.} A \term{list} of the value forms to whose values % the temporary variables are bound. % % \itemitem{3.} A \term{list} consisting of the store variables % (the temporary variables that are bound to the new values). % % \itemitem{4.} The \term{writer} \term{form} % (the form that changes the \term{value} % of the \term{place} % and returns the new \term{value}). % % \itemitem{5.} The \term{reader} \term{form} % (the \term{form} that retrieves the \term{value} % of the \term{place}). % \endlist The evaluation of \param{forms} must result in the five values described in \secref\SetfExpansions. \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} % added qualification about top-level-ness --sjl 5 Mar 92 If a \macref{define-setf-expander} \term{form} appears as a \term{top level form}, the \term{compiler} must make the \term{setf expander} available so that it may be used to expand calls to \macref{setf} later on in the \term{file}. \term{Programmers} must ensure that the \param{forms} can be evaluated at compile time if the \param{access-fn} is used in a \term{place} later in the same \term{file}. The \term{compiler} must make these \term{setf expanders} available to compile-time calls to \funref{get-setf-expansion} when its \param{environment} argument is a value received as the \term{environment parameter} of a \term{macro}. \endissue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY} \label Examples:: \code (defun lastguy (x) (car (last x))) \EV LASTGUY (define-setf-expander lastguy (x &environment env) "Set the last element in a list to the given value." (multiple-value-bind (dummies vals newval setter getter) (get-setf-expansion x env) (let ((store (gensym))) (values dummies vals `(,store) `(progn (rplaca (last ,getter) ,store) ,store) `(lastguy ,getter))))) \EV LASTGUY (setq a (list 'a 'b 'c 'd) b (list 'x) c (list 1 2 3 (list 4 5 6))) \EV (1 2 3 (4 5 6)) (setf (lastguy a) 3) \EV 3 (setf (lastguy b) 7) \EV 7 (setf (lastguy (lastguy c)) 'lastguy-symbol) \EV LASTGUY-SYMBOL a \EV (A B C 3) b \EV (7) c \EV (1 2 3 (4 5 LASTGUY-SYMBOL)) \endcode %% 7.2.0 74 \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \code ;;; Setf expander for the form (LDB bytespec int). ;;; Recall that the int form must itself be suitable for SETF. (define-setf-expander ldb (bytespec int &environment env) (multiple-value-bind (temps vals stores store-form access-form) (get-setf-expansion int env);Get setf expansion for int. (let ((btemp (gensym)) ;Temp var for byte specifier. (store (gensym)) ;Temp var for byte to store. (stemp (first stores))) ;Temp var for int to store. (if (cdr stores) (error "Can't expand this.")) ;;; Return the setf expansion for LDB as five values. (values (cons btemp temps) ;Temporary variables. (cons bytespec vals) ;Value forms. (list store) ;Store variables. \bq(let ((,stemp (dpb ,store ,btemp ,access-form))) ,store-form ,store) ;Storing form. \bq(ldb ,btemp ,access-form) ;Accessing form. )))) \endcode \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{setf}, \macref{defsetf}, \funref{documentation}, \funref{get-setf-expansion}, {\secref\DocVsDecls} \label Notes:: \macref{define-setf-expander} differs from the long form of \macref{defsetf} in that while the body is being executed the \term{variables} in \param{lambda-list} are bound to parts of the \term{place} \term{form}, not to temporary variables that will be bound to the values of such parts. In addition, \macref{define-setf-expander} does not have \macref{defsetf}'s restriction that \param{access-fn} must be a \term{function} or a function-like \term{macro}; an arbitrary \macref{defmacro} destructuring pattern is permitted in \param{lambda-list}. \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \endissue{DECLS-AND-DOC} \endcom %%% ========== GET-SETF-EXPANSION \begincom{get-setf-expansion}\ftype{Function} \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \label Syntax:: \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \DefunWithValuesNewline get-setf-expansion {place {\opt} environment} {vars, vals, store-vars, writer-form, reader-form} \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \label Arguments and Values:: \param{place}---a \term{place}. \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \param{environment}---an \term{environment} \term{object}. \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} \param{vars, vals, store-vars, writer-form, reader-form}---a \term{setf expansion}. \label Description:: %% 7.2.0 75 %% 7.2.0 77 Determines five values constituting the \term{setf expansion} for \param{place} in \param{environment}; \seesection\SetfExpansions. %% Redundat with concept info. % \beginlist % % \itemitem{\bull} A \term{list} of the temporary variables. % % \itemitem{\bull} A \term{list} of the value \term{forms} to whose values % the temporary variables are bound. % % \itemitem{\bull} A \term{list} of the store variables. % % \itemitem{\bull} The \term{writer} \term{form}. % % \itemitem{\bull} The \term{reader} \term{form}. % % \endlist % \funref{get-setf-method-multiple-value} % does not check the number of store variables. % The intent of \funref{get-setf-method-multiple-value} % is that it be used in cases % that allow storing multiple values into a \term{place}. % % \funref{get-setf-method} takes care of % error-checking and macro expansion. \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} If \param{environment} is not supplied or \nil, the environment is the \term{null lexical environment}. \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} % The consequences are undefined if \param{place} is not % %a reference to a \term{place}. \label Examples:: \code (get-setf-expansion 'x) \EV NIL, NIL, (#:G0001), (SETQ X #:G0001), X \endcode %% Moon: This is so monumentally confusing that it would be better to remove it. %% Note that it never uses the store-variables. % % \code % (define-setf-expander multivalue (x) % (values '() '() `(,(gensym) ,(gensym)) `(setq ,x 3) '4)) % \EV MULTIVALUE % (get-setf-expansion '(multivalue dummy-symbol)) % \EV NIL, NIL, (#:G0002 #:G0003), (SETQ DUMMY-SYMBOL 3), 4 % \endcode \issue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} % The following example is suspect \code ;;; This macro is like POP (defmacro xpop (place &environment env) (multiple-value-bind (dummies vals new setter getter) (get-setf-expansion place env) `(let* (,@(mapcar #'list dummies vals) (,(car new) ,getter)) (if (cdr new) (error "Can't expand this.")) (prog1 (car ,(car new)) (setq ,(car new) (cdr ,(car new))) ,setter)))) (defsetf frob (x) (value) `(setf (car ,x) ,value)) \EV FROB ;;; The following is an error; an error might be signaled at macro expansion time (flet ((frob (x) (cdr x))) ;Invalid (xpop (frob z))) \endcode %;;; The following will modify (cdr z) and not (car z) % (macrolet ((frob (x) `(cdr ,x))) % (xpop (frob z))) \endissue{GET-SETF-METHOD-ENVIRONMENT:ADD-ARG} %%% 7.2.0 76 %A version of \macref{setf} %allowing exactly two %\term{subforms}, containing no optimization to remove unnecessary variables, and %not allowing storing of multiple values, could be defined by: %\code % (defmacro setf (reference value) % (multiple-value-bind (vars vals stores store-form access-form) % (get-setf-expansion reference) % (declare (ignore access-form)) % \bq(let* ,(mapcar #'list % (append vars stores) % (append vals (list value))) % ,store-form))) %\endcode \label Affected By:\None. \label Exceptional Situations:\None.%Probably not true. %Removed per SETF-METHOD-VS-SETF-METHOD. % An error \oftype{error} is signaled by \funref{get-setf-expansion} % if there would be more than one store variable. \label See Also:: \macref{defsetf}, \macref{define-setf-expander}, \macref{setf} \label Notes:: Any \term{compound form} is a valid \term{place}, since any \term{compound form} whose \term{operator} \param{f} has no \term{setf expander} are expanded into a call to \f{(setf \param{f})}. \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS} \endcom %%% ========== SETF %%% ========== PSETF \begincom{setf, psetf}\ftype{Macro} \label Syntax:: \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} \DefmacWithValues setf {\stardown{pair}} {\starparam{result}} \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} \DefmacWithValues psetf {\stardown{pair}} {\nil} \auxbnf{pair}{place newvalue} \label Arguments and Values:: \param{place}---a \term{place}. \param{newvalue}---a \term{form}. \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} % \param{result}---the \term{primary value} of the last \param{newvalue}, % or \nil\ if there are no \param{pairs}. \param{results}---the \term{multiple values}\meaning{2} returned by the storing form for the last \param{place}, or \nil\ if there are no \param{pairs}. \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92} \label Description:: \macref{setf} changes the \term{value} of \param{place} to be \param{newvalue}. %% Moon: Also returns a different value; anyway, this is redundant. %\macref{psetf} is like \macref{setf} except when multiple argument \param{pairs} are supplied. %% 7.2.0 5 \f{(setf place newvalue)} expands into an update form that stores the result of evaluating \param{newvalue} into the location referred to by \param{place}. %%dussud removed. %\issue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} %If \param{newvalue} produces more values than there %are store variables, the extra values are ignored. If \param{newvalue} %produces fewer values than there are store variables, the missing values %are set to \nil. %\endissue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} %%% KMP/clean-up suggested additional wording. Some \param{place} forms involve uses of accessors that take optional arguments. Whether those optional arguments are permitted by \macref{setf}, or what their use is, is up to the \macref{setf} expander function and is not under the control of \macref{setf}. The documentation for any \term{function} that accepts \keyref{optional}, \keyref{rest}, or {\tt &key} arguments and that claims to be usable with \macref{setf} must specify how those arguments are treated. %% End KMP/clean-up suggested additional wording. %% 7.2.0 6 If more than one \param{pair} is supplied, the \param{pairs} are processed sequentially; that is, \code (setf place-1 newvalue-1 place-2 newvalue-2 ... place-N newvalue-N) \endcode is precisely equivalent to \code (progn (setf place-1 newvalue-1) (setf place-2 newvalue-2) ... (setf place-N newvalue-N)) \endcode %% 7.2.0 21 %% 7.2.0 22 For \macref{psetf}, if more than one \param{pair} is supplied then the assignments of new values to places are done in parallel. More precisely, all \term{subforms} (in both the \param{place} and \param{newvalue} \term{forms}) that are to be evaluated are evaluated from left to right; after all evaluations have been performed, all of the assignments are performed in an unpredictable order. %% Removed per X3J13. -kmp 5-Oct-93 % The unpredictability matters only if more than one \param{place} form % refers to the same place. For detailed treatment of the expansion of \macref{setf} and \macref{psetf}, \seesection\KindsOfPlaces. \label Examples:: \code (setq x (cons 'a 'b) y (list 1 2 3)) \EV (1 2 3) (setf (car x) 'x (cadr y) (car x) (cdr x) y) \EV (1 X 3) x \EV (X 1 X 3) y \EV (1 X 3) (setq x (cons 'a 'b) y (list 1 2 3)) \EV (1 2 3) (psetf (car x) 'x (cadr y) (car x) (cdr x) y) \EV NIL x \EV (X 1 A 3) y \EV (1 A 3) \endcode \label Affected By:: \macref{define-setf-expander}, \macref{defsetf}, \varref{*macroexpand-hook*} \label Exceptional Situations:\None. \label See Also:: \macref{define-setf-expander}, \macref{defsetf}, \funref{macroexpand-1}, \macref{rotatef}, \macref{shiftf}, {\secref\GeneralizedReference} \label Notes:\None. \endcom %%% ========== SHIFTF \begincom{shiftf}\ftype{Macro} \label Syntax:: \DefmacWithValues shiftf {\plusparam{place} newvalue} {old-value-1} \label Arguments and Values:: %% 7.2.0 23 \param{place}---a \term{place}. \param{newvalue}---a \term{form}; \eval. \param{old-value-1}---an \term{object} (the old \term{value} of the first \param{place}). \label Description:: \macref{shiftf} modifies the values of each \param{place} by storing \param{newvalue} into the last \param{place}, and shifting the values of the second through the last \param{place} into the remaining \param{places}. \issue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} If \param{newvalue} produces more values than there are store variables, the extra values are ignored. If \param{newvalue} produces fewer values than there are store variables, the missing values are set to \nil. \endissue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} In the form {\tt (shiftf \i{place1} \i{place2} ... \i{placen} \i{newvalue})}, the values in \i{place1} through \i{placen} are \term{read} and saved, and \i{newvalue} is evaluated, for a total of \f{n}+1 values in all. Values 2 through \f{n}+1 are then stored into \i{place1} through \i{placen}, respectively. It is as if all the \param{places} form a shift register; the \param{newvalue} is shifted in from the right, all values shift over to the left one place, and the value shifted out of \i{place1} is returned. \issue{PUSH-EVALUATION-ORDER:FIRST-ITEM} For information about the \term{evaluation} of \term{subforms} of \param{places}, \seesection\GenRefSubFormEval. \endissue{PUSH-EVALUATION-ORDER:FIRST-ITEM} \label Examples:: \code (setq x (list 1 2 3) y 'trash) \EV TRASH (shiftf y x (cdr x) '(hi there)) \EV TRASH x \EV (2 3) y \EV (1 HI THERE) (setq x (list 'a 'b 'c)) \EV (A B C) (shiftf (cadr x) 'z) \EV B x \EV (A Z C) (shiftf (cadr x) (cddr x) 'q) \EV Z x \EV (A (C) . Q) (setq n 0) \EV 0 (setq x (list 'a 'b 'c 'd)) \EV (A B C D) (shiftf (nth (setq n (+ n 1)) x) 'z) \EV B x \EV (A Z C D) \endcode \label Affected By:: \macref{define-setf-expander}, \macref{defsetf}, \varref{*macroexpand-hook*} \label Exceptional Situations:\None. \label See Also:: \macref{setf}, \macref{rotatef}, {\secref\GeneralizedReference} \label Notes:: %% Removed per Kawabe's comment #2, first public review. % \macref{shiftf} can assign values to lexical as well as dynamic variables. The effect of \f{(shiftf \param{place1} \param{place2} ... \param{placen} \param{newvalue})} is roughly equivalent to \code (let ((var1 \param{place1}) (var2 \param{place2}) ... (varn \param{placen}) (var0 \param{newvalue})) (setf \param{place1} var2) (setf \param{place2} var3) ... (setf \param{placen} var0) var1) \endcode except that the latter would evaluate any \term{subforms} of each \f{place} twice, whereas \macref{shiftf} evaluates them once. For example, \code (setq n 0) \EV 0 (setq x (list 'a 'b 'c 'd)) \EV (A B C D) (prog1 (nth (setq n (+ n 1)) x) (setf (nth (setq n (+ n 1)) x) 'z)) \EV B x \EV (A B Z D) \endcode \endcom %%% ========== ROTATEF \begincom{rotatef}\ftype{Macro} \label Syntax:: %% 7.2.0 27 \DefmacWithValues rotatef {\starparam{place}} {\nil} \label Arguments and Values:: \param{place}---a \term{place}. \label Description:: \macref{rotatef} modifies the values of each \param{place} by rotating values from one \param{place} into another. \issue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} If a \param{place} produces more values than there are store variables, the extra values are ignored. If a \param{place} produces fewer values than there are store variables, the missing values are set to \nil. \endissue{SETF-MULTIPLE-STORE-VARIABLES:ALLOW} %% 7.2.0 25 In the form \f{(rotatef \i{place1} \i{place2} ... \i{placen})}, the values in \i{place1} through \i{placen} are \term{read} and \term{written}. Values 2 through \i{n} and value 1 are then stored into \i{place1} through \i{placen}. It is as if all the places form an end-around shift register that is rotated one place to the left, with the value of \i{place1} being shifted around the end to \i{placen}. \issue{PUSH-EVALUATION-ORDER:FIRST-ITEM} For information about the \term{evaluation} of \term{subforms} of \param{places}, \seesection\GenRefSubFormEval. \endissue{PUSH-EVALUATION-ORDER:FIRST-ITEM} \label Examples:: \code (let ((n 0) (x (list 'a 'b 'c 'd 'e 'f 'g))) (rotatef (nth (incf n) x) (nth (incf n) x) (nth (incf n) x)) x) \EV (A C D B E F G) \endcode \label Affected By:\None. \label Exceptional Situations:\None. \label See Also:: \macref{define-setf-expander}, \macref{defsetf}, \macref{setf}, \macref{shiftf}, \varref{*macroexpand-hook*}, {\secref\GeneralizedReference} \label Notes:: % \macref{rotatef} can be used to assign values to \term{lexical variables} % as well as to \term{dynamic variables}. %% 7.2.0 26 The effect of \f{(rotatef \param{place1} \param{place2} ... \param{placen})} is roughly equivalent to \code (psetf \param{place1} \param{place2} \param{place2} \param{place3} ... \param{placen} \param{place1}) \endcode except that the latter would evaluate any \term{subforms} of each \f{place} twice, whereas \macref{rotatef} evaluates them once. \endcom %-------------------- Flow Errors -------------------- \begincom{control-error}\ftype{Condition Type} \label Class Precedence List:: \typeref{control-error}, \typeref{error}, \typeref{serious-condition}, \typeref{condition}, \typeref{t} \label Description:: \Thetype{control-error} consists of error conditions that result from invalid dynamic transfers of control in a program. The errors that result from giving \specref{throw} a tag that is not active or from giving \specref{go} or \specref{return-from} a tag that is no longer dynamically available are \oftype{control-error}. \endcom%{control-error}\ftype{Condition Type} \begincom{program-error}\ftype{Condition Type} \label Class Precedence List:: \typeref{program-error}, \typeref{error}, \typeref{serious-condition}, \typeref{condition}, \typeref{t} \label Description:: \Thetype{program-error} consists of error conditions related to incorrect program syntax. The errors that result from naming a \term{go tag} or a \term{block tag} that is not lexically apparent are \oftype{program-error}. \endcom%{program-error}\ftype{Condition Type} \begincom{undefined-function}\ftype{Condition Type} \label Class Precedence List:: \typeref{undefined-function}, \typeref{cell-error}, \typeref{error}, \typeref{serious-condition}, \typeref{condition}, \typeref{t} \label Description:: \Thetype{undefined-function} consists of \term{error} \term{conditions} that represent attempts to \term{read} the definition of an \term{undefined function}. %Barrett: "name"? %KMP: An "undefined function" is by definition just a "name". See glossary. The name of the cell (see \typeref{cell-error}) is the \term{function name} which was \term{funbound}. \label See Also:: \funref{cell-error-name} \endcom%{undefined-function}\ftype{Condition Type}