function
,
t
A function is an object that represents code
to be executed when an appropriate number of arguments is supplied.
A function is produced by
the function
special form,
the function coerce
,
or
the function compile
.
A function can be directly invoked by using it as the first argument to
funcall
, apply
, or multiple-value-call
.
Specializing.
(function [arg-typespec [value-typespec]])
typespec—a type specifier.
value-typespec—a type specifier.
The list form of the function
type-specifier
can be used only for declaration and not for discrimination.
Every element of this type is
a function that accepts arguments of the
types
specified by the argj-types and returns values that are
members of the types specified by value-type. The
&optional
, &rest
, &key
,
and &allow-other-keys
markers can appear in the list of argument types.
The type specifier provided
with &rest
is the type
of each actual argument, not the type of the
corresponding variable.
The &key
parameters
should be supplied as lists of the form (
keyword type)
.
The keyword must be a valid keyword-name symbol
as must be supplied in the actual arguments of a
call.
This is usually a symbol in the KEYWORD
package but can be any symbol.
When &key
is given in a
function
type specifier lambda list,
the keyword parameters given
are exhaustive unless &allow-other-keys
is also present.
&allow-other-keys
is an indication
that other keyword arguments might actually be
supplied and, if supplied, can be used.
For example,
the type of the function make-list
could be declared as follows:
(function ((integer 0) &key (:initial-element t)) list)
The value-type can be a values
type specifier in order to indicate the
types of multiple values.
Consider a declaration of the following form:
(ftype (function (arg0-type arg1-type ...) val-type) f))
Any form
(f arg0 arg1 ...)
within the scope of
that declaration is equivalent to the following:
(the val-type (f (the arg0-type arg0) (the arg1-type arg1) ...))
That is, the consequences are undefined if any of the arguments are not of the specified types or the result is not of the specified type. In particular, if any argument is not of the correct type, the result is not guaranteed to be of the specified type.
Thus, an ftype
declaration for a function
describes calls to the function, not the actual definition
of the function.
Consider a declaration of the following form:
(type (function (arg0-type arg1-type ...) val-type) fn-valued-variable)
This declaration has the interpretation that, within the scope of the
declaration, the consequences are unspecified if the value of fn-valued-variable
is called with arguments not of the specified
types; the value resulting from a valid call will be of type
val-type
.
As with variable type declarations, nested declarations imply intersections of types, as follows:
ftype
:
(ftype (function (arg0-type1 arg1-type1 ...) val-type1) f))
and
(ftype (function (arg0-type2 arg1-type2 ...) val-type2) f))
If both these declarations are in effect,
then within the shared scope of the declarations, calls to f
can be
treated as if f
were declared as follows:
(ftype (function ((and arg0-type1 arg0-type2) (and arg1-type1 arg1-type2 ...) ...) (and val-type1 val-type2)) f))
It is permitted to ignore one or all of the ftype
declarations in force.
function
declarations, the declarations combine similarly.