[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue: FUNCTION-NAME (Version 1)



I favor the FUNCTION-NAME:LARGE proposal, because it defines a single,
useful notion of what a function name is.  The other proposals have
the flaw that there are two kinds of function names:  symbols, and
extended names, with only some of the Lisp primitives accepting the
latter.  This may be convenient for some implementations, for the
short term, but it fragments the language.

I have two other comments on the proposal.


A. Reducing the Cost to Implementors

One observation you could put in the Cost To Implementors section is
that none of the SMALL, MEDIUM, or LARGE proposals require changes to
the "guts" of the interpreter and compiler.  This is because an
implementation is free to use plain symbols internally to name
functions, and use a hack like JonL's SETF:|3.FOO.BAR| mapping to
convert non-symbol names to symbols.  This conversion would be done as a
part of parsing the handful of forms which accept function names, and
then all other passes of the interpreter and compiler (the "guts") would
just see symbols.  (By "parsing" I mean ensuring the right number and
type of syntactic subforms.  You can see that this is a very early and
simple stage of processing.)  Or, Lisp compilers with an "alphatization"
phase could perform function name symbolization at that phase.


B. Finishing the Job of Regularization

I'd like to suggest two additions to your smorgasbord of options in the
FUNCTION-NAME:LARGE section of the proposal.  One addition would
regularize a major special case of functions--lambda expressions.  The
other addition would reaffirm an unstated regularity in the language,
that function names can stand in for functions under FUNCALL and APPLY.
Not only can the treatment of symbolic and setf-list function names be
regularized, but lambda too can be treated in a consistent manner.

If these two points are added to your proposal, the language as a whole
would have a completely uniform treatment of functions and function
names.  Here they are:

13. Declare that any function name is a suitable argument to FUNCALL and
    APPLY.  In such a case, the function name is passed to FDEFINITION,
    and the result (which may in turn be a function name) is called.
    That is, the following two expressions are equivalent, when fname
    is a function name:
	(FUNCALL fname x y)
	  <==>
	(FUNCALL (FDEFINITION fname) x y)
    Note that the definition is sought in the global environment.
    Compare with the rule which applies to a function name occurs,
    syntactically, as the car of a list in code:
	(fname x y)
	  <==>
	(FUNCALL (FUNCTION fname) x y)
	  <==> (under proposal item 9)
	(FUNCALL (FDEFINITION fname <local-environment>) x y)

12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and
    whose cdr is a well-formed lambda argument list and body) is a function
    name.  The effects of the function name accessors on lambda expressions
    are as follows.  FDEFINITION returns an implementation-defined value which
    is the function specified the lambda expression, closed in the global
    environment.  This FDEFINITION value cannot be changed by SETF.
    FBOUNDP always returns T, and MAKUNBOUND is an error.

Esthetics:

The effect of items 11 and 12 is to complete the regularization of
Common Lisp's treatment of functions and function names.  The total
effect of proposal items 1 through 12 is that Lisp has just two notions
for referencing function objects: FUNCTIONS, which are Lisp objects that
directly represent executable code, and FUNCTION NAMES, which can denote
functions.  Symbols, SETF function names, and lambda expressions are all
examples of the latter notion.  The former notion is highly
implementation dependent.  Function names can occur as syntactic
entities in code.  FUNCALL and APPLY work uniformly on both functions
and function names, with a consistent semantics.

Lambda expressions are often thought to denote "anonymous" functions, so
it may seem paradoxical to treat them as names.  The paradox is only
apparent, since the expression itself has the properties of a Lisp
function name: It is (typically) a cons tree which can be read, printed,
and stored in source files, and it denotes a well-defined Lisp function.

Benefit to Users:

Function names are useful for representing objects in remote
environments, because they need not be bound at all times to the same
function, or to any function, and because they are typically stable in
meaning across reads and prints, where plain functions are not.
Programs which deal simultaneously with remote and local environments,
such as CLOS, can probably be simplified, since function names
can be used uniformly, rather than an ad-hoc mixture of functions
and function names.

The language as a whole become more uniform from these additions and
clarifications, making it easier to learn and use.  (See Esthetics.)

Cost to Implementors:

Interpreters which currently have a special case check for application
of lambda expressions would need to modify this check to call
FDEFINITION when a list of any sort is encountered.  Note that all
Common Lisps already must perform some such check, since lambda
expressions can be funcalled (and this is currently a very special case,
the only standard case of a list being funcalled).  This means that
every Lisp already has a place to insert the required call to
FDEFINITION.

In some implementations, FDEFINITION of a lambda expression could be that
lambda-expression itself.  In others featuring a pre-eval codewalk, the
walk would be done by FDEFINITION, which would return an appropriate
closure.

Cost of Non-adoption:

Rather than two notions for function references (functions and function
names), there would be several notions, each corresponding to the valid
inputs for particular group of primitives.  APPLY and FUNCALL would
accept functions, symbolic names, and lambda expressions, but not setf
function names.  FDEFINITION and its kind would accept symbols and setf
function names but not lambda expressions.  If the :LARGE proposal is
not adopted, this fragmentation would also apply to the various syntaxes
involving function names; some names would be acceptable to DEFUN
but not to FLET, etc.

					-- John