From: Art Nuzzo
Subject: Scope of variables
Date: 
Message-ID: <afd48687.0107200835.92dd020@posting.google.com>
I have a basic question about scope of variables. Suppose I have 
the following:

(defun foo ()
  (let ((a 5))
    #'(lambda (n)       
	(declare (special n))
	(setf a (+ a 1))
	(format t "foo n: ~A    a: ~A~%" n a)
	(bar)
)))

(defun bar ()
  (format t "bar n: ~A    a: ~A~%" n a))


Now declaring 'n' to be special allowed bar to see it. I have tried 
doing the same for 'a' but that didn't seem to work.  Here is one of
the many variations I had tried:

(defun foo ()
  (let ((b 5))
    #'(lambda (x)  
	(let ((a b) (n x))
	(declare (special n a))
	(setf a (+ a 1))
	(format t "foo n: ~A    a: ~A~%" n a)
	(bar)
))))

Now bar can see 'a' but the value of 'a' is reset each time the 
function is run. (This also seems like a round about way of doing
it. Certainly there must be an easier way.)

Is there anyway to make it so bar will see both 'x' and 'a' and 
not reset the value of 'a'?




Thanks for any information,


Art Nuzzo

From: Kent M Pitman
Subject: Re: Scope of variables
Date: 
Message-ID: <sfwu207q6dg.fsf@world.std.com>
·······@motorola.com (Art Nuzzo) writes:

> I have a basic question about scope of variables. Suppose I have 
> the following:
> 
> (defun foo ()
>   (let ((a 5))
>     #'(lambda (n)       
>       (declare (special n))
>       (setf a (+ a 1))
>       (format t "foo n: ~A    a: ~A~%" n a)
>       (bar)
> )))
> 
> (defun bar ()
>   (format t "bar n: ~A    a: ~A~%" n a))
> 
> 
> Now declaring 'n' to be special allowed bar to see it. I have tried 
> doing the same for 'a' but that didn't seem to work.  Here is one of
> the many variations I had tried:
> 
> (defun foo ()
>   (let ((b 5))
>     #'(lambda (x)  
>       (let ((a b) (n x))
>       (declare (special n a))
>       (setf a (+ a 1))
>       (format t "foo n: ~A    a: ~A~%" n a)
>       (bar)
> ))))
> 
> Now bar can see 'a' but the value of 'a' is reset each time the 
> function is run. (This also seems like a round about way of doing
> it. Certainly there must be an easier way.)
> 
> Is there anyway to make it so bar will see both 'x' and 'a' and 
> not reset the value of 'a'?

You cannot get a "closure" over a special variable.

Special variables are more different than lexical variables than you think.

In the case of a lexical variable, each binding is a new variable.
So when you do

 (defun make-counter ()
   (let ((x 0))
     #'(lambda () (incf x))))

and you do

 (setq *counter-1* (make-counter))
 (setq *counter-2* (make-counter))

you will be counting with two different variables because each call to
MAKE-COUNTER allocates a new variable (whose lexical name is X, but that
doesn't really matter--it's never referred to by name).

Special variables are ALWAYS the same location.  There is only one special
named X.  If you re-bind a lexical, as in
 (let ((x 1)) (values (let ((x (1+ x))) x) x))
you get a second variable.  In the case of
 (let ((x 1)) 
   (declare (special x)) 
   (values (let ((x (1+ x)))
             (declare (special x))
             x)
           x))
you'd get the same answer but the way it works is VERY different.  The
inner binding secretly stores the old value of X at the time of the binding
(on the stack somewhere) and replaces the SAME location with a new value.

So for a bound lexical, you get a new variable [location].
For a bound special, you get a new value [in same location].

So if you go back to your definition:

> (defun foo ()
>   (let ((a 5))
>     #'(lambda (n)       
>       (declare (special n))
>       (setf a (+ a 1))
>       (format t "foo n: ~A    a: ~A~%" n a)
>       (bar)
> )))

if you declare A to be special, you will not be closing over A.  As soon
as the #'(lambda ...) executes, the fact that A was bound to 5 at the time
of creation of this closure is irrelevant.  So if A were special, the above
is the same as if A had not been bound around the lambda. e.g.,

 (defun foo () 
   #'(lambda (n)
       (declare (special n))
       (setf (symbol-value 'a) (+ (symbol-value 'a) 1))
       (format t "foo n: ~A   a: ~A~%" n a)
       (bar)))

