[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