[gambit-list] Meroon macros

Bradley Lucier lucier at math.purdue.edu
Wed Mar 3 14:24:26 EST 2010


On Wed, 2010-03-03 at 11:40 -0500, James Long wrote:

> So that's my task.  Can you help me by pointing me in the right
> direction?  I grep'ed Meroon's source for all its macro defines and it
> looks like it's all in "meroon.gsc" and "macros.scm".  However, it
> looks like Meroon calls certain functions at expansion time, so I need
> to make sure things are defined in the right phase (expansion,
> runtime, or both?).
> 
> Why does your build script load "pre_meroon.scm" first before it can
> compile Merooon?  Is Meroon written in Meroon?  That makes it
> difficult, as I would have to fix up pre_meroon into a BH module as
> well, because I can never use BH's macro system and Gambit's at the
> same time (BH will throw "Invalid syntax" when trying to parse an
> expression that is a macro but it doesn't know it is).
> 
> I've already tried getting it to work, and I had trouble grokking
> which functions needed to be available in which phase.

James:

I'm really impressed with the progress you've made with Meroon in such a
short time.

Let me explain my understanding of how Meroon is built.  Even though I
have not been able to complete a dependency graph, I believe I
understand how it works.  To my mind, it is rational, it may not be
pretty ;-).

Yes, Meroon is built in Meroon.  Preliminary classes are built by hand
using low-level constructors, and then the high levels of Meroon are
built on top of that.

If you want to run with an interpreted Meroon, to debug the Meroon
sources, say, you can just run the make_meroon script to build
_meroon.scm and say:

heine:~/Desktop/MeroonV3-2008Mar01> gsi
Gambit v4.6.0

> (load "old-load")
"/home/lucier/Desktop/MeroonV3-2008Mar01/old-load.scm"
> (old-load "_meroon.scm")
[ Meroon V3 Paques2001+1 $Revision: 1.2 $ ]
> 

So now Meroon is available to you, and everything is being run
interpreted.  pre_meroon.scm isn't needed.

This will not work with Gambit's load procedure, you need to use the
old-load procedure, as defined in old-load.scm, which simulates a repl,
it reads each form in _meroon.scm in order and executes it, whether that
form defines a macro, a function, etc.  When using old-load, gambit
first expands each form using any macros that have been defined
previously, which can use any functions that have been defined
previously.  So this is a layered build system, with very thin
layers ;-).

Gambit's load procedure won't work to load _meroon.scm all at once,
because when Gambit loads a file it first reads all the forms in the
file, evaluates the macro definitions in the file (which may use any
functions defined in previous files, not functions from the current
file), expands the rest of the source using all now-existing macros and
functions, and then loads all the non-macro forms in the file.

So one could determine which forms in _meroon.scm depend on which macros
and on which functions, and group them in files like:

F0: functions that don't depend on any macros
M0: Macros that use only the functions in F0 (and standard functions) to expand forms
F1: functions that can be expanded by the macros in M0 (and standard macros)
M1: Macros that use the functions in F0 and F1 and the macros in M0 to expand forms
etc.

and then you could load F0, M0, F1, M1, F2, M2, ... in order.

So then the question is: What is the role of pre_meroon?

I asked Christian to make a number of changes to Meroon, which he did in
a way that made minimal changes to the Meroon sources---he added a file
postset.scm. This file defines a new base class, Inlinable-Class, that
generates accessors, predicates, and makers in a form that the Gambit
compiler can inline.  It also changes the name of setters from
set-classname-fieldname! (in the style of set-car!) to
classname-fieldname-set! (in the style of vector-set!).  The default
base class is then set to Inlinable-Class.

Very cool.  Demonstrates the meta-object protocol of Meroon.  But all
the previous code defining Meroon uses setters with names in the style
set-classname-fieldname! (and the previously default Class), so once you
load postset.scm, the Meroon you've just built won't recognize the code
that was used to build it.  

So _meroon.scm is pre_meroon.scm with postset.scm appended to it.
pre_meroon.scm (without postset.scm) is loaded form by form; then
_meroon.scm is compiled in one go (with all the macros and functions
defined by pre_meroon.scm used to expand forms in _meroon.scm before
compilation).  Then you can load directly into gsi or gsc the compiled
file _meroon.o1 (which, at the end of it, changes the default class to
Inlinable-class).

If you try to compile _meroon.scm after loading _meroon.scm, you get the
following problem:

heine:~/Desktop/MeroonV3-2008Mar01> gsc
Gambit v4.6.0

> (load "old-load.scm")
"/home/lucier/Desktop/MeroonV3-2008Mar01/old-load.scm"
> (old-load "_meroon.scm")
[ Meroon V3 Paques2001+1 $Revision: 1.2 $ ]
> (compile-file "_meroon.scm")
"/home/lucier/Desktop/MeroonV3-2008Mar01/_meroon.o2"
> 
*** EOF again to exit
heine:~/Desktop/MeroonV3-2008Mar01> gsc
Gambit v4.6.0

> (load "_meroon")
[ Meroon V3 Paques2001+1 $Revision: 1.2 $ ]

******************* Meroon Domain *********************
Occurred in: allocator
Reason: Inappropriate class
Hint[0]: #<Class: Class>
Hint[1]: #!unbound2
*** ERROR IN Mono-Field-create-careful-reader -- Meroon "Error"
1> 

So, Meroon is built in a layered system, and this system could be made
more explicit.  There is no confusion (in my mind) about
phases---whenever a form is initially loaded, it is expanded using any
previously defined macros and functions, then the expanded form is
loaded into the interpreter.  We need this little trick to compile
_meroon.scm,  which includes postset.scm.

Sorry, I don't have more time to make this e-mail shorter.

Brad




More information about the Gambit-list mailing list