Common Lisp the Language, 2nd Edition
Next: Assignment
Up: Constants and Variables
Previous: Constants and
Variables
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
.
For example:
(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
.
symbol-function
on any symbol
for which fboundp
returns true. Note that
fboundp
must return true for a symbol naming a macro or a
special form.fboundp
returns true for a symbol but the symbol
denotes a macro or special form, then the value returned by
symbol-function
is not well-defined but
symbol-function
will not signal an error.symbol-function
is used with setf
the
new value must be of type function
. It is an error to set
the symbol-function
of a symbol to a symbol, a list, or the
value returned by symbol-function
on the name of a macro or
a special form.[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.
Next: Assignment
Up: Constants and Variables
Previous: Constants and
Variables
AI.Repository@cs.cmu.edu