This is the mail archive of the guile-emacs@sourceware.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: Emacs with Guile


Richard Stallman <rms@gnu.org> writes:

> Can you tell me more about the conversion of objects between Lisp and
> Scheme?

My code has essentially two new primitives: scheme-eval for Lisp
programs, and lisp-eval for Scheme programs.  This is how they look like:

  DEFUN ("scheme-eval", Fscheme_eval, Sscheme_eval, 1, 1, 0,
         "Evaluate a Guile Scheme expression.")
       (obj)
       Lisp_Object obj;
  {
    return scm_to_lisp (scm_eval (lisp_to_scm (obj)));
  }

  SCM_DEFINE (lisp_eval, "lisp-eval", 1, 0, 0,
              (SCM obj),
              "Evaluate an Emacs Lisp expression.")
  {
    return lisp_to_scm (Feval (scm_to_lisp (obj)));
  }

(Practically, there are some more code, such as error handling.)

This is how I plan to accomplish the conversion:
(Not implemented all of these yet.)

0. ( Everything begins in the Lisp world. )

1. When scheme-eval is called from the Lisp side, the argument
   (usually an expression) is recursively converted into an
   equivalent Scheme object: Lisp symbol to Scheme symbol, Lisp
   cons to Scheme cons, etc.  At this level, the argument should
   not include such an object that is special to Emacs Lisp (e.g.,
   buffer, window, frame); otherwise, it makes an error. [done]

2. The converted object is evaluated by the Scheme interpreter.
   Let's go into the Scheme world. [done]

3. A Scheme program may call lisp-eval to obtain the property of
   Emacs Lisp.  The argument is converted into a Lisp object in
   a similar way to above and evaluated by the Lisp interpreter.
   [Error handling at this level for Scheme programs is not done.]

4. The Lisp interpreter may return a special object such as a buffer.
   At this level, any kind of a return value is converted into a
   special Scheme object called "Lisp reference."  A Scheme program
   may use this value as a parameter of lisp-eval so that it can be
   used with other Lisp functions.  In order to convert the reference
   to an equivalent Scheme object, a programmer has to do explicit
   dereference.  [not all but some are converted.]

5. A Scheme program may return any object to the Lisp interpreter.
   If it is a Lisp reference, it is converted to an actual Lisp
   object.  Otherwise, a special Lisp object "Scheme reference"
   will be created.  A Scheme reference can be a parameter of
   scheme-eval, but a Lisp program should not keep this value more
   than temporary in order to avoid circular references between
   Lisp data and Scheme data, which makes GC process too complex.
   [ not done ]

Thus, the Lisp interpreter and the Scheme interpreter is called by
each other, and objects are converted appropriately.

Using some convenient macros and tricks, the current Emacs Scheme
programs looks like this:

  ;; Define a Scheme module and use related utils
  (define-module (foo bar)
    :use-module (emacs emacs))

  ;; Import a function from the Lisp world.
  (import-lisp-function insert)

  ;; Import a variable from the Lisp world.
  (import-lisp-variable user-full-name)

  ;; Call a Lisp function with the reference of variable
  (insert user-full-name)

  ;; Get the value of variable as a Scheme object (dereference)
  (define name (user-full-name))

  ;; Set the value of variable.  This actually changes the value
  ;; of Lisp variable `user-full-name'.
  (set! (user-full-name) name)

  ;; Now we can define a new Emacs command like this
  (define-command (scheme-interaction-mode)
    "Scheme Interaction mode."
    (interactive)
    (kill-all-local-variables)
    (use-local-map scheme-interaction-mode-map)
    (set! (major-mode) 'scheme-interaction-mode)
    (set! (mode-name) "Scheme Interaction")
    (set-syntax-table scheme-mode-syntax-table)
    (scheme-mode-variables)
    (run-hooks 'scheme-interaction-mode-hook))

I am not sure if we can use this program in the future with the real
Guile-based Emacs, but I think this code looks the best with my Guile
Emacs.

> What I would like to have in Emacs eventually is support
> for both Lisp and Scheme but with all objects represented in
> just one form (presumably the form Guile needs).

I think it is the right way, and I know my approach is not very good.
But I would like to use Guile's features with Emacs as soon as possible.
My approach is extremely easy to implement.  My patch to the C source
is less than 500 lines right now.  This works.

> However, I do not think we should try to rewrite all the Emacs Lisp
> code into Scheme.  After all, users have lots of Lisp code too.
> So elimination of support for Emacs Lisp should not be a goal,
> not even for the future.

The best advantage of my code is it does not do anything with Lisp
internals, which means all Emacs Lisp code successfully work without
any problem.  I am not going to replace Emacs Lisp programs by Scheme
programs, but I just want to add support for Guile Scheme in addition
to Emacs Lisp before replacing the Lisp internals with Guile.

My project is a temporary project in a sense.  After becoming easy to
utilize Guile's features within Emacs, I will be one for Guile-based
Emacs.

Best Regards,
Keisuke Nishida

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]