[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Default scope of references
I would like some protection against accidental references to
dynamically bound variables in interpreted code. Compilers typically
complain about such lossage. When I heard that Common Lisp defaulted
to lexical binding, I thought that was what was meant. For instance,
given
(DEFVAR *TEST-1* '(PROGN (DEFUN SET-FOO (VAL)
(SETQ FOO VAL))
(SET-FOO NIL)))
(DEFVAR *TEST-2* '(PROGN (SET 'FOO T)
(DEFUN GET-FOO ()
FOO)
(GET-FOO)))
in the absence of (PROCLAIM (SPECIAL FOO)), I somehow expected that
(EVAL *TEST-1*) and (EVAL *TEST-2*) would each tell me that I was
accessing a variable that was neither declared special nor lexically
bound. According to CLtL, however, ``The general rule is that if the
symbol occurs textually within a program construct that creates a
*binding* for a variable of the same name, then the reference is to the
variable specified by the binding; if no such program construct
textually contains the reference, then it is taken to refer to the
special variable of that name.'' [p. 55] Thus these forms are
supposedly legally evaluable. Is this what was intended? Should
evaluation of these forms be or signal an error? I would certainly
hope that the answer is the same for both tests.
The CL interpreters I have seen signal an error in (EVAL *TEST-1*);
they are happy to let (EVAL *TEST-2*) modify the global value of FOO.
A funnier situation occurs when we have
(DEFVAR *TEST-3* '(PROGN (EVAL (BUTLAST *TEST-1*))
(DEFUN LEX-TEST ()
(LET ((FOO T))
(SET-FOO NIL)
FOO))
(LEX-TEST)))
I have actually seen an implementation for which (EVAL *TEST-3*) yields
NIL, but that is clearly erroneous. Other implementations happily
evaluate *TEST-3* to T, setting the global value of FOO to NIL. A
stranger situation occurs with
(DEFVAR *TEST-4* '(PROGN (EVAL (BUTLAST *TEST-3*))
(COMPILE 'LEX-TEST)
(LEX-TEST)))
In the implementations I have tested, (EVAL *TEST-4*) will signal an
error when SET-FOO attempts to change the value of FOO.
Unfortunately, my access to Common Lisp implementations is confined to
one vendor's Beta release and two other implementations to which I have
no hands-on access. Rather than disparage anyone's implementation on
such slender evidence, I would like to hear from implementors on the
results of evaluating the four tests in the most current versions of
their implementations.
Dan