[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Issue: FUNCTION-TYPE (version 3)
- To: cl-cleanup@SAIL.STANFORD.EDU
- Subject: Issue: FUNCTION-TYPE (version 3)
- From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
- Date: Mon, 11 May 1987 15:55 EDT
- Sender: FAHLMAN@C.CS.CMU.EDU
Status: Revised by SEF to reflect intensive discussions prior to the
last X3J13 meeting.
Issue: FUNCTION-TYPE
References: functions (pg 32), types (pg 33), FUNCTIONP (pg 76),
APPLY (pg 107).
Category: CHANGE/CLARIFICATION
Edit History: Version 1 by RPG 02/26/87
Version 2 by cleanup committee 15-Mar-87
Version 3 by SEF 10-May-83
Problem Description:
The definition of the term `function' in CLtL includes all symbols and
many lists in addition to true functions. The type named `function' is
therefore not a useful type, and its presence complicates the type
hierarchy. The language would be improved if functions were treated as a
type in a consistent and useful manner. This would also make it easier
to integrate the function data type into the CLOS class hierarchy.
The current confused situation came about mostly because of a desire in
the original Common Lisp definition to retain compatibility with older
Lisp dialects, but in the context of Common Lisp some of these ancient
design decisions are inappropriate.
Proposal FUNCTION-TYPE:REDEFINE
1. Under this proposal FUNCTION is a full-fledged data type that can be
used both for declaration and discrimination. The list form of the
FUNCTION type specifier may still be used only for declaration.
Symbols (whether or not the symbol is FBOUNDP) and lambda expressions
are not of type FUNCTION under this proposal.
The types CONS, SYMBOL, ARRAY, NUMBER, CHARACTER, and FUNCTION are
pairwise disjoint. In particular, a list may not be used to implement
any FUNCTION subtype.
No sub-types of FUNCTION are defined in Common Lisp, but implementations
are free to define subtypes of FUNCTION. Examples might be
COMPILED-FUNCTION, INTERPRETED-FUNCTION, COMPILED-CLOSURE, and so on.
2. The behvior of FUNCTIONP is defined to be exactly equivalent to
#'(LAMBDA (X) (TYPEP X 'FUNCTION)). In particular, FUNCTIONP is no
longer true of symbols and lambda lists.
3. The descriptions of FUNCALL, APPLY, MAPCAR and all functions in
Common Lisp which take functional arguments are modified to clarify that
they will take either functions, symbols, or lists that represent
lambda-expressions. A symbol or lambda expression is coerced to a
function using the null lexical environment, and the resulting function
is used. Note that this leaves the behavior of FUNCALL, APPLY, MAPCAR,
et al. unchanged, but that their descriptions must be changed to
accommodate the new definition of the FUNCTION type.
4. In all non-error situations, the result of evaluating a FUNCTION
special form is required to be of type FUNCTION. It is an error to use
the special form FUNCTION on a symbol that does not denote a function in
the lexical 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.)
5. If SYMBOL-FUNCTION is called on a symbol that names a function in the
null lexical context, it returns that function (which, of course, is of
type FUNCTION). It is an error to call SYMBOL-FUNCTION on anything
else. In particular, it is an error to call SYMBOL-FUNCTION on a symbol
that names a macro or special form in the null lexical context; it is
unpredictable what will be returned in this case.
It is an error to pass anything other than a (true) function as the
value to (SETF (SYMBOL-FUNCTION symbol) value). Some implementations
will signal an error in this case; others may accept the bogus object
and fail only when the supposed function is called.
6. The description of COMPILE must be changed, since it is no longer
meaningful to speak of a symbol with a definition that "is a
lambda-expression". Change this to the following:
If COMPILE is called with no definition supplied, then it will attempt
to compile the current global definition of the symbol <name>, and will
signal an error if it is unable to do so. In some implementations, an
interpeted function can be compiled individually only if it contains no
references to lexical context outside the function definition. If the
symbol's definition is already compiled, no error is signalled. An
implemenation may choose to recompile the function if the original
interpreted form is available; otherwise, this is a no-op.
Rationale:
This change gives a clean, useful definition to the FUNCTION data type in
Common Lisp and the related type predicates. Under the current
definition, FUNCTIONP is nearly useless, since it is defined to be true
of all symbols, including those that do not have functional definitions.
Current Practice:
Many programmers find it necessary to write their own predicate
corresponding to the new form of FUNCTIONP.
Adoption Cost:
The type predicates would of course have to be brought into compliance
with this proposal, but that should require little effort.
Compiled functions are true functions in almost all implementations,
but, in some implementations, interpreted functions and closures are
represented as lists. This would have to be changed in the interpreter,
FUNCALL, APPLY, and other places.
Benefits:
By resurrecting FUNCTION as a useful concept, this proposed change will
eliminate a lot of confusion and will make it easier to talk about
situations in which (true) functions are passed around as Lisp objects.
By eliminating some tangles in the type hierarchy, this proposal
simplifies the task of mapping Common Lisp types into CLOS classes. It
also brings Common Lisp into closer alignment with Scheme and other
Lisp-1 dialects.
Conversion Cost:
This proposal attempts to minimize the impact on user code by allowing
APPLY, FUNCALL, and related functions to accept symbols and lambda
lists, as they currently do. The only impact on user-level code should
be a change in the operation of certain type predicates, and such cases
should be relatively easy to find and fix.
Aesthetics:
Making the concept of a function well-defined will probably be perceived
as a simplification.
It would be cleaner to require all functional arguments to be true
functions, eliminating the use of symbols and lambda-lists in this
context. However, in this case we felt that the simplification was not
worth a major incompatible change.
Discussion:
The original form of this proposal suggested that APPLY and friends
should take only true functions as the functional argument. The
current proposal was agreed to after a discussion of the conversion
problems that such an incompatible change might entail.
Some committee members have argued for an APPLICABLE-P predicate that
would be true of all objects that can be passed as the functional
argument to APPLY and friends: true functions, lambda lists, and symbols
that are FBOUNDP. I (sef) believe that this is not terribly useful and
can easily be defined by any user who wants it (or something similar).
In any event, this can be handled in a separate proposal.