public inbox for
 help / color / mirror / Atom feed
From: Keisuke Nishida <>
Subject: Dynamic binding: lisp-ref and lisp-set!
Date: Fri, 05 May 2000 08:21:00 -0000	[thread overview]
Message-ID: <> (raw)
In-Reply-To: <>


(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 <lisp-variable> ()
    (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))
         #:getter lisp-ref
         #:setter lisp-set!))

  (define-method (write (obj <lisp-variable>) port)
    (display "#<lisp-variable " port)
    (display (sym obj) port)
    (display ">" port))

  (define name (make <lisp-variable> #:symbol 'user-full-name))

  => #<lisp-variable user-full-name>
  (lisp-ref name)
  => #<foreign-object <emacs-string> 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 <lisp-variable>:

  (define-method (insert (obj <lisp-variable>))
    (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 => #<foreign-object <emacs-string> 40480ce0>
  (set! foo "Hello")
  foo => #<foreign-object <emacs-string> 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?

-- Kei

  reply	other threads:[~2000-05-05  8:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-05-05  6:47 New internal implementation Keisuke Nishida
2000-05-05  8:21 ` Keisuke Nishida [this message]
2000-05-06  5:37 ` Satoru Takabayashi
2000-05-06  6:57   ` Keisuke Nishida
2000-05-06 15:50     ` Satoru Takabayashi
2000-05-06 17:43       ` Keisuke Nishida
2000-05-07  2:27         ` Satoru Takabayashi
2000-05-07  2:58           ` Keisuke Nishida
     [not found]         ` <>
     [not found]           ` <>
2000-05-07  3:14             ` Satoru Takabayashi
2000-05-07  3:41               ` Keisuke Nishida

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).