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] |
On Fri, Aug 21, 1998 at 09:07:47AM +0200,
it occurred to Marius Vollmer to write:
> 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.
Of course, a simple set! changes the environment, too.
Here's a little implementation of a special set! I had to make to get
SIOD compatibility (for GIMP's script-fu scripts which extensively
have the habit of set!ing undefined variables because SIOD allows it
and the authors didn't know better..)
;; SIOD's set! is really screwed up. If the variable being set is
;; unbound, it is bound at the top level. Otherwise it is reset. So we
;; have to find out if a variable is bound in a _local_ environment.. thus
;; we create the syntax manually. Also, SIOD set! returns the new value.
;; There would be no prob otherwise, but all scripts use these "features"..
(define-public set!
; we memoize the correct place for the variable..
(procedure->memoizing-macro
(lambda (exp env)
(define variable (cadr exp))
(define value (caddr exp))
(let loop ((e env))
(define frame (car e))
`(begin
(,@(cond ((procedure? frame)
; here we create the top level binding
`(',variable-set! ',(frame variable #t)))
((eq? (car frame) variable)
`(',set-cdr! ',frame))
((and (list? frame) (list-index (car frame) variable))
=> (lambda (i)
`(',set-car! ',(list-tail (cdr frame) i))))
(else (loop (cdr e))))
,value)
,variable)))))
Is there some better way to do this? There is no "local-defined?"
procedure to my knowledge..
Lauri Alanko
la@iki.fi