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: Changing the environment


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