From mboxrd@z Thu Jan 1 00:00:00 1970 From: Keisuke Nishida To: guile-emacs@sourceware.cygnus.com Cc: guile@sourceware.cygnus.com Subject: Dynamic binding: lisp-ref and lisp-set! Date: Fri, 05 May 2000 08:21:00 -0000 Message-id: References: X-SW-Source: 2000-q2/msg00027.html Hello, (This message is about Guile Emacs, but is also something about Guile in general.) I'm thinking of not using procedure-with-setter to refer to Lisp variables. The binding to Lisp variables is dynamic, and I'm not sure about the Guile's dynamic features. One Guile's (kind of) dynamic variable is fluid, which changes the value depending on the current dynamic root. A fluid uses fluid-ref and fluid-set! to access the value. I guess we'd better use the same way for Lisp variables. This is a GOOPS version of lisp-ref/set!: (define-class () (sym #:accessor sym #:init-keyword #:symbol) (var #:allocation #:virtual #:slot-ref (lambda (i) (%lisp-eval (sym i))) #:slot-set! (lambda (i v) (%lisp-eval `(setq ,(sym i) ',v)) *unspecified*) #:getter lisp-ref #:setter lisp-set!)) (define-method (write (obj ) port) (display "#" port)) (define name (make #:symbol 'user-full-name)) name => # (lisp-ref name) => # 40480ce0> (%lisp->scheme (lisp-ref name)) => "Keisuke Nishida" The new Emacs Scheme code might look like this: (insert (lisp-ref user-full-name)) We could do the same thing more naturally by defining a procedure so as to accept : (define-method (insert (obj )) (insert (lisp-ref obj))) (insert user-full-name) However, this requires us to define similar methods for all procedures, which is practically impossible. In order to write the latter natural expression (in the sense of Emacs Lisp), I guess we have to modify the Guile's evaluator so that it handles special objects like this: (define foo (make-dynamic-object (lambda () (make-variable #f)) (lambda (variable) (variable-ref variable)) (lambda (variable value) (variable-set! variable value)))) foo => #f (set! foo "Hello") foo => "Hello" Using this object, a fluid can be written as (define foo (make-dynamic-object (lambda () (make-fluid)) (lambda (fluid) (fluid-ref fluid)) (lambda (fluid value) (fluid-set! fluid value)))) foo => #f (set! foo "Hello") foo => "Hello" and our Lisp reference can be written as (define foo (make-dynamic-object (lambda () 'user-full-name) (lambda (symbol) (%lisp-eval symbol)) (lambda (symbol value) (%lisp-eval `(setq ,symbol ',value))))) foo => # 40480ce0> (set! foo "Hello") foo => # 40480ce8> I asked about the Guile's new top-level environment if I could use it to do my job, but the answer was no. The environment also seems to be (kind of) static; that is, environment-ref/set! is called only once at evaluation time (not at run time). I believe make-dynamic-object can be implemented, but I'm not sure whether it is a good thing or not. What do people think? Thanks, -- Kei