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]

Re: fluid-let


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.