I have seen this problem show up from time to time, but no real answer. (feel free to tell me to go away if you think I should.)
ANSI Common Lisp is quite elaborate on the compilation environment, but I am not clear as to whether the compilation environment is reset upon commencing compilation of a file, so I assume that it should not be reset (i.e., made empty, inheriting everything from the evaluation environment).
this means that free `special' declarations in the compiler environment may affect code compiled later adversely. the maintenance issues in ensuring that improper declarations are not made are non-trivial. it would make sense, I think, to have a `lexical' declaration that would "reverse" any possible `special' declaration in effect at the time.
I recognize that it would not be useful to let all binding forms default to lexical scope unless a bound `special' declaration occurs in it scope, but given this, there are no mechanisms to avoid undesirable free `special' declarations, _except_ for the "surround it with asterisks on both sides if it is `special' globally" _convention_.
the reason I ask this question is also practical. I have been burnt by CMUCL's treating (setq foo bar) at top-level as an implicit `special' declaration. a warning is duly emitted, but when working within a single CMUCL image for a day or more, such warnings may easily be forgotten.
(this can also be construed as a question whether CMUCL is conforming in its implicitly declaring free variables special when setq'd at top-level. I can find no requirements either way for such behavior in ANSI CL.)
#<Erik> -- education is for people who can't handle reality the hard way
In article <...> Erik Naggum <e...@naggum.no> writes:
[I'll skip the hard part of the question :]
> the reason I ask this question is also practical. I have been burnt by > CMUCL's treating (setq foo bar) at top-level as an implicit `special' > declaration. a warning is duly emitted, but when working within a single > CMUCL image for a day or more, such warnings may easily be forgotten. > > (this can also be construed as a question whether CMUCL is conforming in > its implicitly declaring free variables special when setq'd at top-level. > I can find no requirements either way for such behavior in ANSI CL.)
One has to consider what the alternatives are. The expression
(setq foo bar)
at top-level does not have any lexical scoping forms. I can think of three possible ways to deal with this:
(1) Implicitly wrap a lexical scope around the form. Drawback: The binding of foo is lost as soon as the setq is exited. This makes the top-level setq useless.
(2) Signal an error for an undeclared variable. Drawback: Requires more defvar declarations for interactive programming. This still won't solve your complaint because you would either forget about doing the defvar or you would be forced to make an explicit global declaration anyway.
(3) Implicitly make "foo" special (and warn). This is what every lisp I have ever encountered does. It allows the simplicity of use for the interpreter while still giving some feedback in compiled files.
-- Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu
| One has to consider what the alternatives are. The expression | | (setq foo bar) | | at top-level does not have any lexical scoping forms. I can think of | three possible ways to deal with this: | | (1) Implicitly wrap a lexical scope around the form. | (2) Signal an error for an undeclared variable. | (3) Implicitly make "foo" special (and warn).
I think I see a deep mistake I have made here, but it's somewhat slippery. there are bound and free variables. free variables are assumed to be found in an enclosing environment; if not, they cause errors. free variables at top-level are not found in any environment, and is therefore in an error situation, anyway, so anything goes?
| This is what every lisp I have ever encountered does.
that's odd. I'm using CMUCL 17f, CLISP 1996-03-15, WCL 2.2, and XLISP 2.1g. among them, only CMUCL implicitly declares top-level setq'd variables special. incidentally, (set 'foobar 42) in CMUCL does not declare `foobar' special, while (setq foobar 42) does. clearly, this is a hack.
is there anything in ANSI CL that could be construed as a requirement or at least a helpful hint as to how this situation should be handled?
(I'm still interested in how one would "undo" a top-level (pervasive?) special declaration.)
#<Erik> -- education is for people who can't handle reality the hard way
> (3) Implicitly make "foo" special (and warn). > This is what every lisp I have ever encountered does. It allows > the simplicity of use for the interpreter while still giving some > feedback in compiled files.
Erik's question was, if I understood it well, whether (setq foo (bar)) should be interpreted as
> In article <...> Erik Naggum <e...@naggum.no> writes:
> [I'll skip the hard part of the question :]
> > the reason I ask this question is also practical. I have been burnt by > > CMUCL's treating (setq foo bar) at top-level as an implicit `special' > > declaration. a warning is duly emitted, but when working within a single > > CMUCL image for a day or more, such warnings may easily be forgotten.
> > (this can also be construed as a question whether CMUCL is conforming in > > its implicitly declaring free variables special when setq'd at top-level. > > I can find no requirements either way for such behavior in ANSI CL.)
> One has to consider what the alternatives are. The expression
> (setq foo bar)
> at top-level does not have any lexical scoping forms. I can think of > three possible ways to deal with this:
> (1) Implicitly wrap a lexical scope around the form. > Drawback: The binding of foo is lost as soon as the setq is > exited. This makes the top-level setq useless.
> (2) Signal an error for an undeclared variable. > Drawback: Requires more defvar declarations for interactive > programming. This still won't solve your complaint > because you would either forget about doing the defvar > or you would be forced to make an explicit global > declaration anyway.
> (3) Implicitly make "foo" special (and warn). > This is what every lisp I have ever encountered does. It allows > the simplicity of use for the interpreter while still giving some > feedback in compiled files.
Why not have the compiler assume that THIS particular reference is special, but not impose a global declaration. I believe that this is the behavior of most Lisps other than CMUCL. On the face of it, I think CMUCL goes too far in making all subsequent bindings special.