[CM] scoping in scheme

Michael Klingbeil michael@klingbeil.com
Wed, 29 Oct 2003 16:59:13 -0500


You can get this effect in Scheme using fluid-let (if your 
implementation of Scheme supports fluid-let, or if you define it 
yourself)


(define test-proc
  (lambda ()
    (set! i (+ i 2))))

(define i -3)
(list (fluid-let ((i 1))
         (test-proc)
         i)
       i)

=> (3 -3)


Note the the define was moved to toplevel. According to the R5RS 
specification, a define with in the body of a begin (or other lambda 
expression) is going to be local to that body only. So in a strict 
R5RS implementation you would get an error when calling test-proc 
since i would be unbound. (See the section "Internal definitions" in 
R5RS).

Guile seems to let you get away with this. Chez scheme does not. 
MzScheme doesn't seem to like the internal define right after begin 
at all. Except this works in MzScheme:

(list
  (let ()
   (define i -3)
   (let ((i 1))
     (test-proc)
     i))
  i)

Anyway to complicate matters fluid-let is NOT part of R5RS. But it is 
available in Chez scheme and MzScheme. And you can add fluid let to 
Guile with a syntax expansion maco. See 
http://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-19.html 
for details.

Not sure what Scheme you are using.

Anyway the mechanism of fluid-let essentially creates a temporary 
binding for the toplevel value of i. So it  does not actually create 
a new lexical variable. Instead it assigns the desired value to the 
current lexical value, and then it restores the old value upon 
exiting from the body of the fluid-let.



>Hi,
>
>hope this is not too off topic: Is it possible to define a top-level
>closure in scheme which acesses (and changes) variables from the
>dynamically scoped environment it is called in?
>
>In the following example i is bound at define time and its value in a
>function call is always taken from the definition's lexical context:
>
>(define test-proc
>  (lambda ()
>    (set! i (+ i 2))))
>
>(list
>  (begin
>   (define i -3)
>   (let ((i 1))
>     (test-proc)
>     i
>     )
>   )
>  i)
>
>=> (1 -1)
>
>It would be nice if the result could be made to be (3 -3) without
>having to supply i as arguments to test-func. Test-func is only
>evaluated for its side effects which should affect the variable's
>meanings in the current dynamic context of the function call.
>
>It might be either trivial or the wrong way to go about the whole
>thing but I thought I'd ask anyway.
>
>Any ideas?
>Orm
>
>_______________________________________________
>Cmdist mailing list
>Cmdist@ccrma.stanford.edu
>http://ccrma-mail.stanford.edu/mailman/listinfo/cmdist