The problem here, as you can see is that the symbol value of A is not yet
set, since you elected to use a variable type that recycles an existing 
named location (which you have not initialized) rather than something that
you do initialize.  Of course, if you don't mind setting A globally, then
this would work.  But it would still ignore the 5 in the FOO above.

What would accomplish the thing you want is not to globally declare A special
but rather to do this:

 (defun foo ()
   (let ((a 5))
     #'(lambda (n)
         (declare (special n))
         (incf a) ;i.e., (setq a (+ a 1)) ;operates on the lexical a
         (let ((a a)) ;bind special a, giving it value of outer (lexical) a
           (declare (special a))
           (format t "foo n: ~A a: ~A~%" n a)
           (bar)))))

 (defun bar ()
   (format t "bar n: ~A a: ~A~%" n a))

 (setq z (foo))

 
 (funcall z 3)
 foo n: 3 a: 6
 bar n: 3 a: 6
 => NIL

 (funcall z 3)
 foo n: 3 a: 7
 bar n: 3 a: 7
 => NIL

However, I really don't recommend using any special variables that have
the same names as lexicals, lest you confuse yourself.  Use specials with
*'s around their names and use lexicals without uniformly or you'll risk
making errors that are PAINFULLY hard to debug.
From: Kaz Kylheku
Subject: Re: Scope of variables
Date: 
Message-ID: <xP767.2034$zb.40224@news1.rdc1.bc.home.com>
In article <···············@world.std.com>, Kent M Pitman wrote:
>Special variables are ALWAYS the same location.  There is only one special
>named X.  If you re-bind a lexical, as in
> (let ((x 1)) (values (let ((x (1+ x))) x) x))
>you get a second variable.  In the case of
> (let ((x 1)) 
>   (declare (special x)) 
>   (values (let ((x (1+ x)))
>             (declare (special x))
>             x)
>           x))
>you'd get the same answer but the way it works is VERY different.  The
>inner binding secretly stores the old value of X at the time of the binding
>(on the stack somewhere) and replaces the SAME location with a new value.

This makes me curious. How can a portable Lisp program tell that the
inner special has the same location as the outer one?  Can you show a
program that will break if the two had independent locations, rather
than save-restore taking place on one?
From: Kent M Pitman
Subject: Re: Scope of variables
Date: 
Message-ID: <sfw4rs6q3m5.fsf@world.std.com>
···@ashi.footprints.net (Kaz Kylheku) writes:

> 
> In article <···············@world.std.com>, Kent M Pitman wrote:
> >Special variables are ALWAYS the same location.  There is only one special
> >named X.  If you re-bind a lexical, as in
> > (let ((x 1)) (values (let ((x (1+ x))) x) x))
> >you get a second variable.  In the case of
> > (let ((x 1)) 
> >   (declare (special x)) 
> >   (values (let ((x (1+ x)))
> >             (declare (special x))
> >             x)
> >           x))
> >you'd get the same answer but the way it works is VERY different.  The
> >inner binding secretly stores the old value of X at the time of the binding
> >(on the stack somewhere) and replaces the SAME location with a new value.
> 
> This makes me curious. How can a portable Lisp program tell that the
> inner special has the same location as the outer one?  Can you show a
> program that will break if the two had independent locations, rather
> than save-restore taking place on one?

Sure... Compare:

