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]

fluid-let



I've been having fun recently learning defmacro, so I decided to try
to whip up fluid-let in terms of dynamic-wind (I know it's already in
slib).

My attempt seems to work; give it a whirl and let me know if you
agree.  The question I have is: how would one do this with
(make-fluid) instead of (gensym) so that this would work with threads?
Is it really basically just a couple of substitutions?

Here's my quick hack:

(defmacro fluid-let (binding-ls . body)
  (let* ((expanded-binding-ls 
	  (map (lambda (binding) 
		 (append binding (list (gensym))))
	       binding-ls))
	 (initial-set!-ls 
	  (map (lambda (binding)
		 `(set! ,(car binding) ,(cadr binding)))
	       expanded-binding-ls))
	 (save-set!-ls 
	  (map (lambda (binding)
		 `(define ,(caddr binding) ,(car binding)))
	       expanded-binding-ls))
	 (final-set!-ls 
	  (map (lambda (binding)
		 `(set! ,(car binding) ,(caddr binding)))
	       expanded-binding-ls)))
    `(begin
      ,@save-set!-ls
      (dynamic-wind
       (lambda () ,@initial-set!-ls)
       (lambda () ,@body)
       (lambda () ,@final-set!-ls)))))

and now some code to test it:

(define a 2)
(define b 4)
(for-each display `(a ":" ,a " " b ":" ,b "\n"))
(fluid-let ((a (* a a))
	    (b (* b b)))
	   (for-each display `(a ":" ,a " " b ":" ,b "\n"))
	   (error "out of here"))
(for-each display `(a ":" ,a " " b ":" ,b "\n"))


-russ