[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following is a complete description of the actions taken by the evaluator, given a form to evaluate.
If form is a number, the result is form.
If form is a string, the result is form.
If form is a symbol, the result is the binding of form. If form is unbound, an error is signalled. The way symbols are bound is explained in (variable-section) below.
If form is not any of the above types, and is not a list, an error is signalled.
In all remaining cases, form is a list. The evaluator examines the car of the list to figure out what to do next. There are three possibilities: this form may be a special form, a macro form, or a plain-old function form. Conceptually, the evaluator knows specially about all the symbols whose appearance in the car of a form make that form a special form, but the way the evaluator actually works is as follows. If the car of the form is a symbol, the evaluator finds the object in the function cell of the symbol (see (symbol)) and starts all over as if that object had been the car of the list. If the car isn't a symbol, then if it's a cons whose car is the symbol macro, then this is a macro form; if it is a "special function" (see (special-function)) then this is a special form; otherwise, it should be a regular function, and this is a function form.
If form is a special form, then it is handled accordingly; each special form works differently. All of them are documented in this manual. The internal workings of special forms are explained in more detail on (special-function), but this hardly ever affects you.
If form is a macro form, then the macro is expanded as explained in chapter (macros-chapter).
If form is a function form, it calls for the application of a function to arguments. The car of the form is a function or the name of a function. The cdr of the form is a list of subforms. Each subform is evaluated, sequentially. The values produced by evaluating the subforms are called the "arguments" to the function. The function is then applied to those arguments. Whatever results the function returns are the values of the original form.
There is a lot more to be said about evaluation. The way variables work and the ways in which they are manipulated, including the binding of arguments, is explained in (variable-section). A basic explanation of functions is in (function-section). The way functions can return more than one value is explained in (multiple-value). The description of all of the kinds of functions, and the means by which they are manipulated, is in chapter (function-chapter). Macros are explained in chapter (macros-chapter). The evalhook facility, which lets you do something arbitrary whenever the evaluator is invoked, is explained in (evalhook-section). Special forms are described all over the manual; each special form is in the section on the facility it is part of.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Zetalisp, variables are implemented using symbols. Symbols are used for many things in the language, such as naming functions, naming special forms, and being keywords; they are also useful to programs written in Lisp, as parts of data structures. But when the evaluator is given a symbol, it treats it as a variable, using the value cell to hold the value of the variable. If you evaluate a symbol, you get back the contents of the symbol's value cell.
There are two different ways of changing the value of a variable. One is to set the variable. Setting a variable changes its value to a new Lisp object, and the previous value of the variable is forgotten. Setting of variables is usually done with the setq special form.
The other way to change the value of a variable is with binding (also called "lambda-binding"). When a variable is bound, its old value is first saved away, and then the value of the variable is made to be the new Lisp object. When the binding is undone, the saved value is restored to be the value of the variable. Bindings are always followed by unbindings. The way this is enforced is that binding is only done by special forms that are defined to bind some variables, then evaluate some subforms, and then unbind those variables. So the variables are all unbound when the form is finished. This means that the evaluation of the form doesn't disturb the values of the variables that are bound; whatever their old value was, before the evaluation of the form, gets restored when the evaluation of the form is completed. If such a form is exited by a non-local exit of any kind, such as *throw (see (*throw-fun)) or return (see (return-fun)), the bindings are undone whenever the form is exited.
The simplest construct for binding variables is the let special form. The do and prog special forms can also bind variables, in the same way let does, but they also control the flow of the program and so are explained elsewhere (see (do-fun)). let* is just a sequential version of let; the other special forms below are only used for esoteric purposes.
Binding is an important part of the process of applying interpreted functions to arguments. This is explained in the next section.
When a Lisp function is compiled, the compiler understands the use of symbols as variables. However, the compiled code generated by the compiler does not actually use symbols to represent variables. Rather, the compiler converts the references to variables within the program into more efficient references, that do not involve symbols at all. A variable that has been changed by the compiler so that it is not implemented as a symbol is called a "local" variable. When a local variable is bound, a memory cell is allocated in a hidden, internal place (the Lisp control stack) and the value of the variable is stored in this cell. You cannot use a local variable without first binding it; you can only use a local variable inside of a special form that binds that variable. Local variables do not have any "top level" value; they do not even exist outside of the form that binds them.
The variables which are associated with symbols (the kind which are used by non-compiled programs) are called "special" variables.
Local variables and special variables do not behave quite the same way, because "binding" means different things for the two of them. Binding a special variable saves the old value away and then uses the value cell of the symbol to hold the new value, as explained above. Binding a local variable, however, does not do anything to the symbol. In fact, it creates a new memory cell to hold the value, i.e. a new local variable.
Thus, if you compile a function, it may do different things after it has been compiled. Here is an example:
(setq a 2) ;Set the variable a to the value 2. (defun foo () ;Define a function named foo. (let ((a 5)) ;Bind the symbol a to the value 5. (bar))) ;Call the function bar. (defun bar () ;Define a function named bar. a) ;It just returns the value of the variable a. (foo) => 5 ;Calling foo returns 5. (compile 'foo) ;Now compile foo. (foo) => 2 ;This time, calling foo returns 2. |
This is a very bad thing, because the compiler is only supposed to speed things up, without changing what the function does. Why did the function foo do something different when it was compiled? Because a was converted from a special variable into a local variable. After foo was compiled, it no longer had any effect on the value cell of the symbol a, and so the symbol retained its old contents, namely 2.
In most uses of variables in Lisp programs, this problem doesn't come up. The reason it happened here is because the function bar refers to the symbol a without first binding a to anything. A reference to a variable that you didn't bind yourself is called a free reference; in this example, bar makes a free reference to a.
We mentioned above that you can't use a local variable without first binding it. Another way to say this is that you can't ever have a free reference to a local variable. If you try to do so, the compiler will complain. In order for our functions to work, the compiler must be told not to convert a into a local variable; a must remain a special variable. Normally, when a function is compiled, all variables in it are made to be "local". You can stop the compiler from making a variable local by "declaring" to the compiler that the variable is "special". When the compiler sees references to a variable that has been declared special, it uses the symbol itself as the variable instead of making a local variable.
Variables can be declared by the special forms defvar and defconst (see below), or by explicit compiler declarations (see (special-fun)). The most common use of special variables is as "global" variables: variables used by many different functions throughout a program, that have top-level values.
Had bar been compiled, the compiler would have seen the free reference and printed a warning message: Warning: a declared special. It would have automatically declared a to be special and proceeded with the compilation. It knows that free references mean that special declarations are needed. But when a function is compiled that binds a variable that you want to be treated as a special variable but that you have not explicitly declared, there is, in general, no way for the compiler to automatically detect what has happened, and it will produce incorrect output. So you must always provide declarations for all variables that you want to be treated as special variables.
When you declare a variable to be special using declare rather than local-declare, the declaration is "global"; that is, it applies wherever that variable name is seen. After fuzz has been declared special using declare, all following uses of fuzz will be treated by the compiler as references to the same special variable. Such variables are called "global variables", because any function can use them; their scope is not limited to one function. The special forms defvar and defconst are useful for creating global variables; not only do they declare the variable special, but they also provide a place to specify its initial value, and a place to add documentation. In addition, since the names of these special forms start with "def" and since they are used at the top-level of files, the Lisp Machine editor can find them easily.
Here are the special forms used for setting variables.
Example: (setq x (+ 3 2 1) y (cons x nil)) |
Example: (setq a 1) (setq b 2) (psetq a b b a) a => 2 b => 1 |
Here are the special forms used for binding variables.
(let ((var1 vform1) (var2 vform2) ...) bform1 bform2 ...) |
You may omit the vform from a let clause, in which case it is as if the vform were nil: the variable is bound to nil. Furthermore, you may replace the entire clause (the list of the variable and form) with just the variable, which also means that the variable gets bound to nil. Example:
(let ((a (+ 3 3)) (b 'foo) (c) d) ...) |
(let* ((a (+ 1 2)) (b (+ a a))) ...) |
(let-if cond ((var-1 val-1) (var-2 val-2)...) body-form1 body-form2...) |
progv first evaluates symbol-list and value-list, and then binds each symbol to the corresponding value. If too few values are supplied, the remaining symbols are bound to nil. If too many values are supplied, the excess values are ignored.
After the symbols have been bound to the values, the body forms are evaluated, and finally the symbols' bindings are undone. The result returned is the value of the last form in the body.
Example: (setq a 'foo b 'bar) (progv (list a b 'b) (list b) (list a b foo bar)) => (foo nil bar nil) |
((var1 val-form-1) (var2 val-form-2) ...) |
This is a very unusual special form because of the way the evaluator is called on the result of an evaluation. Thus progw is mainly useful for implementing special forms and for functions part of whose contract is that they call the interpreter. For an example of the latter, see sys:*break-bindings* ((sys:*break-bindings*-var)); break implements this by using progw.
Here are the special forms for defining special variables.
(defvar variable) |
(defvar variable initial-value) |
defvar should be used only at top level, never in function definitions, and only for global variables (those used by more than one function). (defvar foo 'bar) is roughly equivalent to
(declare (special foo)) (if (not (boundp 'foo)) (setq foo 'bar)) |
(defvar variable initial-value documentation) |
If defvar is used in a patch file (see (patch-facility)) or is a single form (not a region) evaluated with the editor's compile/evaluate from buffer commands, if there is an initial-value the variable is always set to it regardless of whether it is already bound.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In the description of evaluation on (description-of-evaluation), we said that evaluation of a function form works by applying the function to the results of evaluating the argument subforms. What is a function, and what does it mean to apply it? In Zetalisp there are many kinds of functions, and applying them may do many different kinds of things. For full details, see (function-functions). Here we will explain the most basic kinds of functions and how they work. In particular, this section explains lambda lists and all their important features.
The simplest kind of user-defined function is the lambda-expression, which is a list that looks like:
(lambda lambda-list body1 body2...) |
This may sound something like the description of let, above. The most important difference is that the lambda-expression is not a form at all; if you try to evaluate a lambda-expression, you will get told that lambda is not a defined function. The lambda-expression is a function, not a form. A let form gets evaluated, and the values to which the variables are bound come from the evaluation of some subforms inside the let form; a lambda-expression gets applied, and the values are the arguments to which it is applied.
The variables in the lambda list are sometimes called parameters, by analogy with other languages. Some other terminologies would refer to these as formal parameters, and to arguments as actual parameters.
Lambda lists can have more complex structure than simply being a list of variables. There are additional features accessible by using certain keywords (which start with &) and/or lists as elements of the lambda list.
The principal weakness of the simple lambda lists is that any function written with one must only take a certain, fixed number of arguments. As we know, many very useful functions, such as list, append, +, and so on, accept a varying number of arguments. Maclisp solved this problem by the use of lexprs and lsubrs, which were somewhat inelegant since the parameters had to be referred to by numbers instead of names (e.g. (arg 3)). (For compatibility reasons, Zetalisp supports lexprs, but they should not be used in new programs). Simple lambda lists also require that arguments be matched with parameters by their position in the sequence. This makes calls hard to read when there are a great many arguments. Keyword parameters enable the use of other styles of call which are more readable.
In general, a function in Zetalisp has zero or more positional parameters, followed if desired by a single rest parameter, followed by zero or more keyword parameters. The positional and keyword parameters may be required or optional, but all the optional parameters must follow all the required ones. The required/optional distinction does not apply to the rest parameter.
The caller must provide enough arguments so that each of the required parameters gets bound, but he may provide extra arguments, for some of the optional parameters. Also, if there is a rest parameter, he can provide as many extra arguments as he wants, and the rest parameter will be bound to a list of all these extras. Optional parameters may have a default-form, which is a form to be evaluated to produce the default value for the parameter if no argument is supplied.
Positional parameters are matched with arguments by the position of the arguments in the argument list. Keyword parameters are matched with their arguments by matching the keyword name; the arguments need not appear in the same order as the parameters. If an optional positional argument is omitted, then no further arguments can be present. Keyword parameters allow the caller to decide independently for each one whether to specify it. Here is the exact explanation of how this all works. When apply (the primitive function that applies functions to arguments) matches up the arguments with the parameters, it follows the following algorithm: The positional parameters are dealt with first. The first required positional parameter is bound to the first argument. apply continues to bind successive required positional parameters to the successive arguments. If, during this process, there are no arguments left but there are still some required parameters (positional or keyword) which have not been bound yet, it is an error ("too few arguments"). Next, after all required parameters are handled, apply continues with the optional positional parameters, if any. It binds successive parameter to the next argument. If, during this process, there are no arguments left, each remaining optional parameter's default-form is evaluated, and the parameter is bound to it. This is done one parameter at a time; that is, first one default-form is evaluated, and then the parameter is bound to it, then the next default-form is evaluated, and so on. This allows the default for an argument to depend on the previous argument. Now, if there are no remaining parameters (rest or keyword), and there are no remaining arguments, we are finished. If there are no more parameters but there are still some arguments remaining, an error is caused ("too many arguments"). If parameters remain, all the remaining arguments are used for both the rest parameter, if any, and the keyword parameters.
First, if there is a rest parameter, it is bound to a list of all the remaining arguments. If there are no remaining arguments, it gets bound to nil. If there are keyword parameters, the same remaining arguments are used to bind them, as follows. The arguments for the keyword parameters are treated as a list of alternating keyword symbols and associated values. Each symbol is matched with the keyword parameter names, and the matching keyword paramater is bound to the value which follows the symbol. All the remaining arguments are treated in this way. Since the arguments are usually obtained by evaluation, those arguments which are keyword symbols are typically quoted in the call; but they do not have to be. The keyword symbols are compared by means of eq, which means they must be specified in the correct package. The keyword symbol for a parameter has the same print name as the parameter, but resides in the keyword package regardless of what package the parameter name itself resides in. (You can specify the keyword symbol explicitly in the lambda list if you must; see below). If any keyword parameter has not received a value when all the arguments have been processed, this is an error if the parameter is required. If it is optional, the default-form for the parameter is evaluated and the parameter is bound to its value. There may be a keyword symbol among the arguments which does not match any keyword parameter name. The function itself specifies whether this is an error. If it is not an error, then the non-matching symbols and their associated values are ignored. The function can access these symbols and values through the rest parameter, if there is one. It is common for a function to check only for certain keywords, and pass its rest parameter to another function using lexpr-funcall; then that function will check for the keywords that concern it. The way you express which parameters are required, optional, and rest is by means of specially recognized symbols, which are called &-keywords, in the lambda list. All such symbols' print names begin with the character "&". A list of all such symbols is the value of the symbol lambda-list-keywords. .setq &rest page .setq &key page The keywords used here are &key, &optional and &rest. The way they are used is best explained by means of examples; the following are typical lambda lists, followed by descriptions of which parameters are positional, rest or keyword; and required or optional.
(a b c)
(a b &optional c)
(&optional a b c)
(&rest a)
(a b &optional c d &rest e)
(&key a b)
(foo ':b 69 ':a '(some elements)) |
(&key a &optional b)
(foo ':a '(some elements)) |
(x &optional y &rest z &key a b)
(foo 1 2 ':b '(a list)) |
(&rest z &key a b c &allow-other-keys)
(&rest z &key &allow-other-keys)
In all of the cases above, the default-form for each optional parameter is nil. To specify your own default forms, instead of putting a symbol as the element of a lambda list, put in a list whose first element is the symbol (the parameter itself) and whose second element is the default-form. Only optional parameters may have default forms; required parameters are never defaulted, and rest parameters always default to nil. For example:
(a &optional (b 3))
(&optional (a 'foo) &rest d &key b (c (symeval a)))
For a keyword parameter, you normally specify the variable name, and the keyword proper is usually computed from it. You can specify the keyword symbol independently if you need to. To do this, use a two-level list instead of a symbol: ((keyword variable)). The top level of list can also contain an default value and supplied-p variable, for optional arguments.
(&key ((foo:a a)) ((foo:b b)))
Occasionally it is important to know whether a certain optional parameter was defaulted or not. You can't tell from just examining its value, since if the value is the default value, there's no way to tell whether the caller passed that value explicitly, or whether the caller didn't pass any value and the parameter was defaulted. The way to tell for sure is to put a third element into the list: the third element should be a variable (a symbol), and that variable is bound to nil if the parameter was not passed by the caller (and so was defaulted), or t if the parameter was passed. The new variable is called a "supplied-p" variable; it is bound to t if the parameter is supplied. For example:
(a &optional (b 3 c))
It is possible to specify a keyword parameter's symbol independently of its parameter name. To do this, use two nested lists to specify the parameter. The outer list is the one which can contain the default-form and supplied-p variable, if the parameter is optional. The first element of this list, instead of a symbol, is again a list, whose elements are the keyword symbol and the parameter variable name. For example:
(&key ((:a a)) &optional ((:b b) t))
(&key ((:base base-value)))
It is also possible to include, in the lambda list, some other symbols, which are bound to the values of their default-forms upon entry to the function. These are not parameters, and they are never bound to arguments; they just get bound, as if they appeared in a let form. (Whether you use these aux-variables or bind the variables with let is a stylistic decision.) To include such symbols, put them after any parameters, preceeded by the &-keyword &aux. Examples:
(a &optional b &rest c &aux d (e 5) (f (cons a e)))
Note that aux-variables are bound sequentially rather than in parallel.
It is important to realize that the list of arguments to which a rest-parameter is bound is set up in whatever way is most efficiently implemented, rather than in the way that is most convenient for the function receiving the arguments. It is not guaranteed to be a "real" list. Sometimes the rest-args list is stored in the function-calling stack, and loses its validity when the function returns. If a rest-argument is to be returned or made part of permanent list-structure, it must first be copied (see copylist, page (copylist-fun)), as you must always assume that it is one of these special lists. The system will not detect the error of omitting to copy a rest-argument; you will simply find that you have a value which seems to change behind your back. At other times the rest-args list will be an argument that was given to apply; therefore it is not safe to rplaca this list as you may modify permanent data structure. An attempt to rplacd a rest-args list will be unsafe in this case, while in the first case it would cause an error, since lists in the stack are impossible to rplacd.
There are some other keywords in addition to those mentioned here. See (lambda-list-keywords) for a complete list. You only need to know about &optional and &rest in order to understand this manual.
Lambda lists provide "positional" arguments: the meaning of an argument comes from its position in the lambda list. For example, the first argument to cons is the object that will be the car of the new cons. Sometimes it is desirable to use "keyword" arguments, in which the meaning of an argument comes from a "keyword" symbol that tells the callee which argument this is. While lambda lists do not provide keyword arguments directly, there is a convention for functions that want arguments passed to them in the keyword fashion. The convention is that the function takes a rest-argument, whose value is a list of alternating keyword symbols and argument values. If cons were written as a keyword-style function, then instead of saying
(cons 4 (foo)) |
(cons ':car 4 ':cdr (foo)) or (cons ':cdr (foo) ':car 4) |
This use of keyword arguments is only a convention; it is not built into the function-calling mechanism of the language. Your function must contain Lisp programming to take apart the rest parameter and make sense of the keywords and values. The special form keyword-extract (see (keyword-extract-fun)) may be useful for this.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section describes some functions and special forms. Some are parts of the evaluator, or closely related to it. Some have to do specifically with issues discussed above such as keyword arguments. Some are just fundamental Lisp forms that are very important.
Example: (setq x 43 foo 'bar) (eval (list 'cons x 'foo)) => (43 . bar) |
Examples: (setq fred '+) (apply fred '(1 2)) => 3 (setq fred '-) (apply fred '(1 2)) => -1 (apply 'cons '((+ 2 3) 4)) => ((+ 2 3) . 4) not (5 . 4) |
Compare apply with funcall and eval.
Example: (cons 1 2) => (1 . 2) (setq cons 'plus) (funcall cons 1 2) => 3 |
Examples: (lexpr-funcall 'plus 1 1 1 '(1 1 1)) => 6 (defun report-error (&rest args) (lexpr-funcall (function format) error-output args)) |
lexpr-funcall with two arguments does the same thing as apply.
Note: the Maclisp functions subrcall, lsubrcall, and arraycall are not needed on the Lisp Machine; funcall is just as efficient. arraycall is provided for compatibility; it ignores its first subform (the Maclisp array type) and is otherwise identical to aref. subrcall and lsubrcall are not provided.
The argument-specs are alternating keywords (or lists of keywords) and values. Each keyword or list of keywords says what to do with the value that follows. If a value happens to require no keywords, provide () as a list of keywords for it.
Two keywords are presently defined: :optional and :spread. :spread says that the following value is a list of arguments. Otherwise it is a single argument. :optional says that all the following arguments are optional. It is not necessary to specify :optional with all the following argument-specs, because it is sticky.
Example:
(call #'foo () x ':spread y '(:optional :spread) z () w) |
Examples: (quote x) => x (setq x (quote (some list))) x => (some list) |
For example, (setq x '(some list)) is converted by read into (setq x (quote (some list))) |
If you want to pass an anonymous function as an argument to a function, you could just use quote; for example:
(mapc (quote (lambda (x) (car x))) some-list) |
The function special form is one way to tell the compiler that it can go ahead and compile the lambda-expression. You just use the symbol function instead of quote:
(mapc (function (lambda (x) (car x))) some-list) |
That's what the compiler does with a function special form whose subform f is a function. The evaluator, when given such a form, just returns f; that is, it treats function just like quote.
To ease typing, the reader converts #'thing into (function thing). So #' is similar to ' except that it produces a function form instead of a quote form. So the above form could be written as
(mapc #'(lambda (x) (car x)) some-list) |
If f is not a function but the name of a function (typically a symbol, but in general any kind of function spec), then function returns the definition of f; it is like fdefinition except that it is a special form instead of a function, and so
(function fred) is like (fdefinition 'fred) which is like (fsymeval 'fred) |
Another way of explaining function is that it causes f to be treated the same way as it would as the car of a form. Evaluating the form (f arg1 arg2...) uses the function definition of f if it is a symbol, and otherwise expects f to be a list which is a lambda-expression. Note that the car of a form may not be a non-symbol function spec, to avoid difficult-to-read code. This can be written as
(funcall (function spec) args...) |
You should be careful about whether you use #' or '. Suppose you have a program with a variable x whose value is assumed to contain a function that gets called on some arguments. If you want that variable to be the car function, there are two things you could say:
(setq x 'car) or (setq x #'car) |
The other way to tell the compiler that an argument that is a lambda expression should be compiled is for the function that takes the function as an argument to use the &functional keyword in its lambda list; see (lambda-list-keywords). The basic system functions that take functions as arguments, such as map and sort, have this &functional keyword and hence quoted lambda-expressions given to them will be recognized as functions by the compiler.
In fact, mapc uses &functional and so the example given above is bogus; in the particular case of the first argument to the function mapc, quote and function are synonymous. It is good style to use function (or #') anyway, to make the intent of the program completely clear.
Example: (defun foo (x) (cond ((null x) 0) (t (comment x has something in it) (1+ (foo (cdr x)))))) |
Example: (defun foo (x) (cond ((null x) 0) (t (1+ (foo (cdr x)))) ;x has something in it )) |
A problem with such comments is that they are discarded when the form is read into Lisp. If the function is read into Lisp, modified, and printed out again, the comment will be lost. However, this style of operation is hardly ever used; usually the source of a function is kept in an editor buffer and any changes are made to the buffer, rather than the actual list structure of the function. Thus, this is not a real problem.
Example: (foo (cdr a) (progn (setq b (extract frob)) (car b)) (cadr b)) |
(When form1 is 'compile, the progn form has a special meaning to the compiler. This is discussed on (progn-quote-compile-discussion).)
Example: (setq x (prog1 y (setq y x))) |
See also bind ((bind-fun)), which is a subprimitive that gives you maximal control over binding.
The following three functions (arg, setarg, and listify) exist only for compatibility with Maclisp lexprs. To write functions that can accept variable numbers of arguments, use the &optional and &rest keywords (see (function-section)).
(arg i), when evaluated during the application of a lexpr, gives the value of the i'th argument to the lexpr. i must be a fixnum in this case. It is an error if i is less than 1 or greater than the number of arguments supplied to the lexpr.
Example: (defun foo nargs ;define a lexpr foo. (print (arg 2)) ;print the second argument. (+ (arg 1) ;return the sum of the first (arg (- nargs 1)))) ;and next to last arguments. |
(defun listify (n) (cond ((minusp n) (listify1 (arg nil) (+ (arg nil) n 1))) (t (listify1 n 1)) )) (defun listify1 (n m) ; auxiliary function. (do ((i n (1- i)) (result nil (cons (arg i) result))) ((< i m) result) )) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The Lisp Machine includes a facility by which the evaluation of a form can produce more than one value. When a function needs to return more than one result to its caller, multiple values are a cleaner way of doing this than returning a list of the values or setq'ing special variables to the extra values. In most Lisp function calls, multiple values are not used. Special syntax is required both to produce multiple values and to receive them.
The primitive for producing multiple values is values, which takes any number of arguments and returns that many values. If the last form in the body of a function is a values with three arguments, then a call to that function will return three values. The other primitive for producing multiple values is return, which when given more than one argument returns all its arguments as the values of the prog or do from which it is returning. The variant return-from also can produce multiple values. Many system functions produce multiple values, but they all do it via the values and return primitives.
The special forms for receiving multiple values are multiple-value, multiple-value-bind, and multiple-value-list. These consist of a form and an indication of where to put the values returned by that form. With the first two of these, the caller requests a certain number of returned values. If fewer values are returned than the number requested, then it is exactly as if the rest of the values were present and had the value nil. If too many values are returned, the rest of the values are ignored. This has the advantage that you don't have to pay attention to extra values if you don't care about them, but it has the disadvantage that error-checking similar to that done for function calling is not present.
return and its variants can only be used within the do and prog special forms and their variants, and so they are explained on (return-fun).
Example: (multiple-value (symbol already-there-p) (intern "goo")) |
multiple-value is usually used for effect rather than for value; however, its value is defined to be the first of the values returned by form.
Example: (setq a (multiple-value-list (intern "goo"))) a => (goo nil #<Package User>) |
Due to the syntactic structure of Lisp, it is often the case that the value of a certain form is the value of a sub-form of it. For example, the value of a cond is the value of the last form in the selected clause. In most such cases, if the sub-form produces multiple values, the original form will also produce all of those values. This passing-back of multiple values of course has no effect unless eventually one of the special forms for receiving multiple values is reached. The exact rule governing passing-back of multiple values is as follows:
If X is a form, and Y is a sub-form of X, then if the value of Y is unconditionally returned as the value of X, with no intervening computation, then all the multiple values returned by Y are returned by X. In all other cases, multiple values or only single values may be returned at the discretion of the implementation; users should not depend on whatever way it happens to work, as it may change in the future or in other implementations. The reason we don't guarantee non-transmission of multiple values is because such a guarantee would not be very useful and the efficiency cost of enforcing it would be high. Even setq'ing a variable to the result of a form, then returning the value of that variable might be made to pass multiple values by an optimizing compiler which realized that the setqing of the variable was unnecessary.
Note that use of a form as an argument to a function never receives multiple values from that form. That is, if the form (foo (bar)) is evaluated and the call to bar returns many values, foo will still only be called on one argument (namely, the first value returned), rather than being called on all the values returned. We choose not to generate several separate arguments from the several values, because this would make the source code obscure; it would not be syntactically obvious that a single form does not correspond to a single argument. Instead, the first value of a form is used as the argument and the remaining values are discarded. Receiving of multiple values is done only with the above-mentioned special forms.
For clarity, descriptions of the interaction of several common special forms with multiple values follow. This can all be deduced from the rule given above. Note well that when it says that multiple values are not returned, it really means that they may or may not be returned, and you should not write any programs that depend on which way it works.
The body of a defun or a lambda, and variations such as the body of a function, the body of a let, etc., pass back multiple values from the last form in the body.
eval, apply, funcall, and lexpr-funcall pass back multiple values from the function called.
progn passes back multiple values from its last form. progv and progw do so also. prog1 and prog2, however, do not pass back multiple values.
Multiple values are passed back from the last subform of an and or or form, but not from previous forms since the return is conditional. Remember that multiple values are only passed back when the value of a sub-form is unconditionally returned from the containing form. For example, consider the form (or (foo) (bar)). If foo returns a non-nil first value, then only that value will be returned as the value of the form. But if it returns nil (as its first value), then or returns whatever values the call to bar returns.
cond passes back multiple values from the last form in the selected clause, but not if the clause is only one long (i.e. the returned value is the value of the predicate) since the return is conditional. This rule applies even to the last clause, where the return is not really conditional (the implementation is allowed to pass or not to pass multiple values in this case, and so you shouldn't depend on what it does). t should be used as the predicate of the last clause if multiple values are desired, to make it clear to the compiler (and any human readers of the code!) that the return is not conditional.
The variants of cond such as if, select, selectq, and dispatch pass back multiple values from the last form in the selected clause.
The number of values returned by prog depends on the return form used to return from the prog. (If a prog drops off the end it just returns a single nil.) If return is given two or more subforms, then prog will return as many values as the return has subforms. However, if the return has only one subform, then the prog will return all of the values returned by that one subform.
do behaves like prog with respect to return. All the values of the last exit-form are returned.
unwind-protect passes back multiple values from its protected form.
*catch does not pass back multiple values from the last form in its body, because it is defined to return its own second value (see (*catch-fun)) to tell you whether the *catch form was exited normally or abnormally. This is sometimes inconvenient when you want to propagate back multiple values but you also want to wrap a *catch around some forms. Usually people get around this problem by enclosing the *catch in a prog and using return to pass out the multiple values, returning through the *catch. This is inelegant, but we don't know anything that's much better.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |