That’s the right script for the play

I’ve just finished reading ClojureScript: Up and running by Stuart Sierra and Luke Vanderhart

I’ve been wanting to try ClojureScript for quite some time. Every language seems to be trans-compiling to JavaScript these days – languages like F#, C#, Java and TypeScript, so I was looking forward to trying a language that also allows you to interact with the browser via a live REPL.

The book is an interesting read, and is aimed at people who haven’t really used the Clojure language before. It covers setup of the ClojureScript library, the basics of the Clojure(Script) language including the emphasis on functional data structures and the sequence abstraction, and demonstrates how to write ClojureScript and run the resulting output on the browser. As someone who’s used Clojure in the past, I could have easily got started just be reading blog posts such as the following, though the discussion around getting a REPL working the browser and having all of the information in one place made things much easier. The text of the book discusses working with Clojure without requiring the use of Leiningen, but given past projects I’ve worked on I’d always use this tool to take care of the build.

It’s easy to get a first Clojure project working.

  C:\Users\clive\Desktop\lein>lein new first-cljs
  C:\Users\clive\Desktop\lein\first-cljs>mkdir src-cljs
  C:\Users\clive\Desktop\lein\first-cljs\src-cljs>notepad hello.cljs

And add the following code, which will raise an alert dialog in the browser.
  (ns first-cljs.main)
  (js/alert “Hello”)

We need to edit the project file so that it references the cljs Leiningen plugin,
  C:\Users\clive\Desktop\lein\first-cljs>notepad project.clj
and add some additional parameters which will be passed to the plugin.
  :plugins [[lein-cljsbuild “0.2.7”]]
  :cljsbuild {
             :builds [{
                       :source-path “src-cljs”
                       :compiler {
                                  :output-to “web/js/main.js”
                                  :optimzations :whitespace
                                  :pretty-print true}}]

We can build the resulting code using the Leiningen command line
  C:\Users\clive\Desktop\lein\first-cljs>..\lein cljsbuild once
   Volume in drive C is Acer
   Volume Serial Number is BA57-7470

  09/12/2012  14:19    <DIR>          .
  09/12/2012  14:19    <DIR>          ..
  09/12/2012  14:40           447,225 main.js

               1 File(s)        447,225 bytes
               2 Dir(s)  572,977,061,888 bytes free

I copied the code into an ASP.NET web forms project. In the picture you can see the code that has been generated.


The code is rather large, and we can use the Google Closure compiler tool chain to optimise this just by changing the Optimizations argument in the project definition.
       :optimizations :advanced

Rebuilding with this option leads to a much smaller amount of JavaScript.
   Volume in drive C is Acer
   Volume Serial Number is BA57-7470

   Directory of C:\Users\clive\Desktop\lein\first-cljs\web\js

  09/12/2012  14:19    <DIR>          .
  09/12/2012  14:19    <DIR>          ..
  09/12/2012  14:47            69,273 main.js
                 1 File(s)         69,273 bytes
                 2 Dir(s)  572,975,824,896 bytes free

The Clojure compiler has applied a lot of sophisticated optimisations, though they do require that the JavaScript matches certain patterns (which the code from the Cljs compiler does). We can see that the names of the internal functions have been compressed and unused functions have been shaken away.


The real aim is to be able to test and debug the generated JavaScript inside a REPL that runs inside the browser.

To get the Clojure side of the REPL we need to add a dependency on 
  [org.clojure/clojurescript “0.0-1450”]
to the Clojure project definition.

To start the other end of the REPL inside the browser, we need to make the following call.
  (ns first-cljs.main
      (:require [clojure.browser.repl :as repl]))
  (repl/connect “http://localhost:9000/repl”)

We’ll also modify the hosting web page to have a div that we can access by Id (called “TextArea”)


Running the REPL inside a Clojure session, connects us to the browser.
  C:\Users\clive\Desktop\lein\first-cljs>..\lein repl
  user=> (require ‘cljs.repl)
  user=> (require ‘cljs.repl.browser)
  user=> (cljs.repl/repl (cljs.repl.browser/repl-env))

We can now interact with hosted page, for example, grabbing the div and changing its contents.
  ClojureScript:cljs.user>   #_=> (def ta (.getElementById js/document “TextArea”))
  ClojureScript:cljs.user>   #_=> (set! (. ta -innerHTML) “Hello”)

All considered, ClojureScript looks like a fairly good way to write and debug powerful web applications. I’ve always wondered about the problems of debugging trans-compiled JavaScript applications. Features like source maps allow you to get source level debugging for the instruction position, but I’ve not seen coercion of data types back into a representation that is meaningful in the original source language when the data is viewed via a window based debugger. In ClojureScript you debug via the REPL, and get a much more faithful textual representation of the original data value. I’d very much like to try it on a large example to find out.

This entry was posted in Books, Computers and Internet. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s