Scheme2Js 20060718 review

by on

Scheme2Js is a Scheme to Javascript compiler

License: GPL (GNU General Public License)
File size: 84K
Developer: Florian Loitsch
0 stars award from

Scheme2Js is a Scheme to Javascript compiler. While some effort has been spent on being as close as possible to R5rs, we concentrated mainly on efficiency.

Usually Scheme2Js produces Javascript code, that is comparable to hand-written code. In order to achieve this performance, Scheme2Js is not completely R5rs compliant. In particular it lacks support for continuations, exact numbers and it treats tail recursion only partially.

Scheme2Js provides several flags, that allow to modify the result:
--no-js-dot-notation disallows access to JavaScript fields with the dot-notation. This flag disables accesses of the form x.y like in document.getElementById. It is however still possible to access the is a valid expression using the js-field function.
--mutable-strings: in order to improve the performance of string-operations and to ease the interface between Scheme and JavaScript code, the default implementation maps Scheme strings to JavaScript strings. Contrary to Scheme strings, JavaScript strings are however immutable. This flag maps strings to a JavaScript class, that represents Scheme strings, that are mutable. The resulting code might be slightly slower, and it is more difficult to interface with Javascript code.
--encapsulate-parts encapsulates the program into an anonymous function. Only global variables are outside of this anonymous function. On one hand this introduces one function call to the anonymous function. But on the other hand most Javascript implementations should run faster with this optimization: usually hashtables are used to represent scopes in JavaScript. By using an anonymous function the programs variables are separated into their own smaller hashtable which (in theory) accelerates accesses to these variables. More importantly the variables are stored in their own hashtable, and not in the global hashtable, which is accessible by the global variable. It is extremely easy to indirectly modify the contents of global variables. Inlining or other common optimizations are hence impossible to do on global variables. By storing the program's variables in an anonymous function these optimizations become again possible.
--optimize-var-number reduces the number of variables used in the resulting JavaScript code. The code may run faster, but is more difficult to debug, as the variable names are lost and the same variable might be used several times.
--optimize-while: with this flag Scheme2Js optimizes common while loops. The unoptimized while loops are often of the form:
while(true) {
resVar = res;
else {

This optimization looks for these patterns and moves the test into the while loop:

while(!test) {
resVar = res;

This optimization has been implemented only recently and is therefore not yet activated by default.
--verbose prints some information.
--no-inlining disables all function inlining (constants might still be inlined).
--inline-globals lets Scheme2Js inline global functions and constants. This might have two unwanted side-effects: for one, global variables are often used to transfer data between different modules. Some inlined functions are lost if there is no reference to them anymore. If global functions are to be used outside a module, one should not use this flag. (This behavior is likely to change in future versions of Scheme2Js.)
--unresolved-is-js: if a variable is unbound, the compiler will assume the variable comes from another module, or from JavaScript. See Section Scheme - Javascript for a more detailed discussion of the JavaScript Scheme interface.
--js-this provides the this variable within Scheme functions. This way, Scheme procedures can be used as methods of JavaScript objects.
--no-tailrec disables the tailrec to while-loop optimization. If you suspect a bug in the compiler's way of translating tail-recs, you could try this flag.
--no-optimize-calls disables Scheme2Js inlining of binary or unary operations. For instance sci_plus(3, 5) is optimized to (3+5). This optimization is quite important, and there's usually no reason to disable it.
--no-optimize-consts disables the pre-constant calculation. Unless disabled (with this flag), compound constants are precalculated and their occurrences replaced by a reference to a variable holding the constant. This makes repeated accesses to these constants faster, but introduces new variables.
--no-optimize-boolify disables the boolify optimization. JavaScript's and Scheme's boolify are not equivalent: JavaScript considers false, 0, null and undefined to be false, whereas Scheme only has #f. The unoptimized boolify therefore always adds the test against false: if (test !== false) ... If Scheme2Js can see, that the test itself is a boolean, it can remove the unnecessary !== false test. This flag disables this optimization.
--d STAGE prints a dot-file (see graphviz) of the AST after stage STAGE. Possible stages are: expand, tree, symbol, node-elim1, tail, inline, constant-propagation, rm-unused-vars, capture, node-elim2, while, (tt "statements"), node-elim3. Usually one doesn't need this flag, unless for debugging purposes.
--print-locs prints the original locations as comments to the JavaScript file. These locations are currently the character-offset from the beginning of the file.

What's New in This Release:
This release adds trampolines.

Scheme2Js 20060718 keywords