Closure around defun 
Author Message
 Closure around defun

I am having some difficulty understanding the behavior of the following:
(let ((*my-print-length* 10))
  (defun foo ()
    (let ((*print-length* *my-print-length*))
      (print *print-length*)
      t)))

(let ((*print-length* 10)
      (*my-print-length* 8))
  (defun bar ()
    (print *print-length*)
    (print *my-print-length*)
    t))

Assuming *print-length* is NIL at the top level. Within #'foo
*print-length* is 10 (inside the let of course). Within #'bar
*print-length* is NIL. I expected *print-length* to be 10 inside both.
Could someone explain why this happens? Thank you.

Side note: This started as trying to have a special readtable that
affected only one function. Wrapping a defun with a let seemed like
a slicker way to accomplish that than binding *readtable* to a global
*my-readtable* within the function (ala #'foo). After investigation
I noticed that any LISP special variable I tried showed the same
property as exhibited above by *print-length*.

Once again thanks a lot for your help.
Hope you have a very nice day. :-)


Hamline University             St. Paul, MN  USA              



Sat, 03 Aug 1996 03:49:40 GMT  
 Closure around defun
  The point is that your *print-length* is implicitly "special" because
declared in a
(DEFVAR *PRINT-LENGTH* nil)
  at the initialization of Lisp.

  Do the following experience:

Quote:
> (setf x 10)  ==>
10
> (let ((x 100))

    (defun bar () x))  ==>
BAR
Quote:
> (bar)  ==>
100
> (defvar x)  ==>
X
> x  ==>
10
> (let ((x 100))

    (defun bar () x))  ==>
BAR

Quote:
> (bar)  ==>
10

  Why these strange facts ? My personal model (is it right ??) is that
at  any  time you   have  the  global-environment-stack and  also  the
local-environment-stack.   When Lisp enters   a let,  it  adds the new
value, sorry the new binding in the official terminology, on the local
stack.  If a closure  is created, this local stack  is  keeped in this
closure. This was the case for the first definition of bar above.

  But if the  variable   is special, this    new binding, sorry   this
value..., is added on the global-environment. The local environment is
saved inside  a  created closure,  but it does   not  contain this new
value. Secondly when the  let is finished,  this new value  is removed
from the  global-environment.  This is  better showed in the following
extended examples.  Don't forget that evaluating  a symbol returns the
binding (local value) if  defined,  and on the  contrary (symbol-value
...) returns the global  one only and  the highest one if several have
been defined.

Quote:
> (setf y 10)  ==>
10
> (let ((y 100))

    (print y)
    (print (symbol-value 'y))
    (defun bar () y))  ==>
100
10
BAR
Quote:
> (bar)  ==>
100
> (defvar y)  ==>
Y
> y  ==>
10
> (let ((y 100))

    (print y)
    (print (symbol-value 'y))
    (defun bar () y))  ==>
100
100
BAR

Quote:
> (bar)  ==>
10

Look also at this example:

Quote:
> (let ((z 10))

    (declare (special z))
    (defun foo () z))  ==>
FOO
Quote:
> (foo)  ==>

ERROR : z is unbound.

The value  of   z  is lost because   it  was  available only  on   the
global-stack and was not stored inside the closure.

And also:

Quote:
> (let ((a 10))

    (declare (special a))
    (defun foo () (bar)))  ==>
FOO
Quote:
> (let ((a 100))

    (defun bar () a))  ==>
BAR

Quote:
> (foo)  ==>
100

because the a of the second let is pushed on the local-stack, therefore
keeped inside the definition of bar.

Personnally I regret  this model (or the right  one) is  not described
int the CLtLn; this would make much simpler the understanding of these
very esoteric notions of bindings vs values, extents vs scopes, etc.



Sat, 03 Aug 1996 18:10:51 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. CGOL revisited: A Pratt parser for SIOD (scheme in one defun)

2. new version of SIOD, Scheme in One Defun

3. Looking for SIOD (Scheme in One Defun)

4. compiler-time side effects of defun

5. Novice question: (defun (setf f)) ???

6. defgeneric and then defun signals no error

7. Limitation of lambda list in DEFUN form?

8. Simple defun list passing question

9. retrieving a lost defun

10. defun

11. defun within let

12. about (defun (setf primo) (val lst)..)

 

 
Powered by phpBB® Forum Software