From: Erik Naggum
Subject: (declare (lexical ...))
Date: 
Message-ID: <3038440536110836@arcana.naggum.no>
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

From: Thomas A. Russ
Subject: Re: (declare (lexical ...))
Date: 
Message-ID: <TAR.96Apr15081251@hobbes.ISI.EDU>
In article <...> Erik Naggum <····@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          ···@isi.edu    
From: Erik Naggum
Subject: Re: (declare (lexical ...))
Date: 
Message-ID: <3038580500648680@arcana.naggum.no>
[Thomas A. Russ]

|   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
From: Howard R. Stearns
Subject: Re: (declare (lexical ...))
Date: 
Message-ID: <3173CD55.41C67EA6@ix.netcom.com>
Thomas A. Russ wrote:
> 
> In article <...> Erik Naggum <····@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.
> 
> --
> Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu
From: Bruno Haible
Subject: Re: (declare (lexical ...))
Date: 
Message-ID: <4kug0v$pl8@nz12.rz.uni-karlsruhe.de>
Thomas A. Russ <···@isi.edu> wrote:
>
>  (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

       (let ((temp (bar)))
         (locally (declare (special foo))
           (setq foo temp)))

or

       (progn
         (declaim (special foo))
         (setq foo (bar)))

and whether the pervasiveness (pervasivity?) of the second alternative
is justified.


Bruno Haible                                     email: <······@ilog.fr>
Software Engineer                                phone: +33-1-49083585