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.
