-
Notifications
You must be signed in to change notification settings - Fork 32
Comparisons
What are the differences between RacketScript and Whalesong?
(Asked on Racket Discourse, answer replicated here)
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 thenode
webpack
command --- sonode
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.