Ralph – Future
The last refactoring of Ralph’s compiler began almost two years ago. After starting with great ideas and ambition, my Master’s thesis interrupted the development just a month later. After graduating I got a job which did not leave much time for large side-projects either. In spring I finally spent a few days finishing off some of the important features.
The compiler now properly performs
syntax-quoting
at read-time, rather than compile-time, and handles nesting.
This fix finally allows writing
macro-writing macros,
like
once-only
.
Ralph also gained the
non-local-exit macro block
(called bind-exit
in the old standard). I was always afraid of adding it, knowing that functions containing
a try-catch block would not be optimized in V8. However, it turns out the protected expressions
stay optimized if they are moved into a function outside of the try-catch block,
and the protected expression is an invocation of that lifted method.
The alpha-conversion pass got refactored into CPS, similar to the A-Normal Form pass. This allows for example to prepend code like module loading statements for free variables that are imported.
To make it easier to debug the compiler, I improved the readability of the generated JavaScript by
replacing the naive JavaScript code generator with
one that is emitting
Mozilla’s Parser API AST
and using escodegen. There are now also pretty-printing
facilitie which can assist understanding the output of transformation passes.
After reading Philip Wadler’s
“A prettier printer”, I
implemented a strict variant as described by Christian Lindig in
“Strictly Pretty”.
However, it was rather cumbersome to define printing functions with the desired line wrapping and
indentation behaviour for S-expressions, so I
ported
Marc Feeley’s genwrite.scm
.
It is less generic, but much more suited for Ralph.
Last but not least, Ralph finally has a REPL. The interactor compiles Ralph expressions entered by the user to JavaScript, sends the generated code to an evaluator via the WebSocket protocol, and prints the response. Currently there are evaluators for node.js and browsers.
I always hoped to use Ralph for future projects once it is in a usable state. The compiler and the language are more or less stable, but there are still some features missing that would make developing real-world applications much easier, like better IDE integration and source map support. Given how long the last refactoring took, I think it is time for me to declare Ralph as “done” and move on to new projects. If you have questions, are interested in using it, or even would like to continue its development, please let me know!