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