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

Re: Issue: LET-TOP-LEVEL (version 1)

] Date: Tue, 1 Mar 88 17:06:53 PST
] From: Jon L White <jonl%edsel@edu.stanford.labrea>

]     Rationale:
]     Common Lisp tries to support lexical closures but this support is
]     really confined to anonymous lambdas within other function
]     definitions.  This proposal attempts to move lexical closures closer
]     to first-class status in Common Lisp.
] I don't believe this problem description.  In particular, previous 
] discussions on these mailing lists suggested that DEFUN is merely a
] macro that turns into something like:
]     (setf (symbol-function 'foo) #'(lambda (x y ...) ...))

I basically agree with this point -- that the rationale / problem
description is wrong, and for the reason given -- but there is still
something there, namely that DEFUN isn't always sufficiently equivalent
to such a macro.

Some implementations do not expand DEFUN into anything so reasonable, or
else define DEFUN as a special form that is not equivalent to the macro
expansion.  They may thus end up with DEFUN semantics that are different
 from the semantics of functions produced by the appropriate SETF of

I would say these implementations are incorrect, because of the
description of DEFUN on page 67 of CLtL, where a LAMBDA expression for
the function is explicitly given and where it is specified that that
function is "defined in the lexical environment in which the DEFUN form
was executed", and because the macro definition of a macro implemented
as a special form is supposed to be equivalent to the special form
definition (CLtL, p. 57), but there are reasons why they may be able to
get away with it: (1) the specification of DEFUN is weakened by the
discussion of top-level forms on page 66, and (2) the macro equivalence
constraint is too weak -- implementations seem to regard it as allowing
the special form to make "improvements" that the macro does not.  (See
the KCL example below.)  In addition there is a more general problem
about macros that often occurs with defun -- nothing seems to rule out
expansions to expresions like (SYSTEM::DO-A-DEFUN '(DEFUN ...)).
(See the other example.)

Some cleanup issue should deal with the first problem: that top-level
forms may not be meaningful in some (unspecified) embedded contexts.  It
should also address the meaning with respect to lexical context of
top-level defining forms other than DEFUN.  Nonetheless, the top-level
forms in question are all macros, and so macro questions arise as well.
The discussion of top-level forms on page 66 of CLtL suggests that
compilers may not recognize these forms "properly" in embedded contexts.
Nothing [else] in CLtL allows compilers to fail to recognize macros.

The general macro issue involved might be the subject of a separate
cleanup issue.

Specifically, consider the implementation note on page 58.  The
restriction on what may appear in macro expansions is insufficient to
"ensure that the expansion can be processed ... in an implementation-
independent manner".  But what would be sufficient?  A necessary
condition is that all implementation-specific special forms be
accompanied by equivalent (modulo efficiency and what else?) macro
definitions so that any expression can be "fully expanded" so as to
contain no implementation-specific special forms.  CLtL does require
equivalent macros for special form implementations of operations
defined as macros in Common Lisp, but does not say anything about
other special forms an implementation may use.  Such a requirement
should be added.  However, for sufficiency something must rule out
functions of the DO-A-DEFUN sort (special forms in disguise).  Perhaps
this is being addressed as a compiler issue?

--- DEFUN Examples ---

1. PopLog Common Lisp.  Here the macro expansion is rather unhelpful
and, indeed, not equivalent to a SETF of SYMBOL-FUNCTION with the
appropriate LAMBDA expression.  A DEFUN is always with respect to the
null lexical environment.  Note that PopLog always compiles.  Thus the
statement on page 66 that "compilers may not recognize these forms
properly in other than top-level contexts" may be cited to justify its
behavior.  A SETF of SYMBOL function does work correctly.

     == (macroexpand-1 '(defun f (x) x))
     (SYSTEM::DEFUN '(F (X) X))

2. KCL.  Although KCL does have a macro of the kind you suggest, the
expansion is not what DEFUN actually does.  [Nonetheless, DEFUN inside
LET does work as desired (closure over the environment).]

     KCl (Kyoto Common Lisp)  June 3, 1987

     >(macroexpand-1 '(defun f (x) x))

     >(eval *)

     (LAMBDA-CLOSURE () () () (X) (BLOCK F X))

     >(defun f (x) x)


DEFUN in Gould CL has similar effects, but the macroexpansion is so long
that I won't show it here.  Then there are other systems (e.g., VAX Lisp
v2.1) where the differences between the effects of the macro expansion
and the DEFUN are insignificant (but still present).

Jeff Dalton,                      JANET: J.Dalton@uk.ac.ed             
AI Applications Institute,        ARPA:  J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University.             UUCP:  ...!ukc!ed.ac.uk!J.Dalton