The Why of ClojureScript
The How of ClojureScript
ClojureScript code can use Clojure macros. Macros are a compile time feature; if ClojureScript code references a macro call, the macro expansion is run by the ClojureScript compiler, ie. in Clojure.
While the ClojureScript compiler currently only runs on Clojure, ClojureScript does ship with the Clojure Reader. As a reminder: the Reader is basically Clojure's parser; it turns a textual representation of a Clojure program into Clojure data structures, which can then be evaluated. ClojureScript comes with a Reader that can parse data in Clojure(Script) notation and hand it to the ClojureScript code as data. ClojureScript's reader only parses, but, since there's no ClojureScript compiler available at runtime, doesn't evaluate.
Closure is used for a few purposes: one of them is library and dependency management, ie. to require libraries and export symbols. ClojureScript namespace definitions map to Google Closure
require calls. ClojureScript can thus easily use the Google Closure libraries that come with a rich set of GUI components and other features.
ClojureScript may be very close to the Clojure language, but its standard library will be a subset of Clojure's. Currently ClojureScript comes with
clojure.string, clojure.set, clojure.walk, clojure.zip etc,and more libraries will be moved over. The difficulty of porting a Clojure library to ClojureScript depends on the nature of the code; purely algorithmic code that uses basic language elements to transform data will be trivial or easy to port. A library that relies on I/O libraries, threading, specific Java libraries etc will obviously require more effort to port; the extra work to factor out platform specific code will pay off.
Brian xperiments with an embedded DSL-style solution; ClojureScript, being a LISP with macros, lends itself well to this. The example handles a sequence of expressions and compiles them to nested callbacks, each will execute one expression in the sequence and then schedule the execution of the rest of the sequence using
setTimeout. This is reminiscent of the programmable semicolon approach in language support for Monads (ie. Haskell's
do notation) or F#'s Compuational Expressions (eg. Async Workflows). The next step would be to support more structured programming concepts like loops, ie. translate them to this continuation passing style using macros.
A blog entry by Justin Grant shows how to implement an algorithm and draw graphics using Google Closure's Canvas support.
ClojureScript is available on GitHub. For more information see the ClojureScript announcement on the clojure.com, or the ClojureScript Wiki at GitHub which contains tons of information, including the Rationale for ClojureScript, a QuickStart Guide and much more. The Clojure mailing list is also a good source for tips about working with ClojureScript as the community discusses the development workflow, tools and more.
This is simply great stuff