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]

Guile and Emacs (was Re: Initial projects list)


Here's one to add, alas with no URL or available code as yet.

I've been hacking on Emacs.  Currently I have an Emacs using Scheme
objects for cons cells and numbers, and the Guile allocator and
garbage collector; Scheme strings are in the works.  Currently Emacs
strings (with text properties) and symbols and "vectorlike" and "misc"
objects and so on are all smobs.  The Emacs Lisp engine is still used;
no Scheme code is run, and even if it were, there's no handle on the
Emacs Lisp objects that would be accessible from Scheme.

This was the easy part.  I'm getting into areas now where I'm not
familiar enough with Scheme or Guile to be entirely sure how to
proceed.  (Most of the Scheme I know is whatever I needed for my intro
CS course at MIT about fifteen years ago.)  So, I'm asking for
advice...

I want to run both Scheme and Emacs Lisp code, letting them
interoperate.  But the Scheme code should work according to Scheme
rules, and Emacs Lisp according to the usual elisp rules.  (For the
()/nil/#f issues, I've got Jim's write-up from the middle of last
year, from the mailing list archives.  That seems like a good start.)
Dynamic versus lexical scoping is a big issue here, obviously.

And if the dynamic scoping is to do something reasonable when multiple
threads are involved... well, my multithreaded programming experience
lately has been limited to ranting about why various libraries aren't
thread-safe; I don't have a lot of positive experience.  My simplistic
view at the moment is that Lisp "let" and argument bindings should
affect only the current thread and any created while the binding is in
effect.  Since Emacs Lisp doesn't (currently) do multiple threads, and
normal Scheme code doesn't use the Lisp bindings, I don't need to
worry about carrying Lisp bindings across threads when passing data
between threads.  If someone else wants to worry about it, fine, but
it's not my problem.

I think the right approach is for Scheme code to have to explicitly
look up the current Lisp binding of a variable, otherwise it gets the
usual Scheme environment.  An elisp-eval is probably needed, which
looks up the symbol-function for the first operand, and causes
everything to be evaluated as elisp, using elisp bindings, etc --
effectively translating the elisp at run-time to Scheme code that
explicitly requests the dynamic elisp bindings.  Static translation
can be done later, but I don't think we'll ever get rid of Emacs Lisp
code that calls eval, so that may be the best place to start.

What I'm experimenting with a little right now is calling eval2 with a
lookup function that uses (fluid-ref the-emacs-environment) to get a
list of binding scopes in which to look things up, but then I find
that I really don't know what this lookup function is supposed to be
returning, much less whether this approach is even going to work. :-)

Or maybe elisp code shouldn't be using the same symbols as Scheme, for
a given name?  Perhaps the Emacs Lisp obarray should be independent,
with hooks accessible from each language to give access to the other's
symbol tables.

Is there any sort of "advanced tutorial", that describes environments,
modules, fluids, symbols versus "variable" objects versus bindings and
so on?  Even a reference manual with examples would probably be a good
start.  (I've been looking at guile-doc/ref, and it's got some of it,
but there are lots of pieces missing, especially Guile-specific info.)

Also, is there a pointer to how to translate Guile modules to C with
the current sources?  Patches needed, anything about the way I need to
write my Scheme code, etc.  (I tried the stuff in the guile-comp
directory, but the configure.in script doesn't even have the right
list of Makefiles to generate, and after fixing that, I get a ghobbit
that just complains "Unbound variable: require".)

Ken

P.S.  I'm trying to get CVS space for this, in case anyone else is
interested in hacking/reviewing/testing the code.