From: ·········@olive-it.ch
Subject: dynamic variable in closure/object
Date: 
Message-ID: <1187650433.971132.31000@o80g2000hse.googlegroups.com>
An instance of a class in a closure and I want the object to be a
special variable
Confusion totalis, really.
Boiled down:
(defclass aclass ()
  ((aslot :initarg aslot)))

(defun do-it ()
  (format nil "aslot of object o is ~a" (SLOT-VALUE o 'aslot)))

CL-USER> (LET ((o (MAKE-INSTANCE 'aclass)))
	             ;;(declare (special o))
	             (setf (slot-value o 'aslot)
		             (lambda ()
		                 (format nil "aslot of object o is ~a" (SLOT-VALUE o
'aslot))))
	             o)
#<ACLASS {AA6E1E1}>
CL-USER> (funcall (slot-value * 'aslot))
"aslot of object o is #<CLOSURE (LAMBDA ()) {AA6E205}>"
--> This I do understand
CL-USER> (LET ((o (MAKE-INSTANCE 'aclass)))
	             (declare (special o))
	             (setf (slot-value o 'aslot)
		             (lambda ()
		                 (format nil "aslot of object o is ~a" (SLOT-VALUE o
'aslot))))
	             o)
#<ACLASS {AA96261}>
CL-USER> (funcall (slot-value * 'aslot))
; Evaluation aborted
--> Variable o is unbound: This I don't understand. I fact I would
like to write something like this let:
CL-USER> (LET ((o (MAKE-INSTANCE 'aclass)))
	             (declare (special o))
	             (setf (slot-value o 'aslot)
		             (lambda ()
		                 (do-it)))
	           o)
#<ACLASS {AB0C591}>
CL-USER> (funcall (slot-value * 'aslot))
; Evaluation aborted
--> Variable o is unbound:
I would like to have the user redefine do-it and to have him access
special variable o
Maybe this will change, however I would like to understand why I can't
access o in both cases where o is declared special
thanx
olli

From: Barry Margolin
Subject: Re: dynamic variable in closure/object
Date: 
Message-ID: <barmar-CD514E.19452820082007@comcast.dca.giganews.com>
In article <·······················@o80g2000hse.googlegroups.com>,
 ·········@olive-it.ch wrote:

> I would like to have the user redefine do-it and to have him access
> special variable o
> Maybe this will change, however I would like to understand why I can't
> access o in both cases where o is declared special

Common Lisp only has LEXICAL closures.  They only close over lexical 
variables, not special variables.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: ·········@olive-it.ch
Subject: Re: dynamic variable in closure/object
Date: 
Message-ID: <1187730365.034548.131810@a39g2000hsc.googlegroups.com>
On Aug 21, 1:45 am, Barry Margolin <······@alum.mit.edu> wrote:
> In article <·······················@o80g2000hse.googlegroups.com>,
>
>  ·········@olive-it.ch wrote:
> > I would like to have the user redefine do-it and to have him access
> > special variable o
> > Maybe this will change, however I would like to understand why I can't
> > access o in both cases where o is declared special
>
> Common Lisp only has LEXICAL closures.  They only close over lexical
> variables, not special variables.
>
Well, I thought that's why there is the special declaration:
(let ((x 10))
   (declare (special x)
...
makes x a special variable in the let body

oli
From: Kaz Kylheku
Subject: Re: dynamic variable in closure/object
Date: 
Message-ID: <1187739469.307431.102280@z24g2000prh.googlegroups.com>
On Aug 21, 2:06 pm, ·········@olive-it.ch wrote:
> On Aug 21, 1:45 am, Barry Margolin <······@alum.mit.edu> wrote:
> > Common Lisp only has LEXICAL closures.  They only close over lexical
> > variables, not special variables.
>
> Well, I thought that's why there is the special declaration:
> (let ((x 10))
>    (declare (special x)
> ...
> makes x a special variable in the let body

Yes, and consequently, lexical closures won't close over x.
From: Kent M Pitman
Subject: Re: dynamic variable in closure/object
Date: 
Message-ID: <ud4xgquwy.fsf@nhplace.com>
Kaz Kylheku <········@gmail.com> writes:

> On Aug 21, 2:06 pm, ·········@olive-it.ch wrote:
> > On Aug 21, 1:45 am, Barry Margolin <······@alum.mit.edu> wrote:
> > > Common Lisp only has LEXICAL closures.  They only close over lexical
> > > variables, not special variables.
> >
> > Well, I thought that's why there is the special declaration:
> > (let ((x 10))
> >    (declare (special x)
> > ...
> > makes x a special variable in the let body
> 
> Yes, and consequently, lexical closures won't close over x.

Which is why (not to beat a dead horse, but sometimes this seems to
require repetition) one should, except in extraordinary cases, always
name variables declared with DEFVAR using *'s around their names, so
you don't accidentally do this to a non-starred variable like X and
then wonder for ever after why closures seem broken.  [Hint:
Situations like this don't come along often.  As a matter of good
style, if you have any question whatsoever on how to safely use these
language constructs, don't _ever_ use DEFVAR, DEFPARAMETER, or
(PROCLAIM '(SPECIAL ...)) or (DECLAIM (SPECIAL ...)) with variable
names that don't have *'s on both ends.
From: Pillsy
Subject: Re: dynamic variable in closure/object
Date: 
Message-ID: <1187699092.128304.3500@k79g2000hse.googlegroups.com>
On Aug 20, 6:53 pm, ·········@olive-it.ch wrote:
> An instance of a class in a closure and I want the object to be a
> special variable
> Confusion totalis, really.

I'm not exactly sure what you're trying to get at, but I'll show you
what will work. First, it's customary, if you need to have the user be
able to control your program by changing the value of a special
variable, to define the variable using DEFVAR, like so[1]:

(defclass a-class () ((a-slot :initarg :a-slot :accessor a-slot)))

(defvar *instance* (make-instance 'a-class :a-slot 'blargle))

(defun a-slot-value () (a-slot *instance*))

Then you can do this:

(a-slot-value) => BLARGLE

(let ((*instance* (make-instance 'a-class :a-slot 'flarble)))
  (a-slot-value)) => FLARBLE

Is this what you're trying to do?

Cheers,
Pillsy

[1] See http://www.lisp.org/HyperSpec/Body/mac_defparametercm_defvar.html
From: ·········@olive-it.ch
Subject: Re: dynamic variable in closure/object
Date: 
Message-ID: <1187731537.715421.197200@d55g2000hsg.googlegroups.com>
On Aug 21, 2:24 pm, Pillsy <·········@gmail.com> wrote:
> On Aug 20, 6:53 pm, ·········@olive-it.ch wrote:
>
> > An instance of a class in a closure and I want the object to be a
> > special variable
> > Confusion totalis, really.
>
> I'm not exactly sure what you're trying to get at, but I'll show you
> what will work. First, it's customary, if you need to have the user be
> able to control your program by changing the value of a special
> variable, to define the variable using DEFVAR, like so[1]:
>
> (defclass a-class () ((a-slot :initarg :a-slot :accessor a-slot)))
>
> (defvar *instance* (make-instance 'a-class :a-slot 'blargle))
>
> (defun a-slot-value () (a-slot *instance*))
>
> Then you can do this:
>
> (a-slot-value) => BLARGLE
>
> (let ((*instance* (make-instance 'a-class :a-slot 'flarble)))
>   (a-slot-value)) => FLARBLE
>
> Is this what you're trying to do?
I'm not sure of what I wanted, I just didn't understand why my dynamic
variables didn't work.
Now that you introduced defvar I found this gem:

                       Because DEFVAR does more than just establish a
dynamic
binding for X. It pervasively declares all references to X and all
subsequent
bindings for X to be dynamic (or special -- same thing). In other
words, DEFVAR
turns its argument (permanently and pervasively) into a special
variable.
Thanx to Erann Gat

This may be the way go, however the declared variable becomes
accessible at top-level.
It just doesn't explain the use of (declare (special o))
Oh well, thanx anyhow
>
> Cheers,
> Pillsy
>
> [1] Seehttp://www.lisp.org/HyperSpec/Body/mac_defparametercm_defvar.html
From: Kaz Kylheku
Subject: Re: dynamic variable in closure/object
Date: 
Message-ID: <1187740403.133888.192670@q3g2000prf.googlegroups.com>
On Aug 20, 3:53 pm, ·········@olive-it.ch wrote:
> An instance of a class in a closure and I want the object to be a
> special variable
> Confusion totalis, really.
> Boiled down:
> (defclass aclass ()
>   ((aslot :initarg aslot)))
>
> (defun do-it ()
>   (format nil "aslot of object o is ~a" (SLOT-VALUE o 'aslot)))
>
> CL-USER> (LET ((o (MAKE-INSTANCE 'aclass)))
>                      ;;(declare (special o))
>                      (setf (slot-value o 'aslot)
>                              (lambda ()
>                                  (format nil "aslot of object o is ~a" (SLOT-VALUE o
> 'aslot))))
>                      o)
> #<ACLASS {AA6E1E1}>
> CL-USER> (funcall (slot-value * 'aslot))
> "aslot of object o is #<CLOSURE (LAMBDA ()) {AA6E205}>"
> --> This I do understand
> CL-USER> (LET ((o (MAKE-INSTANCE 'aclass)))
>                      (declare (special o))
>                      (setf (slot-value o 'aslot)
>                              (lambda ()
>                                  (format nil "aslot of object o is ~a" (SLOT-VALUE o
> 'aslot))))
>                      o)
> #<ACLASS {AA96261}>
> CL-USER> (funcall (slot-value * 'aslot))
> ; Evaluation aborted
> --> Variable o is unbound: This I don't understand. I fact I would
> like to write something like this let:
> CL-USER> (LET ((o (MAKE-INSTANCE 'aclass)))
>                      (declare (special o))
>                      (setf (slot-value o 'aslot)
>                              (lambda ()
>                                  (do-it)))
>                    o)

Not sure what you think the LAMBDA will do here. The body of this
lambda makes no references to any variables, and so it doesn't capture
anything at all.

> #<ACLASS {AB0C591}>
> CL-USER> (funcall (slot-value * 'aslot))

This FUNCALL is no longer in the dynamic scope of the LET. The LET
block has terminated, tearing down the dynamic binding set up for
variable O.

So the call to DO-IT, trampolined through your closure, will try to
access the top-level binding of O. You don't have one.

What you can do is lexically capture some other variable, and then in
your closure, rebind the value of that variable to the special O.

You really shouldn't use these special declarations. In general, if
you want a special variable, define it with DEFVAR or DEFPARAMETER,
and give it an appropriate name delimited by asterisks.

  (defvar *o*)

  (defun do-it ()
    (format nil "aslot of object o is ~a" (SLOT-VALUE o 'aslot)))

  (let ((o (make-instance 'aclass)))
     (setf
        (slot-value o 'aslot)
        (lambda ()
          (let ((*o* o))
            (do-it))))
      o)

Now this LET return an object whose ASLOT is a function which binds
that object to the special variable *O* and invokes DO-IT.