Nazdar světe! říká ClojureScript

Tak jsem se neudržel a ClojureScript si vyzkoušel. Následuje popis (jednoho zápasu), jak si vyrobit Hello, world! v ClojureScriptu. Vzhledem k tomu, že ClojureScript je zatím v alpha verzi a Windows (kde jsem to musel z časových důvodů vyzkoušet) tradičně hází vývojářům klacky pod nohy :-/ se instalace, kompilace a vyzkoušení triviálního příkladu protáhlo na několik hodin. Nicméně zvítězil jsem a tady je výsledek.

Nebudu se zabývat instalací ClojureScriptu — je dobře popsána ve wiki projektu, Windows instalace je trochu dramatičtější. Navíc v případě Windows je problém, pokud se kompilace provádí v cestě s mezerami (Documents and Settings apod.), je při optimalizovaném překladu vyhozena výjimka.

Tak, máme nainstalováno? Spustíme z příkazové řádky příkaz cljsc (ClojureScript compiler):

C:\clojure-clojurescript\samples\my-hello>cljsc
Usage: "cljsc <file-or-dir> > out.js"
       "cljsc <file-or-dir> {:optimiztions :advanced} > out.js"

No. Co/k čemu ten ClojureScript vlastně je? ClojureScript je dialekt Clojure (spíš podmnožina). Nejdůležitější je jeho kompilátor, který umožňuje zkompilovat Clojure(Script) do JavaScriptu. Pokud by někoho zajímaly filozofické důvody pro vznik ClojureScriptu, jsou uvedeny ve wiki na stránce Rationale (odůvodnění). V podstatě jde asi o to, dostat Clojure i na jinou platformu než JVM, v tomto případě JavaScript VM.

ClojureScript kompilátor generuje JavaScript, který (záměrně) odpovídá konvenci JavaScriptové knihovny Google Closure. Důvod je zřejmý — (Google) Closure Compiler. Tím se vysvětlují dva způsoby použití kompilátoru cljsc:

  • cljsc <file-or-dir> > out.js spustí pouze ClojureScript kompilátor a výsledný soubor “slinkuje” s knihovnou Closure Library.
  • cljsc <file-or-dir> {:optimiztions :advanced} > out.js dělá totéž, plus ještě následně prožene výsledný kód Closure Compilerem, který kód zoptimalizuje a vytvoří jeden kompaktní soubor.

Takže, pojďme se podívat na ten příklad. Vytvořím soubor hello.cljs. Metadata ^:export u definice funkce říkají, aby název výsledné funkce nebyl kompilátorem minifikovaný.

(ns hello)

(defn ^:export greet [n]
    (str "Hello, " n "!"))

Následně ho zkompiluju:

cljsc hello.cljs {:optimizations :advanced} > hello.js

A výsledný kód zavolám v prohlížeči:

<html>
<head>
    <title>ClojureScript</title>
    <script src="hello.js" type="text/javascript">
</script>
</head>
<body>
    <script type="text/javascript">
            alert(hello.greet("ClojureScript"));
    </script>
</body>
</html>

A výsledek?

Uf! Byla to dřina. :-|

Když to vezmu prakticky, tak zatím ClojureScript moc použitelný není. Problém jsou hlavně chybějící nástroje. Pokud ale jednou bude zaintegrován například do Leiningenu nebo Mavenu, tak si dokážu představit, že třeba ve spojení s Compojure půjde vytvořit kompletní webovou (klient/server) aplikaci pouze v Clojure. To by bylo komfortní.