Racket to Javascript compiler

What are the difference between:

Are both active? Which one has more features?

Is it possible to compile a rkt file to a js file that has no dependencies?

2 Likes

lastest commit of them

  • Racketscript: 27 days ago
  • Whalesong: 30 Oct 2014, fork is 14 May 2017

You would more likely want to use Racketscript, but I already don't remember Racketscript's compiled JS file has dependency or not.

2 Likes

Whalesong is stuck on version 6.2 of Racket.

Here is an explanation from one of the issues:

I recommend looking at RacketScript.

5 Likes

Hi, The descriptions below are to the best of my knowledge. Please correct any misunderstandings.

Whalesong is a semantics-preserving implementation of Racket. Thus, features like tail calls, continuations, and the numeric tower all behave exactly like Racket.

  • Implementation-wise, Whalesong calls the Racket compiler to first compile to bytecode, and then to JS. To support Racket semantics, the runtime maintains its own stack and uses trampolines to implement tail calls and other control operators, and is thus somewhat "heavyweight".

  • Usage-wise, Whalesong has performance tradeoffs that would be expected from such an approach. Another tradeoff is that existing tools in the JS ecosystem may not work with WhaleSong generated JS since it is not idiomatic. These tradeoffs are acceptable since Whalesong is primarily used for smaller programs in a teaching context, e.g., see wescheme.org.

RacketScript follows in the steps of other "-Script"-style languages, like ClojureScript or ReScript, i.e., it's not Racket.

  • Implementation-wise, RacketScript directly translates (fully expanded) Racket to approximate JavaScript counterparts. For example, Racket functions become JS functions. Same with numbers and most arithmetic. Thus the output is more readable and compatible with the existing JS ecosystem.

    Some effort is made to preserve Racket semantics when it's not too costly, e.g., self recursive tail calls are converted to loops. Other Racket features that dont have direct JS equivalents---e.g., structs, hashes, bytes, strings, values, etc---are supported by a lightweight runtime, which must accompany any compiled file.

    One of the design goals of RacketScript is to keep this runtime size small, which means other features like the full numeric tower or mutual tail calls (which work in Whalesong) are not currently supported. Compiling other features like contracts or reflection are still a work in progress and likely requires active research, so it's possible they may never be supported.

  • Usage-wise, as mentioned, RacketScript compiled Racket requires a runtime but all dependencies can be combined into a single file using the webpack compile target option (which uses the node webpack command --- so node is required to be installed).

    Note that currently, writing webapps with RacketScript remains somewhat tedious (since Racket programs have historically not needed to run in the browser and thus there's a lack of libraries and abstractions) and will likely involve a lot of non-Rackety JS FFI calls.

    On the other hand, Racketscript possibly provides a unique setting and opportunity for exploration of new libraries and DSLs that were not possible in base Racket. There have been some beginning contributions in this regard, e.g., a big bang implementation that compiles to underlying html events, as well as the Rackt wrapper for React, but for sure more are needed and would be very welcome.

6 Likes

How hard is to make Whalesong use the fully expanded version of the program instead of the BC-bytecode? IIRC they were quite similar. The problem is that it would be even slower becasue the BC-bytecode has already many optimizations (like constant propagation and folding), and the trampoline will confuse the JS compiler and destroy any hope of inlining or loop unroling, and the BC-bycode has safe for space marks, and ...

How hard is to make a fully expanded program to BC-bytecode compiler? Perhaps schemified code to BC-bytecode? [My guess is that cp0 adds too man subte assumptions about Chez Scheme, that it will be necesary to rewrite a lot of the internal parts of Whalesong.]

I think both are possible, but they require a lot of work.

How hard is to make Whalesong use the fully expanded version of the program instead of the BC-bytecode? IIRC they were quite similar. The problem is that it would be even slower becasue the BC-bytecode has already many optimizations (like constant propagation and folding), and the trampoline will confuse the JS compiler and destroy any hope of inlining or loop unroling, and the BC-bycode has safe for space marks, and ...

It's definitely possible - and it would fix the current problem (that Whalesong is dependent on the bytecodes used in the BC compiler). The current compiler is written in C [1].
The nice thing about this approach is, that the exising Whalesong runtime can be reused.
However, as you point out, there will be no synergy between such a compiler and the one in Racket CS.

The new compiler in Racket CS produces linklets as an intermediary step towards outputing Chez Scheme code. I think, it would be to look at compiling linklets to JavaScript.

I think both are possible, but they require a lot of work.
I agree.

[1] https://github.com/racket/racket/blob/master/racket/src/bc/src/compile.c

1 Like