Re: fluid-let

Marius Vollmer (mvo@zagadka.ping.de)
17 Aug 1998 21:04:38 +0200

Russ McManus <mcmanr@eq.gs.com> writes:

> Is this closer?

Yep. You might want to look at fluidlet.scm from SLIB and see how
they do it with syntax-rules macros. You might also note (as I have
just this moment) that `fluid-let' from SLIB does not save the
external values on reentry, which I find strange. What do you say, is
it a bug in SLIB?

> (defmacro fluid-let (binding-ls . body)
> (let* ((expanded-binding-ls
> (map (lambda (binding)
> (append binding (list (gensym))))

You might want to put the gensym first, with (cons (gensym) binding).

> binding-ls))
> (tmp-var (gensym))
> (environment-ls
> (map (lambda (binding)
> `(,(caddr binding) ,(cadr binding)))
> expanded-binding-ls))
> (swap-ls
> (map (lambda (binding)
> `(begin
> (set! ,tmp-var ,(car binding))
> (set! ,(car binding) ,(caddr binding))
> (set! ,(caddr binding) ,tmp-var)))

Binding temp-var with `let' might be cleaner here.

`(let ((,tmp-var ,(car binding)))
(set! ,(car binding) ,(caddr binding))
(set! ,(caddr binding) ,tmp-var))

> expanded-binding-ls)))
> `(let ,environment-ls
> (let ((,tmp-var #f))
> (dynamic-wind
> (lambda () ,@swap-ls)
> (lambda () ,@body)
> (lambda () ,@swap-ls))))))

I think there is no need to duplicate the (lambda () ,@swap-ls), just
make one closure outside of the dynamic-wind.

> Now on to with-fluids...

And after that you might want to try to express fluid-let with
defmacro but *without* gensym, while still being referential
transparent.