先日、Opt Technologiesの社内勉強会で Practical REPL-driven Development with Clojure と題してClojureとREPL駆動開発の入門的な発表をしたので、その内容を簡単にご紹介します。
1. Clojure Quick Intro
極めて簡潔なClojure入門
Clojureとは
Clojureのリテラル(+α)
Clojureのシンタックス
2. Leiningen
ビルドツールLeiningenの使い方
基本的な lein
タスク
lein repl
: REPLを起動
lein new <template name> <project name>
: テンプレートを指定してプロジェクト生成
例えば
$ lein new app clj-demo
lein run
: -main
関数を実行
lein test
: テストを実行
lein uberjar
: jarファイルを作成
3. Clojure REPL
Clojure REPLの使い方
REPLで利用可能な主なユーティリティ
doc: ドキュメントを出力
source: ソースコードを出力
*1, *2, *3: 直前の評価結果を保持する変数
*e: 直前の例外を保持する変数 (cf. pst)
検索系
4. Lisp Editing
Lisp編集のためのエディタプラグインの使い方
Parinfer
Indent mode ではインデント編集時に括弧を、 Paren modeでは括弧編集時にインデントを自動調整するプラグイン
AtomにParinferを設定した環境での操作例(抜粋)
↑では、改行後に書き始めるインデント位置によって自動的に閉じ括弧の位置が調整されている(Indent mode)。
ParEdit
特殊なキーバインドを利用して括弧とインデントを半自動的に調整するプラグイン
SpacemacsにParEditを設定した環境での操作例(抜粋)
↑では、 M-(
(メタキーと (
の同時入力)という特殊なキーバインドで直後の式を丸括弧で囲んでいる。
5. REPL-driven Development in practice
Clojure Koansと4ClojureというClojureチュートリアルを題材に、REPL駆動開発してみる
コースA: Clojure Koans
禅の公案問答のごとく(?)ひたすら穴埋め問題に取り組みながらClojureの基礎が学べるチュートリアル
1. リポジトリをcloneする
$ git clone git://github.com/functional-koans/clojure-koans.git
2. koan(公案)プログラムを実行する
$ cd clojure-koans/
$ lein koan run
実行すると、アサーションに失敗する。
3. ソースファイルをエディタで開く
例えば
$ emacs src/koans/01_equalities.clj
4. Clojure REPLを起動する
Spacemacs/Emacs + CIDERプラグインなら cider-jack-in
コマンド(, '
, M-RET '
or C-c M-j
)
5. ソース上の式を評価しながら穴埋め問題を解いてアサーションを通るようにする
ソースバッファ上でインライン評価
Spacemacs/Emacsなら cider-eval-last-sexp
コマンド(, e e
, M-RET e e
, C-x C-e
or C-c C-e
)など
ソースバッファからREPLバッファに送って評価
Spacemacsなら cider-send-last-sexp-to-repl
コマンド(, s e
, M-RET s e
)など
6. 変更を保存してmeditation(瞑想/坐禅)の結果を確認する
コースB: 4Clojure
Clojureの基礎は習得済みのプログラマ向けの問題集
1. エディタでClojureのバッファを開く
例えば
$ emacs clj-demo/src/clj_demo/4clojure/problem22.clj
2. Clojure REPLを起動する
Spacemacs/Emacs + CIDERプラグインなら cider-jack-in
コマンド(, '
, M-RET '
or C-c M-j
)
3. 例としてProblem #22に取り組んでみる
シーケンスの要素数を返す関数を書く問題(標準関数 count
は使わない)。
4. 関数を書いてみる
5. 書いた関数の動作確認をする
ソースバッファ上でインライン評価
Spacemacs/Emacsなら cider-eval-last-sexp
コマンド(, e e
, M-RET e e
, C-x C-e
or C-c C-e
)など
ソースバッファからREPLバッファに送って評価
Spacemacsなら cider-send-last-sexp-to-repl
コマンド(, s e
, M-RET s e
)など
6. 問題ページに解答を貼り付けて実行してみる
問題ページで実行可能な形式にするには、以下のように元の関数定義の defn
を fn
に置き換えると良い。
(fn my-count [coll]
(reduce (fn [n _] (inc n))
0
coll))
Further Reading
エディタプラグイン/設定
- Clojure/ClojureScript関連リンク集 > Clojure開発全般
- Clojure開発環境での基本操作まとめ: Spacemacs, IntelliJ IDEA (Cursive), VS Code (Calva), Vim (vim-iced), rebel-readline
- Clojureで快適なREPL駆動開発のために"reloaded workflow"を実践しよう