I've made an attempt to port TeXmacs to guile-2 for some time (please see a patch included
in attachment). It's progressed slowly as I've got a fairly little time to work on
that. Here are some issues of building and running TeXmacs with guile-2 that I've
encountered:
* Small C API change in guile-2:
Such as introduction of `scm_t_subr' type in the 5th parameter of scm_c_define_gsubr() . I've added a new detection code in
autoconf script to fix the signature issue.
* Changes in guile:
** Top level definition:
Guile-2 doesn't allow definitions are defined in _expression_ context. In other words,
definitions must be either:
- At the top level of a program, or
- At the beginning of the body of `lambda' and its derived forms such as: `let', `let*',
`letrec' and `letrec*'
The simplest fix is: moving these definitions out of conditional expressions and using
`set!' in the expressions to bind the symbols to the desired `lambda's. For example:
(if foo?
(begin
(define (bar arg) (noop))))
can be rewritten as:
(define bar #f)
(if foo?
(begin
(set! bar (lamda (arg) (noop)))))
** Loading guile module behaves differently in guile-1 and guile-2:
Let say in the top-level of program we import a module:
(use-modules (my-module))
and in my-module.scm we have a hypothetical code:
(do-some-work)
(define-module (my-module))
...
The difference between guile-1 and guile-2 is the question of what modules that guile uses to
lookup the definition of `do-some-work'.
- guile-1: the current module up to the point of (define-module (my-module)) is the
current module of top-level program, i.e.: (guile-user), so if `do-some-work' is defined
in the top-level program, its definition can be found.
- guile-2: it creates a fresh module (i.e. unnamed module) before loading the file so
current module is a fresh module up to the point of (define-module ...)
As a result, the (texmacs-module ...) macro no longer works in guile-2 since this macro is
defined in the top-level of program; only (guile) module is available at that point.
The heart of current TeXmacs module logic are in 3 macros and they are also the most
troublesome to run with guile-2:
- inherit-modules: it re-exports public definitions defined in various modules so that
these definitions are easier to access "globally".
- texmacs-module: besides creating a new module, the macro also lets the current module
access "global" definitions, which have been re-exported by prior inherit-modules
(N.B. whilst it's convenient, I'd prefer to have an explicit control on importing
module)
- tm-define: it provides mechanism to override a macro's definition depending on its
context (i.e. contextual polymorphism).
In guile-1, the process of loading all TeXmacs modules at boot time is illustrated in the attached
figure tm-1.png (or you can use freemind to open the
tm-1.mm file). The icon (1)
indicates current module in these places are mostly (guile-user) module.
To replace the usage of `texmacs-module' with `define-module' macro comes with guile, I've
re-organised the process a little bit (see attached figure tm-2.png or
tm-2.mm):
- I've wrapped all glues into a separate module called (texmacs-glue). In the future, we
might want to sub-divide the glues into several modules (e.g. dynamic libraries) and
only load those needed depending on platform or configuration.
- I've created a new (texmacs-core) module where we will put important "global" macros and
variables such as `inherit-modules', etc. It also re-exports all public glues defined in
(texmacs-glue)
- All modules (including the top-level) will need to use (texmacs-core) module explicitly.
In general, replacing (texmacs-module) with (define-module) is quite straightforward. But
the major problem that I'm having at the moment is to compile the expansion of `tm-define'
macro. Here is steps to quickly see the problem after applying the attached patch:
- Edit init-texmacs.scm & find this line:
(include "kernel/boot/boot.scm")
- Add a following line after the above line and also comment out the rest of the file:
(use-modules (tm-test))
- Here is the minimum content of tm-test.scm:
(define-module (tm-test)
:use-module (texmacs-core))
(use-modules (kernel boot abbrevs)
(kernel boot ahash-table)
(kernel boot debug)
(kernel texmacs tm-define))
(tm-define (foo)
(display* "bar"))
You'd see this error message:
;;; ERROR: build-constant-store: unrecognized object #<procedure nval head>
I've haven't got a chance to look deeper into that. I guess, looking at the output of macroexpand
for (tm-define ...) might give some hint why the compiler chokes there.