Common Lisp the Language, 2nd Edition
The value of an ordinary variable may be obtained simply by writing the name of the variable as a form to be executed. Whether this is treated as the name of a special variable or a lexical variable is determined by the presence or absence of an applicable special declaration; see chapter 9.
The following functions and special forms allow reference to the values of constants and variables in other ways.
[Special Form]
quote object
(quote x) simply returns x. The object is not evaluated and may be any Lisp object whatsoever. This construct allows any Lisp object to be written as a constant value in a program. For example:
(setq a 43) (list a (cons a 3)) => (43 (43 . 3)) (list (quote a) (quote (cons a 3)) => (a (cons a 3))
Since quote forms are so frequently useful but somewhat cumbersome to type, a standard abbreviation is defined for them: any form f preceded by a single quote (') character is assumed to have (quote ) wrapped around it to make (quote f). For example:
(setq x '(the magic quote hack))
is normally interpreted by read to mean
(setq x (quote (the magic quote hack)))
See section 22.1.3.
X3J13 voted in January 1989 (CONSTANT-MODIFICATION) to clarify that
it is an error to destructively modify any object that appears as a constant
in executable code, whether within a quote special form or as
a self-evaluating form.
See section 25.1 for a discussion of how quoted constants are treated by the compiler.
X3J13 voted in March 1989 (QUOTE-SEMANTICS) to clarify that
eval and compile are not permitted either to copy or
to coalesce (``collapse'') constants (see eq)
appearing in the code they process; the resulting
program behavior must refer to objects that are eql to the
corresponding objects in the source code.
Moreover, the constraints introduced by the votes on
issues (CONSTANT-COMPILABLE-TYPES)
and (CONSTANT-CIRCULAR-COMPILATION)
on what kinds of objects may appear
as constants apply only to compile-file (see section 25.1).
[Special Form]
function fn
The value of function is always the functional interpretation of fn; fn is interpreted as if it had appeared in the functional position of a function invocation. In particular, if fn is a symbol, the functional definition associated with that symbol is returned; see symbol-function. If fn is a lambda-expression, then a ``lexical closure'' is returned, that is, a function that when invoked will execute the body of the lambda-expression in such a way as to observe the rules of lexical scoping properly.
X3J13 voted in June 1988 (FUNCTION-TYPE)
to specify that the result of a function special form is always
of type function. This implies that a form (function fn)
may be interpreted as (the (function fn)).
It is an error to use the function special form on a symbol that does not denote a function in the lexical or global environment in which the special form appears. Specifically, it is an error to use the function special form on a symbol that denotes a macro or special form. Some implementations may choose not to signal this error for performance reasons, but implementations are forbidden to extend the semantics of function in this respect; that is, an implementation is not allowed to define the failure to signal an error to be a ``useful'' behavior.
X3J13 voted in March 1989 (FUNCTION-NAME) to extend function
to accept any function-name (a symbol or a list
whose car is setf-see section 7.1)
as well as lambda-expressions.
Thus one may write (function (setf cadr)) to refer to the setf
expansion function for cadr.
(defun adder (x) (function (lambda (y) (+ x y))))
The result of (adder 3) is a function that will add 3 to its argument:
(setq add3 (adder 3)) (funcall add3 5) => 8
This works because function creates a closure of the inner lambda-expression that is able to refer to the value 3 of the variable x even after control has returned from the function adder.
More generally, a lexical closure in effect retains the ability to refer to lexically visible bindings, not just values. Consider this code:
(defun two-funs (x) (list (function (lambda () x)) (function (lambda (y) (setq x y))))) (setq funs (two-funs 6)) (funcall (car funs)) => 6 (funcall (cadr funs) 43) => 43 (funcall (car funs)) => 43
The function two-funs returns a list of two functions, each of which refers to the binding of the variable x created on entry to the function two-funs when it was called with argument 6. This binding has the value 6 initially, but setq can alter a binding. The lexical closure created for the first lambda-expression does not ``snapshot'' the value 6 for x when the closure is created. The second function can be used to alter the binding (to 43, in the example), and this altered value then becomes accessible to the first function.
In situations where a closure of a lambda-expression over the same set of bindings may be produced more than once, the various resulting closures may or may not be eq, at the discretion of the implementation. For example:
(let ((x 5) (funs '())) (dotimes (j 10) (push #'(lambda (z) (if (null z) (setq x 0) (+ x z))) funs)) funs)
The result of the above expression is a list of ten closures. Each logically requires only the binding of x. It is the same binding in each case, so the ten closures may or may not be the same identical (eq) object. On the other hand, the result of the expression
(let ((funs '())) (dotimes (j 10) (let ((x 5)) (push (function (lambda (z) (if (null z) (setq x 0) (+ x z)))) funs))) funs)
is also a list of ten closures. However, in this case no two of the closures may be eq, because each closure is over a distinct binding of x, and these bindings can be behaviorally distinguished because of the use of setq.
The question of distinguishable behavior is important; the result of the simpler expression
(let ((funs '())) (dotimes (j 10) (let ((x 5)) (push (function (lambda (z) (+ x z))) funs))) funs)
is a list of ten closures that may be pairwise eq. Although one might think that a different binding of x is involved for each closure (which is indeed the case), the bindings cannot be distinguished because their values are identical and immutable, there being no occurrence of setq on x. A compiler would therefore be justified in transforming the expression to
(let ((funs '())) (dotimes (j 10) (push (function (lambda (z) (+ 5 z))) funs)) funs)
where clearly the closures may be the same after all. The general rule, then, is that the implementation is free to have two distinct evaluations of the same function form produce identical (eq) closures if it can prove that the two conceptually distinct resulting closures must in fact be behaviorally identical with respect to invocation. This is merely a permitted optimization; a perfectly valid implementation might simply cause every distinct evaluation of a function form to produce a new closure object not eq to any other.
Frequently a compiler can deduce that a closure in fact does not need to close over any variable bindings. For example, in the code fragment
(mapcar (function (lambda (x) (+ x 2))) y)
the function (lambda (x) (+ x 2)) contains no references to any outside entity. In this important special case, the same ``closure'' may be used as the value for all evaluations of the function special form. Indeed, this value need not be a closure object at all; it may be a simple compiled function containing no environment information. This example is simply a special case of the foregoing discussion and is included as a hint to implementors familiar with previous methods of implementing Lisp. The distinction between closures and other kinds of functions is somewhat pointless, actually, as Common Lisp defines no particular representation for closures and no way to distinguish between closures and non-closure functions. All that matters is that the rules of lexical scoping be obeyed.
Since function forms are so frequently useful but somewhat cumbersome to type, a standard abbreviation is defined for them: any form f preceded by #' (# followed by an apostrophe) is assumed to have (function ) wrapped around it to make (function f). For example,
(remove-if #'numberp '(1 a b 3))
is normally interpreted by read to mean
(remove-if (function numberp) '(1 a b 3))
See section 22.1.4.
[Function]
symbol-value symbol
symbol-value returns the current value of the dynamic (special) variable named by symbol. An error occurs if the symbol has no value; see boundp and makunbound. Note that constant symbols are really variables that cannot be changed, and so symbol-value may be used to get the value of a named constant. In particular, symbol-value of a keyword will return that keyword.
symbol-value cannot access the value of a lexical variable.
This function is particularly useful for implementing interpreters for languages embedded in Lisp. The corresponding assignment primitive is set; alternatively, symbol-value may be used with setf.
[Function]
symbol-function symbol
symbol-function returns the current global function definition named by symbol. An error is signalled if the symbol has no function definition; see fboundp. Note that the definition may be a function or may be an object representing a special form or macro. In the latter case, however, it is an error to attempt to invoke the object as a function. If it is desired to process macros, special forms, and functions equally well, as when writing an interpreter, it is best first to test the symbol with macro-function and special-form-p and then to invoke the functional value only if these two tests both yield false.
This function is particularly useful for implementing interpreters for languages embedded in Lisp.
symbol-function cannot access the value of a lexical function name produced by flet or labels; it can access only the global function value.
The global function definition of a symbol may be altered by using setf with symbol-function. Performing this operation causes the symbol to have only the specified definition as its global function definition; any previous definition, whether as a macro or as a function, is lost. It is an error to attempt to redefine the name of a special form (see table 5-1).
X3J13 voted in June 1988 (FUNCTION-TYPE) to clarify the behavior
of symbol-function in the light of the redefinition of the type function.
[Function]
fdefinition function-name
X3J13 voted in March 1989 (FUNCTION-NAME) to add the function
fdefinition to the language.
It is exactly like symbol-function
except that its argument may be any function-name (a symbol or a list
whose car is setf-see section 7.1);
it returns the current global function
definition named by the argument function-name.
One may use fdefinition with setf
to change the current global function definition associated with
a function-name.
[Function]
boundp symbol
boundp is true if the dynamic (special) variable named by symbol has a value; otherwise, it returns nil.
See also set and makunbound.
[Function]
fboundp symbol
fboundp is true if the symbol has a global function definition. Note that fboundp is true when the symbol names a special form or macro. macro-function and special-form-p may be used to test for these cases.
X3J13 voted in June 1988 (FUNCTION-TYPE) to emphasize that,
despite the tightening of the definition of the type function,
fboundp must return true when the argument names a special form or
macro.
See also symbol-function and fmakunbound.
X3J13 voted in March 1989 (FUNCTION-NAME) to extend fboundp
to accept any function-name (a symbol or a list
whose car is setf-see section 7.1).
Thus one may write (fboundp '(setf cadr)) to determine whether a setf
expansion function has been globally defined for cadr.
[Function]
special-form-p symbol
The function special-form-p takes a symbol. If the symbol globally names a special form, then a non-nil value is returned; otherwise nil is returned. A returned non-nil value is typically a function of implementation-dependent nature that can be used to interpret (evaluate) the special form.
It is possible for both special-form-p and macro-function to be true of a symbol. This is possible because an implementation is permitted to implement any macro also as a special form for speed. On the other hand, the macro definition must be available for use by programs that understand only the standard special forms listed in table 5-1.