npmでおてがるcljs REPL: Lumoの紹介

[Clojure Advent Calendar 2016](http://qiita.com/advent-calendar/2016/clojure)の7日目の記事になります。

# ClojureScriptとREPL
現在はNode.jsも考慮されてますが、もともとClojureScriptはブラウザ上のJavaScriptを対象にしていたので、ブラウザREPLの開発が進みました。
(figwheelでも[node向け](https://github.com/bhauman/lein-figwheel/wiki/Node.js-development-with-figwheel)の解説はありました）

この記事では、コンソールで動くREPLの話題を扱います。

実践記事ではなく紹介のみですので、興味があれば公式サイトを開いていじってみましょう。

## lumo
[lumo](https://github.com/anmonteiro/lumo)は、macOS, Linux, Windowsで動くコンソールREPLです。

バイナリパッケージをダウンロードしてくるか、node(.js)が入ってnpmにパスが通っている環境でnpmでインストールします。
macOSではHomebrewでもインストールできます。

ここでは、npmからインストールしてみます。

```bash
$ npm -g install lumo-cljs

$ lumo
$ lumo -h
Lumo 1.0.0
Usage:  lumo [init-opt*] [main-opt] [arg*]

  With no options or args, runs an interactive Read-Eval-Print Loop

  init options:
    -i, --init path              Load a file or resource
    -e, --eval string            Evaluate expressions in string; print
                                 non-nil values
    -c cp, --classpath cp        Use colon-delimited cp for source
                                 directories and JARs
    -K, --auto-cache             Create and use .planck_cache dir for cache
    -k, --cache path             If dir exists at path, use it for cache
    -q, --quiet                  Quiet mode; doesn't print the banner
    -v, --verbose                Emit verbose diagnostic output
    -d, --dumb-terminal          Disable line editing / VT100 terminal
                                 control
    -s, --static-fns             Generate static dispatch function calls
    -n addr, --socket-repl addr  Enable a socket REPL where x is port or IP:port

  main options:
    -m ns-name, --main=ns-name   Call the -main function from a namespace
                                 with args
    -r, --repl                   Run a repl
    path                         Run a script from a file or resource
    -h, -?, --help               Print this help message and exit
    -l, --legal                  Show legal info (licenses and copyrights)

  The init options may be repeated and mixed freely, but must appear before
  any main option.

  Paths may be absolute or relative in the filesystem.
```

Windowsのコマンドプロンプトで動かしてみます。

```bash
> echo (+ 1 1) | lumo
Lumo 1.0.0
ClojureScript 1.9.293
 Docs: (doc function-name-here)
 Exit: Control+D or :cljs/quit or exit

cljs.user=> 2
cljs.user=>
```

```bash
>lumo -e "(+ 1 1)"
2

>lumo -e "(println 'hello)"
hello
nil

>lumo -e "(* 4 (Math/atan 1))"
3.141592653589793
```
このようにclojureのREPLと同じような操作ができます。


[リリースノート](https://github.com/anmonteiro/lumo/releases)をみると1.0.0でもある程度機能があるようですが、Windows環境では、オートコンプリートなどは動いてませんでした。

ドキュメントがない状態なので、この先は[cljsのチートシート](http://cljs.info/cheatsheet/)やlumoのソースをみたり、planckの[ユーザーガイド](http://planck-repl.org/guide.html)で使えそうな部分をみて試しましょう。



## planck
[planck](http://planck-repl.org/)は、macOSで動くコンソールREPLです。

バイナリかhomebrewでインストールします。

```bash
$ brew install plank
$ planck
```

2年近く開発がつづいており機能が追加されてます。
続きは、[ユーザーガイド](http://planck-repl.org/guide.html)を試しましょう。

iOSで動く[Replete](https://itunes.apple.com/us/app/replete/id1013465639?mt=8)という実装もあります。今年6月のバージョンでClojureScript 1.9.14 と Specが動きます。

## コンソールREPL登場の経緯
npmのサイトを[キーワードclojurescriptで検索](https://www.npmjs.com/browse/keyword/clojurescript)するとclojurescriptをパッケージングしたものがみつかります。

ClojureScript[自身でコンパイル](https://github.com/swannodette/cljs-bootstrap)できるようになると、cljsでコマンドプロンプトを表示する部分を実装する開発者が増えました。

そのなかで、macのJVMではClojure REPLの立ち上がりが比較的遅いのもあり、スクリプト実行などなども考えて、Mike Fikesさんがcljs用のREPLインターフェイスをObjCで開発しました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">This is for real—dev version of Planck ClojureScript REPL has crossed into the 1/5 second realm :) <a href="http://t.co/AUKLPic3HF">pic.twitter.com/AUKLPic3HF</a></p>&mdash; Mike Fikes (@mfikes) <a href="https://twitter.com/mfikes/status/630157629495615488">2015年8月8日</a></blockquote>

その後、planckやlumoでの実行環境の最適化が進んでいっています。


# ReactNative
## re-natal
cljsでReactNativeプロジェクトをつくれるフレームワークです。

Clojureを使ったAndroid開発と同じように、REPLから直接状態の変更ができます。

[README](https://github.com/drapanjanas/re-natal/blob/master/README.md)のチュートリアルどおりにすすめると環境が構築できます。

必要なパッケージをいれて、下記のコマンドを実行するだけでスケルトンプロジェクトが作成できます。

```bash
$ npm install -g re-natal
$ re-natal init FutureApp
```

REPLからの切り替えは、READMEのチュートリアルにあるREPLの項に登場します。

```clj
(in-ns 'future-app.ios.core)
(dispatch [:set-greeting "Hello Native World!"])
```


## natal
iOS向けのcljs組み込みReactNativeプロジェクト作成フレームワークです。

plankの作者Mike Fikesさんがcljs REPLをJavaScriptCore(AppleのmacOS/iOS用実装)に組み込み[Ambly](https://github.com/omcljs/ambly)というライブラリを公開しました。
その後、ReactNativeにAmblyを組み込み[natal](https://github.com/dmotz/natal)が登場しました。

re-natalより単純なので、こちらのほうが触りやすいかもしれません。

```clj
$ npm install -g natal
$ natal init FutureApp
```

REPLはこんな感じです。

```bash
$ cd future-app
$ rlwrap natal repl
```

```clj
(in-ns 'future-app.core)
(swap! app-state assoc :text "Hello Native World")
```

natalにはAndroid側の実装がなかったのですが、natalベースのre-natalではAndroidでも動くようになりました。


## その他
ブラウザ上で動くIDE [Nightlight](https://sekao.net/nightlight/)やエディタ[paren-soup](https://github.com/oakes/paren-soup)などもあります。

NightlightのInstaREPLで[Clojure koans](http://clojurekoans.com/)などを動かすと面白いと思います。


# おわりに
cljsがcljs自身で動くようになりclojureのソースコードがそのまま動く環境がこのように広がってます。
今後も動く環境が増えていくと思うので楽しみましょう。

raspi1ではclojureだと起動までが分単位なのですが、lumoどのぐらい動くか試してみたいと思います。