(let ((x 1) f)
  (declare (special x))
  (setq f #'(lambda () x))
  (print (funcall f))
  (let ((x 2))
    (declare (special x))
    (print (funcall f))
    t))
1
2
=> T

;with

(let ((x 1) f)
  (setq f #'(lambda () x))
  (print (funcall f))
  (let ((x 2))
    (print (funcall f))
    t))
1
1
=> T

In the first case, the function which accesses the SPECIAL is getting the
same location in both cases, but the location has different values.

In the second case, the function accesses the same lexical always, so gets
the same value every time, regardless of present lexical or special bindings.
From: Simon Katz
Subject: Re: Scope of variables
Date: 
Message-ID: <v9z67.3$kG6.630@news.dircon.co.uk>
> To me, this doesn't prove that the inner special x has the same location
> as the outer one. It could just be that the called closure is
> dynamically resolving its reference to x by looking at the chain of
> nested active environments above it.  It's scans upward one level and
> finds that the environment there has an x, which is bound to the value 2.
> Why can't that environment have its own location for x? What difference
> can it make if it doesn't?
> 
> I don't dispute that there could be a global special binding for the
> symbol x, and saving/restoring going on; but I'm merely curious
> whether
> that implementation is required by the standard. I guess I'm going
> to
> have to dig around in the draft.

There was a discussion of different implementation approaches early last year. Take a look at

http://groups.google.com/groups?hl=en&safe=off&th=7bbe97b009396b1e,12&seekm=y6Nv4.6362%24Nh1.13242%40newsfeeds.bigpond.com#p
From: Kent M Pitman
Subject: Re: Scope of variables
Date: 
Message-ID: <sfwlmlhymrz.fsf@world.std.com>
"Simon Katz" <·····@nomistech.com> writes:

> > To me, this doesn't prove that the inner special x has the same location
> > as the outer one. It could just be that the called closure is
> > dynamically resolving its reference to x by looking at the chain of
> > nested active environments above it.  It's scans upward one level and
> > finds that the environment there has an x, which is bound to the value 2.
> > Why can't that environment have its own location for x? What difference
> > can it make if it doesn't?
> > 
> > I don't dispute that there could be a global special binding for the
> > symbol x, and saving/restoring going on; but I'm merely curious
> > whether
> > that implementation is required by the standard. I guess I'm going
> > to
> > have to dig around in the draft.
> 
> There was a discussion of different implementation approaches early last year. Take a look at
> 
> http://groups.google.com/groups?hl=en&safe=off&th=7bbe97b009396b1e,12&seekm=y6Nv4.6362%24Nh1.13242%40newsfeeds.bigpond.com#p
> 

I agree it looks like there is some good discussion.  Note I didn't
mean to open the shallow/deep binding wound here.  I consider those
conceptually to both implement a single "slot" even though in deep
binding there are different physical memory cells backing up that "slot".  
CL allows either shallow or deep binding, but does not allow access to
the stack on which deep binding might occur, nor to operators that might
get other thant he current binding,  so there is only a performance
difference between these.  If an implementation allows more, of course,
you can tell, but that's true for any implementation allowing low-level
access to anything... and such is not CL, it's vendor-specific stuff.

In fact, we had a HUGE battle in the design of CL about whether I was
allowed to use the word "slot" for a symbol's value or function, and the
answer was "no".  I think this is silly, but some people felt it was not,
so as far as I know, we *never* refer to a symbol's function or value as
a slot value, just to avoid confusing people about where the information
is stored. (I claim that even if we had said slot, the implementation is
still free to store things as it wants--it already carves up locations at
the virtual memory level and two things that seem "next to each other" may
be harmlessly far apart without violating the abstraction; there was also
a concern about whether people would have to represent things no  user could
get to, which also seems silly to me since if no user can get to them, you
aren't violating semantics by not representing them... bleah)
From: ····@mail.ru
Subject: Re: Scope of variables
Date: 
Message-ID: <q9gkj9.bg.ln@hermit.athome>
Kent M Pitman <······@world.std.com> wrote:
>> 
>> This makes me curious. How can a portable Lisp program tell that the
>> inner special has the same location as the outer one?  Can you show a
>> program that will break if the two had independent locations, rather
>> than save-restore taking place on one?
> 
> Sure... Compare:
> 
> (let ((x 1) f)
>  (declare (special x))
>  (setq f #'(lambda () x))
>  (print (funcall f))
>  (let ((x 2))
>    (declare (special x))
>    (print (funcall f))
>    t))
> 1
> 2
> => T
> 

Could you explain, please, why do we need the second (declare (special x)) when
we have one already? If we used (defvar x) then there wasn't any of them.

    Aleksandr Skobelev
From: Kent M Pitman
Subject: Re: Scope of variables
Date: 
Message-ID: <sfwsnfmaqmx.fsf@world.std.com>
····@mail.ru writes:

> 
> Kent M Pitman <······@world.std.com> wrote:
> >> 
> >> This makes me curious. How can a portable Lisp program tell that the
> >> inner special has the same location as the outer one?  Can you show a
> >> program that will break if the two had independent locations, rather
> >> than save-restore taking place on one?
> > 
> > Sure... Compare:
> > 
> > (let ((x 1) f)
> >  (declare (special x))
> >  (setq f #'(lambda () x))
> >  (print (funcall f))
> >  (let ((x 2))
> >    (declare (special x))
> >    (print (funcall f))
> >    t))
> > 1
> > 2
> > => T
> > 
> 
> Could you explain, please, why do we need the second (declare (special x)) when
> we have one already? If we used (defvar x) then there wasn't any of them.

Declarations made by DEFVAR work through DECLAIM.  DECLAIM and PROCLAIM make
SPECIAL declarations that are "pervasive".  They apply to contained bindings.

DECLARE dos not make pervasive declarations.  (It also does not undo a 
pervasive binding, so you can confuse yourself if you've already been 
DEFVAR'ing the same name in the same environment.  Start with a fresh 
environment to make sure you see the effect.)  A DECLARE of a SPECIAL applies
only to the binding being made by the form it applies to, not to contained
bindings.  A declaration that is not in a binding form applies to the contained
forms unless a new binding is made.

 Lisp> (locally (declare (special x))
         #'(lambda ()
             (let ((x    ; <-- lexical binding, creating closure
                    x))  ; <-- special reference due to containing DECLARE
               #'(lambda () x)))) ; <-- closed reference

 => #<FUNCTION>

 Lisp> (let ((x 3)) (declare (special x)) (funcall *))

 => #<CLOSURE>

 Lisp> (let ((x 4)) (declare (special x)) (funcall *))

 => 3

Note that the variable * in a Lisp interactive Loop holds onto the 
returned value of the previous expression.  Use this only for
interactive toying around; never in real programming.

Approximately, the motivation for this is referential transparency.
Either a variable is globally known to always be special, which is
referentially transparent, or else a variable must be affected only by
declarations to the present binding, or else code substitutions would
be a disaster.  Or so the story goes...
From: Kalle Olavi Niemitalo
Subject: Re: Scope of variables
Date: 
Message-ID: <87puajyckf.fsf@Astalo.y2000.kon.iki.fi>
Kent M Pitman <······@world.std.com> writes:

> You cannot get a "closure" over a special variable.

Was that possible in some previous Lisp?  I think I read there
was a vote on whether to remove that for Common Lisp.

If so, was there also a declaration for *not* getting a closure?

>  (defun bar ()
>    (format t "bar n: ~A a: ~A~%" n a))

Don't you have to declare N and A special there?
Or is that the default when they aren't lexically bound?
From: Kent M Pitman
Subject: Re: Scope of variables
Date: 
Message-ID: <sfwelqz8jen.fsf@world.std.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > You cannot get a "closure" over a special variable.
> 
> Was that possible in some previous Lisp?  I think I read there
> was a vote on whether to remove that for Common Lisp.

Maclisp had dynamic closures.  They worked in a kind of ad hoc way, though.
A special kind of closure had a list of special bindings to instantiate on
entry and to retrieve on exit.  The mechanism wasn't very re-entrant and was
really useless in practice.  (I can dredge up a coding example if you're
curious.)

I never used InterLisp, but I had the impression it used a-list "sphaghetti
stacks" with required deep binding and you could get a closure any part
of the sphaghetti.  If it wasn't InterLisp, I know it was some other such
old dialect that could.

> If so, was there also a declaration for *not* getting a closure?

Well, making a variable special will cause that variable to be closed.

There is no operator to say "please don't generate a closure".  The normal
way to do that is to move the definition to top-level. e.g.,

(defun foo () (mapcar #'(lambda ...not a closure...) ...))
=>
(defun foo1 () ...not a closure...)
(defun foo () (mapcar #'foo1 ...))

> >  (defun bar ()
> >    (format t "bar n: ~A a: ~A~%" n a))
> 
> Don't you have to declare N and A special there?
> Or is that the default when they aren't lexically bound?

No.  There is no default.  Though most implementations will warn you and then
auto-declare them special, that's not required and should not be depended
upon for portable code.

It could just as well-do scheme-like toplevel lexicals, which would be
beyond the scope of CL's definition.  So would the question of whether doing
so implies that the top-level special can (or cannot) share a cell with the
top-level lexical.
From: Thomas F. Burdick
Subject: Re: Scope of variables
Date: 
Message-ID: <xcvy9p6tajr.fsf@conquest.OCF.Berkeley.EDU>
Kent M Pitman <······@world.std.com> writes:

> Maclisp had dynamic closures.  They worked in a kind of ad hoc way, though.
> A special kind of closure had a list of special bindings to instantiate on
> entry and to retrieve on exit.  The mechanism wasn't very re-entrant and was
> really useless in practice.  (I can dredge up a coding example if you're
> curious.)

I'm curious.  It seems to me that the Emacs Lisp way of doing closures
in a dynamically-scoped lisp is the most sane way (ie, you use
lexical-let for anything you want to close over), but I'm curious how
people used them in lisps without hacks for faking lexicals.  Given
that you acutally used Maclisp, I'll take your word for it that its
dynamic closures weren't that usefull, but in a dynamically-scoped
lisp, dynamic closures seem like a natural, and useable, solution.
Which I guess is the thinking that caused people to implement them.
So now I'm curious what I'm missing.
From: Reini Urban
Subject: Re: Scope of variables
Date: 
Message-ID: <9ki4c7$jdc$1@fstgss02.tu-graz.ac.at>
Thomas F. Burdick <···@conquest.ocf.berkeley.edu> wrote:
: Kent M Pitman <······@world.std.com> writes:
:> Maclisp had dynamic closures.  They worked in a kind of ad hoc way, though.
:> A special kind of closure had a list of special bindings to instantiate on
:> entry and to retrieve on exit.  The mechanism wasn't very re-entrant and was
:> really useless in practice.  (I can dredge up a coding example if you're
:> curious.)

: I'm curious.  It seems to me that the Emacs Lisp way of doing closures
: in a dynamically-scoped lisp is the most sane way (ie, you use
: lexical-let for anything you want to close over), but I'm curious how
: people used them in lisps without hacks for faking lexicals.  Given
: that you acutally used Maclisp, I'll take your word for it that its
: dynamic closures weren't that usefull, but in a dynamically-scoped
: lisp, dynamic closures seem like a natural, and useable, solution.
: Which I guess is the thinking that caused people to implement them.
: So now I'm curious what I'm missing.

try to implement an event-driven GUI for example with such dynamic
closures. esp. multi-threaded. it will not work.
lexical closures also have massive performance advantages. 
see SICP.

I also tried to implement dynamic closures for my dynamic lisp, 
but it failed miserably. not worth the effort. much better is imho to
convert the lisp to lexical and re-invent dynamic scope for specials. 
which was actually done with autolisp. this way the compiler (and GUI) 
can do the real thing and the user still mess around with its old habits.
-- 
Reini Urban
http://xarch.tu-graz.ac.at/acadwiki/AutoLispFaq
From: ···@itasoftware.com
Subject: Re: Scope of variables
Date: 
Message-ID: <hevu1slf.fsf@itasoftware.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > You cannot get a "closure" over a special variable.
> 
> Was that possible in some previous Lisp?  I think I read there
> was a vote on whether to remove that for Common Lisp.

ZetaLisp (Lisp Machine Lisp) had dynamic closures.