function-information

Arguments:
fspec &optional env all-declarations special-operators

This function returns information about the operator named by
fspec when it is found in the functional position
in the environment env. env
may be an environment object or nil,
indicating the null lexical
environment. all-declarations is a boolean which
requests a building of all declarations out of previous declarations
of the same name, including the global environment. This switch is
added so that the interpreter, which almost never looks at
declarations, doesn't need to cons as much for no good
reason. special-operaor is a boolean which
controls whether :special-operator is returned for
the first value when fspec names both a macro and
a special-operator in certain cases (see below for more information). The default
is nil, and :macro is
returned in that case.

Four values are returned.

The first value returned is one of the following values, providing
information about the type of definition or binding of
fspec:

nil: there is no binding or definition of
fspec.

:function: fspec refers to a function.

:macro: fspec refers to a macro.

:compiler-macro: fspec has a
compiler macro associated with it. (If the symbol names both a macro
and a compiler macro, see below for
details.)

:special-operator: fspec
refers to a special operator. (If fspec refers to
both a macro and a special operator, see below for details.)

The second returned value is a locative cons (a cons whose car and/or
cdr may be used as a mutable value). This locative cons is used to
provide the local binding of the value (for :evaluation environments)
or local compiler structure information (for the compiler/compilation environments). To
reduce consing at critical points in the environments implementation,
there are a few exceptions where the second value is not a cons
representing a locative:

When the first return value from function-information is
:special-operator, then the second value is nil, because the value of a special operator is opaque
to the programmer (companion-macros are mandated by the spec in order
for a non-compiler to "see" into special-operators, and so a
functional value does not make sense).

When the first return value from function-information is either
:function or :macro, and the
definition is in fact dynamic and thus accessible via fdefinition or macro-function, respectively, then the second
returned value is nil, unless the third
argument to function-information is non-nil, indicating that consing definitions and
declarations is ok.

The third returned value is an alist containing information
declarations that apply to the bindings of
symbol. The keys are symbols that name
declaration specifiers (such as dynamic-extent, inline, ftype, etc.)
and the value is the associated value.

The fourth returned value is a boolean indicating whether definition is
local or global: the value is true if the binding is local, nil if not. (In CLtL-2, this local/global boolean is
the second returned value.)

If one considers a namespace to be a one-to-one mapping of a name to a
binding, then the function namespace is not a pure namespace in Common
Lisp; consider that a name can simultaneously name both a
special-operator and either a macro or a compiler-macro, or it can
name a macro or function and a compiler-macro simultaneously. Of
course, any lexical definition created for that name (such as an
flet, labels, or macrolet) will shadow all of these potential
combinations, but if no such shadowing occurs, there is a necessity
for function-information
to be able to make the distinctions between the various combinations
of definition that are possible.

If the fourth argument (the special-operators
argument) to function-information is true, and if the
name is a non-shadowed special-operator, then
:special-operator is returned, even if it has a
macro or a compiler-macro definition as well. If the argument is
nil, then for a special-operator which also
has a compiler-macro, :compiler-macro is returned
only for :compiler
or :compilation environments (otherwise
:special-operator is returned), and for a
special-operator which also has a macro definition,
:macro is returned only for
:interpreter and :evaluation
environments (otherwise :special-operator is
returned).

We do not define what occurs if a special-operator has both a macro
and a compiler-macro definition, beause Allegro CL has none of these
situations. There should be a normalized behavior for such
situation.

If a name defines a compiler-macro as well as either a macro or a
function, then which is returned depends on the environment kind: a
:compiler
or :compilation environment will cause the
:compiler-macro to be returned, and an
:interpreter or an :evaluation
environment will result in the :function or
:macro being returned.