This is the mail archive of the guile@cygnus.com mailing list for the guile project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes: > is it possible to get and change the environment of a given closure? In general, no. It might be possible by changing the module that a closure belongs to, and thereby affecting its top-level bindings, but I do not recommend that in any case. > The function > > (define f (lambda (arg) (display arg) (display x) (display y) ) > > has an environment, which is an obarray with one entry: "arg". More precisely, the environment includes *all* bindings that are lexically visible at the point of the lambda. This includes all bindings made outside the lambde, including all top-level bindings ("f", for example). It does *not* include "arg", which is a free variable inside the lambda. Each time you invoke f, a new binding for "arg" is made, and a new environment is constructed by extending the environment of "f" with this new binding. Now, there must also exist bindings for "x" and "y" in the environment for f (everything else would lead to an error). Say they are at the top-level: (define x #f) (define y #f) (define f (lambda (arg) (display arg) (display x) (display y))) In Scheme, you can't change the environment of a closure, so "x" and "y" in the body of f will always refer to the bindings introduced by the two defines for "x" and "y". You can only change the *values* that these bindings have while calling f. You want to do this only temporarily, so that "x" and "y" revert to their old values after f has returned. This is what `fluid-let' is intended to do. So (define b (lambda (arg) (fluid-let ((x 1) (y 2)) (f arg)))) This expands into something like (define b (lambda (arg) (let ((old-x 1) (old-y 2)) (let ((swapper (lambda () (swap x old-x) (swap y old-y)))) (dynamic-wind swapper (lambda () (f arg)) swapper))))) with (define-macro (swap a b) (let ((t (gensym))) `(let ((,t ,a)) (set! ,a ,b) (set! ,b ,t)))) See the other thread about `fluid-let'.