Skip to content
This repository was archived by the owner on Mar 14, 2021. It is now read-only.

Examples

kriyative edited this page Jul 12, 2011 · 3 revisions

Please note that the output from the following examples are pretty printed Javascript, which is not the default.

To get started:

(use 'clojurejs.js)

For a more detailed (lightly tested) example of using ClojureJS, check out the following gist:

https://gist.github.com/788487

Functions

(js
 (defn test-fn [a]
   (let [b (+ a 1)
         c (+ b 1)]
     (+ a b c))))

translates to the following Javascript:

test_fn = function (a) {
    var 
        b = (a + 1), 
        c = (b + 1);
    return (a + b + c);;
}

Destructuring

Function args and let bindings can be destructured, e.g.:

(js
 (defn test-fn [num-list]
   (let [ [a b] num-list
         c (+ b 1)]
     (+ a b c))))

which translates to:

test_fn = function (num_list) {
    var 
        _temp_1000 = num_list, a = _temp_1000[0], b = _temp_1000[1], 
        c = (b + 1);
    return (a + b + c);;
}

Map destructuring (aka associative destructuring) allows to bind the properties of a JavaScript object to names, including :keys syntax and defaults for missing keys (using :or). For example:

(js
 (defn test-fn [square]
   (let [{:keys [x1 y1 x2 y2]} square
         area (* (- x2 x1) (- y2 y1))]
     (do-stuff area))))

becomes:

test_fn = function (square) {
    var
    _temp_1000 = square,
    x1 = _temp_1000['x1'], x2 = _temp_1000['x2'],
    y1 = _temp_1000['y1'], y2 = _temp_1000['y2'],
    area = ((x2 - x1) * (y2 - y1));
return do_stuff(area);;

When destructuring an array, aliasing the whole array with :as works the same as in Clojure. Destructuring bindings may be nested arbitrarily.

Macros

(js
 (defmacro nil? [x] `(== nil ~x))
 (if (nil? a) (print "is null")))

translates to the following Javascript:

if ((null == a)) { print("is null"); };

loop/recur

(js
 (defn join [arr delim]
   (loop [str (get arr 0)
          i 1]
     (if (< i (length arr))
       (recur (+ str delim (get arr i))
              (+ i 1))
       str))))

translates to the following Javascript:

join = function (arr, delim) {
        for (var str = arr[0], i = 1; true;) {
            if ((i < arr.length)) {
                str = (str + delim + arr[i]);
                i = (i + 1);
                continue;
            } else {
                return str;
            };
            break;
        };
}

try/catch/finally

(js
 (defn test []
   (try
     (/ 5 0)
     (catch ex
         (console.log ex))
     (finally
      0))))

translates to:

test = function() {
    try {
        return (5 / 0);
    } catch (ex) {
        return console.log(ex);
    } finally {
        return 0;
    };
}

Caveats

The defn form doesn't support multiple arity forms or keyword args. Doc-strings are supported and emitted as comments if pretty-printing is turned on.

Currently, there's no support for namespaces. Macro expanders are defined in a global ref, which is preserved between successive invocations of the translator.

There's lots of room for improvements in the generated Javascript, from performance tweaks to better formatting of expressions.

boot.cljs

The file `boot.cljs' includes some useful macros and utility functions implemented in ClojureJS.

(html spec)

The html function in boot.cljs implements a minimal HTML templating facility which is similar to hiccup, but is executed on the browser side.

(jq
 (defn test []
   (.append ($ document.body)
            (html
             [:div {:id "container"}
              [:span {:class "title"} "Lorem ipsum blah blah"]
              [:ul {:id "hmenu"}
               [:li [:a {:class "link_login"} "Login"]]
               [:li [:a {:class "link_signup"} "Signup"]]
               [:li [:a {:class "link_about"} "About"]]
               [:li [:a {:class "link_contact"} "Contact"]]]]))))

Invoking (test) on the browser side would create and add the dom tree specified in the array structure to the document body.

(html-str spec)

The html-str function is similar to the html function, except it returns a HTML string representation of the specified spec. e.g.,

(html-str
 [:ul
  [:li [:a {:href "#"} "link1"]]
  [:li [:a {:href "#"} "link2"]]])

at runtime, would generate:

"<ul><li><a href='#'>link1</a></li><li><a href='#'>link2</a></li></ul>"
Clone this wiki locally