Sam Steingold <[EMAIL PROTECTED]> writes:

>> Sam Steingold <[EMAIL PROTECTED]> writes:
>> 
>> > (proclaim '(special x))
>> > (defun f1 () x)
>> > (defun f2 () (f1))
>> > (defun f3 () (f2))
>> >
>> > (f3)
>> >
>> > Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable X is unbound
>> 
>> Maybe I'm missing something, but since X is unbound, I'd say this is
>> expected behaviour.  What behaviour did you expect, and why?
>
> I meant to write
>
> (defun f3 (x) (f2))
> (f3 10)
>
> but it does work.
> I cannot reproduce the bug I encountered, but the workaround is to
> replace the proclamation with a defvar, so I stopped investigating.

At a guess I'd say that you put the forms above in a file, and
compiled them in a fresh core (i.e. one where x hadn't been declared
special previously).  Since proclaim is _not_ treated specially by the
file-compiler, the special declaration for x will only come into
effect once the compiled file is loaded.  As a result, the x in f1
ends up as a special variable reference, because x is free in f1, but
of course the X in f3 is a lexical binding, hence it will not cause
the X in f1 to be bound, thus the error.  You should IMHO have gotten
a warning that X is free in f1 at compile-time, however.

The proper "work-around", i.e. the correct way of specifying
global declarations that are to affect the compile-time environment,
too, is to DECLAIM them, i.e.

(declaim (special x))

Using defvar also fixes your troubles, since DEFVAR expands into
declaim, too, in order to properly affect references and bindings in
later forms in the file being compiled...

At least this is what I suspect has happened here.

Regs, Pierre.


Reply via email to