]> git.donarmstrong.com Git - lilypond.git/blobdiff - guile18/lang/elisp/README
Import guile-1.8 as multiple upstream tarball component
[lilypond.git] / guile18 / lang / elisp / README
diff --git a/guile18/lang/elisp/README b/guile18/lang/elisp/README
new file mode 100644 (file)
index 0000000..1cecb38
--- /dev/null
@@ -0,0 +1,303 @@
+                                                    -*- outline -*-
+
+This directory holds the Scheme side of a translator for Emacs Lisp.
+
+* Usage
+
+To load up the base Elisp environment:
+
+    (use-modules (lang elisp base))
+
+Then you can switch into this module
+
+    (define-module (lang elisp base))
+
+and start typing away in Elisp, or evaluate an individual Elisp
+expression from Scheme:
+
+    (eval EXP (resolve-module '(lang elisp base)))
+
+A more convenient, higher-level interface is provided by (lang elisp
+interface):
+
+    (use-modules (lang elisp interface))
+
+With this interface, you can evaluate an Elisp expression
+
+    (eval-elisp EXP)
+
+load an Elisp file with no effect on the Scheme world
+
+    (load-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
+
+load an Elisp file, automatically importing top level definitions into
+Scheme
+
+    (use-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
+
+export Scheme objects to Elisp
+
+    (export-to-elisp + - * my-func 'my-var)
+
+and try to bootstrap a complete Emacs environment:
+
+    (load-emacs)
+
+* Status
+
+Please see the STATUS file for the full position.
+
+** Trying to load a complete Emacs environment.
+
+To try this, type `(use-modules (lang elisp interface))' and then
+`(load-emacs)'.  The following output shows how far I get when I try
+this.
+
+guile> (use-modules (lang elisp interface))
+guile> (load-emacs)
+Calling loadup.el to clothe the bare Emacs...
+Loading /usr/share/emacs/20.7/lisp/loadup.el...
+Using load-path ("/usr/share/emacs/20.7/lisp/" "/usr/share/emacs/20.7/lisp/emacs-lisp/")
+Loading /usr/share/emacs/20.7/lisp/byte-run.el...
+Loading /usr/share/emacs/20.7/lisp/byte-run.el...done
+Loading /usr/share/emacs/20.7/lisp/subr.el...
+Loading /usr/share/emacs/20.7/lisp/subr.el...done
+Loading /usr/share/emacs/20.7/lisp/version.el...
+Loading /usr/share/emacs/20.7/lisp/version.el...done
+Loading /usr/share/emacs/20.7/lisp/map-ynp.el...
+Loading /usr/share/emacs/20.7/lisp/map-ynp.el...done
+Loading /usr/share/emacs/20.7/lisp/widget.el...
+Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...
+Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...done
+Loading /usr/share/emacs/20.7/lisp/widget.el...done
+Loading /usr/share/emacs/20.7/lisp/custom.el...
+Loading /usr/share/emacs/20.7/lisp/custom.el...done
+Loading /usr/share/emacs/20.7/lisp/cus-start.el...
+Note, built-in variable `abbrev-all-caps' not bound
+  ... [many other variable not bound messages] ...
+Loading /usr/share/emacs/20.7/lisp/cus-start.el...done
+Loading /usr/share/emacs/20.7/lisp/international/mule.el...
+<unnamed port>: In procedure make-char-table in expression (@fop make-char-table (# #)):
+<unnamed port>: Symbol's function definition is void
+ABORT: (misc-error)
+
+Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
+guile> 
+
+That's 3279 lines ("wc -l") of Elisp code already, which isn't bad!
+
+I think that progress beyond this point basically means implementing
+multilingual and multibyte strings properly for Guile.  Which is a
+_lot_ of work and requires IMO a very clear plan for Guile's role with
+respect to Emacs.
+
+* Design
+
+When thinking about how to implement an Elisp translator for Guile, it
+is important to realize that the great power of Emacs does not arise
+from Elisp (seen as a language in syntactic terms) alone, but from the
+combination of this language with the collection of primitives
+provided by the Emacs C source code.  Therefore, to be of practical
+use, an Elisp translator needs to be more than just a transformer that
+translates sexps to Scheme expressions.
+
+The finished translator should consist of several parts...
+
+** Syntax transformation
+
+Although syntax transformation isn't all we need, we do still need it!
+
+This part is implemented by the (lang elisp transform) module; it is
+close to complete and seems to work pretty reliably.
+
+Note that transformed expressions use the `@fop' and `@bind' macros
+provided by...
+
+** C support for transformed expressions
+
+For performance and historical reasons (and perhaps necessity - I
+haven't thought about it enough yet), some of the transformation
+support is written in C.
+
+*** @fop
+
+The `@fop' macro is used to dispatch Elisp applications.  Its first
+argument is a symbol, and this symbol's function slot is examined to
+find a procedure or macro to apply to the remaining arguments.  `@fop'
+also handles aliasing (`defalias'): in this case the function slot
+contains another symbol.
+
+Once `@fop' has found the appropriate procedure or macro to apply, it
+returns an application expression in which that procedure or macro
+replaces the `@fop' and the original symbol.  Hence no Elisp-specific
+evaluator support is required to perform the application.
+
+*** @bind
+
+Currently, Elisp variables are the same as Scheme variables, so
+variable references are effectively untransformed.
+
+The `@bind' macro does Elisp-style dynamic variable binding.
+Basically, it locates the named top level variables, `set!'s them to
+new values, evaluates its body, and then uses `set!' again to restore
+the original values.
+
+Because of the body evaluation, `@bind' requires evaluator support.
+In fact, the `@bind' macro code does little more than replace itself
+with the memoized SCM_IM_BIND.  Most of the work is done by the
+evaluator when it hits SCM_IM_BIND.
+
+One theoretical problem with `@bind' is that any local Scheme variable
+in the same scope and with the same name as an Elisp variable will
+shadow the Elisp variable.  But in practice it's difficult to set up
+such a situation; an exception is the translator code itself, so there
+we mangle the relevant Scheme variable names a bit to avoid the
+problem.
+
+Other possible problems with this approach are that it might not be
+possible to implement buffer local variables properly, and that
+`@bind' might become too inefficient when we implement full support
+for undefining Scheme variables.  So we might in future have to
+transform Elisp variable references after all.
+
+*** Truth value stuff
+
+Following extensive discussions on the Guile mailing list between
+September 2001 and January 2002, we decided to go with Jim Blandy's
+proposal.  See devel/translation/lisp-and-scheme.text for details.
+
+- The Elisp nil value is a new immediate SCM_MAKIFLAG, eq?-distinct
+from both #f and '() (and of course any other Scheme value).  It can
+be accessed via the (guile) binding `%nil', and prints as `#nil'.
+
+- All Elisp primitives treat #nil, #f and '() as identical.
+
+- Scheme truth-testing primitives have been modified so that they
+treat #nil the same as #f.
+
+- Scheme list-manipulating primitives have been modified so that they
+treat #nil the same as '().
+
+- The Elisp t value is the same as #t.
+
+** Emacs editing primitives
+
+Buffers, keymaps, text properties, windows, frames etc. etc.
+
+Basically, everything that is implemented as a primitive in the Emacs
+C code needs to be implemented either in Scheme or in C for Guile.
+
+The Scheme files in the primitives subdirectory implement some of
+these primitives in Scheme.  Not because that is the right decision,
+but because this is a proof of concept and it's quicker to write badly
+performing code in Scheme.
+
+Ultimately, most of these primitive definitions should really come
+from the Emacs C code itself, translated or preprocessed in a way that
+makes it compile with Guile.  I think this is pretty close to the work
+that Ken Raeburn has been doing on the Emacs codebase.
+
+** Reading and printing support
+
+Elisp is close enough to Scheme that it's convenient to coopt the
+existing Guile reader rather than to write a new one from scratch, but
+there are a few syntactic differences that will require changes in
+reading and printing.  None of the following changes has yet been
+implemented.
+
+- Character syntax is `?a' rather than `#\a'.  (Not done.  More
+  precisely, `?a' in Elisp isn't character syntax but an alternative
+  integer syntax.  Note that we could support most of the `?a' syntax
+  simply by doing 
+
+      (define ?a (char->integer #\a)
+      (define ?b (char->integer #\b)
+
+  and so on.)
+
+- Vector syntax is `[1 2 3]' rather than `#(1 2 3)'.
+
+- When in an Elisp environment, #nil and #t should print as `nil' and
+  `t'.
+
+** The Elisp evaluation module (lang elisp base)
+
+Fundamentally, Guile's module system can't be used to package Elisp
+code in the same way it is used for Scheme code, because Elisp
+function definitions are stored as symbol properties (in the symbol's
+"function slot") and so are global.  On the other hand, it is useful
+(necessary?) to associate some particular module with Elisp evaluation
+because
+
+- Elisp variables are currently implemented as Scheme variables and so
+  need to live in some module
+
+- a syntax transformer is a property of a module.
+
+Therefore we have the (lang elisp base) module, which acts as the
+repository for all Elisp variables and the site of all Elisp
+evaluation.
+
+The initial environment provided by this module is intended to be a
+non-Emacs-dependent subset of Elisp.  To get the idea, imagine someone
+who wants to write an extension function for, say Gnucash, and simply
+prefers to write in Elisp rather than in Scheme.  He/she therefore
+doesn't buffers, keymaps and so on, just the basic language syntax and
+core data functions like +, *, concat, length etc., plus specific
+functions made available by Gnucash.
+
+(lang elisp base) achieves this by
+
+- importing Scheme definitions for some Emacs primitives from the
+  files in the primitives subdirectory
+
+- then switching into Elisp syntax.
+
+After this point, `(eval XXX (resolve-module '(lang elisp base)))'
+will evaluate XXX as an Elisp expression in the (lang elisp base)
+module.  (`eval-elisp' in (lang elisp interface) is a more convenient
+wrapper for this.)
+
+** Full Emacs environment
+
+The difference between the initial (lang elisp base) environment and a
+fully loaded Emacs equivalent is
+
+- more primitives: buffers, char-tables and many others
+
+- the bootstrap Elisp code that an undumped Emacs loads during
+  installation by calling `(load "loadup.el")'.
+
+We don't have all the missing primitives, but we can already get
+through some of loadup.el.  The Elisp function `load-emacs' (defined
+in (lang elisp base) initiates the loading of loadup.el; (lang elisp
+interface) exports `load-emacs' to Scheme.
+
+`load-emacs' loads so much Elisp code that it's an excellent way to
+test the translator.  In current practice, it runs for a while and
+then fails when it gets to an undefined primitive or a bug in the
+translator.  Eventually, it should go all the way.  (And then we can
+worry about adding unexec support to Guile!)  For the output that
+currently results from calling `(load-emacs)', see above in the Status
+section.
+
+* Resources
+
+** Ken Raeburn's Guile Emacs page
+
+http://www.mit.edu/~raeburn/guilemacs/
+
+** Keisuke Nishida's Gemacs project
+
+http://gemacs.sourceforge.net
+
+** Jim Blandy's nil/#f/() notes
+
+http://sanpietro.red-bean.com/guile/guile/old/3114.html
+
+Also now stored as guile-core/devel/translation/lisp-and-scheme.text
+in Guile CVS.
+
+** Mikael Djurfeldt's notes on translation
+
+See file guile-core/devel/translation/langtools.text in Guile CVS.