1ヶ月間仕事でClojureを書いている今時点でよく使う関数・コマンドまとめ

3月からClojureを仕事で書いていまして、その中で開発中によく使っているコマンドや、気に入った関数について振り返りながらまとめます。
※書く内容は4月初めに決めたのですが、投稿が遅くなってしまいました。

これからClojureを書き始める、書き始めようかなという人の参考になればいいなと思います。

# Emacsを使った開発のために

## Emacsのインストール

最初は[Emacs For Mac OS X](https://emacsformacosx.com/ "emacsmac")を使って開発をしていたのですが、REPLと繋いでいる場合に落ちることがままありました。
そこで[Emacs Mac Port](https://github.com/railwaycat/homebrew-emacsmacport "emacsmacport")を教えていただいて、乗り換えたところほぼ落ちることはなくなりました。快適です。
MacでEmacsを使う方はこちらをおすすめします。

## Emacsの設定

基本的には@ayato_p さんが書いた、[新: Emacs を使うモダンな Clojure 開発環境](http://qiita.com/ayato_p/items/8bac8229cf8de93df887 "emacs config")を参考にすればイケてる開発環境になると思います。

## cider-mode.el

ciderのバージョンは0.12.0です。

- cider-jack-in (C-c M-j)
REPLに接続します。日々ここから作業スタートです。

- cider-eval-defun-at-point (C-c C-c)
現在カーソルのあるフォームを評価します。
ある程度コードを書いたらほぼ無意識で使ってます。

- cider-load-buffer (C-c C-k)
名前空間(ファイル全体)を評価します。

- cider-switch-to-repl-buffer (C-c C-z)
コードとREPLを行き来します。僕は固定した場所にREPLを出しておくのではなく、これを使ってREPLと行き来するのが好きです。ほんとに便利。

- cider-find-var (M-.)
カーソル上のVarにジャンプしてくれます。タグジャンプですね。ただ、ライブラリやClojure.coreの関数にも飛んでいけるので非常に便利です。

- cider-pop-back (M-,)
IDEとかによくある"戻る"です。上のcider-find-varと組み合わせて使うことが多いです。

- cider-eval-defun-at-point (C-u C-M-x)
フォームにブレークポイントを貼ります。実行されるとデバッグモードに入り、`n`でステップ実行します。
とても便利なのですが、たまにうまくデバッグモードに入らないときがあるのが困ったところ。

- cider-repl-clear-output (C-u C-c C-o)
REPLをクリアします。ターミナルの`Ctrl-l`と一緒ですね。

- cider-pretty-print (C-u C-c C-p)
評価した結果をデータ構造が見やすいように表示してくれます。戻り値が意図したとおりのデータ構造になっているか確認するのに便利です。

- cider-undef (C-c C-u)
評価したフォームをundefします。色々書いてておかしいシンボルかぶったかな？と思った時に。
正直使用頻度は低いです。

- cider-doc (C-c C-d C-d)
ドキュメントを参照します。僕はこれよりも[ClojureDocs]("http://clojuredocs.org/")で見ることのほうが多いのであまり使ってません。

- cider-javadoc (C-c  C-d C-j)
ドキュメントを参照します。cider-docのJava版です。

## clj-refactor.el

clj-refactorのうちよく使っているコマンドを紹介します。バージョンは2.0.0です。
なお、それぞれのコマンド名の右のかっこで書いたキーは、clj-refactorのprefixキーに続けて入力するキーを示しています。

例えば、僕はprefixキーをC-c jに割り当てているので、(ad)だと`C-c j a d`と打つことになります。

- add require (ad)
新しいnamespaceをrequireするときに使います。
下のような状態になるのでTabで移動しながら入力します。

```clj
;;; before
(ns post.core
  (:require [plumbing.core :as pl]))

;;; after
(ns post.core
  (:require [plumbing.core :as pl]
            [ :as ]))
```

- clean namespace (cn)
名前空間の最初のns formにソートをかけ、使われていないものは削除してくれます。

- wrap in thred first (tf)
入れ子関数呼び出しになっている箇所をthread first macroに変えてくれます。

```clj
;;; before
(sql/from (sql/select :*) :hoge)

;;; after
(-> :*
    sql/select
    (sql/from :hoge))
```

- wrap in thread last (tl)

入れ子関数呼び出しになっている箇所をthread last macroに変えてくれます。

```clj
;;; 初期状態
(map #(* % 2) (filter even? (range 1 10)))

;;; コマンド実行後
(->> 10
     (range 1)
     (filter even?)
     (map #(* % 2)))
```

- unwind thread (uw)

threading macroを1段階解除してくれます。
例えば、上の`wrap in thread first`や`wrap in thread last`の実行例では実行後に最初の値が飛び出していてあまり美しくありません。そこでこれを使い、以下のように修正します。

```clj
;;; before
(->> 10
     (range 1)
     (filter even?)
     (map #(* % 2)))

;;; after
(->> (range 1 10)
     (filter even?)
     (map #(* % 2)))
```


- destructure keys (dk)

いちいちkeyを指定して取得するコードを書いてしまった時に、それらをdestructuringを使ったコードに直してくれます。

```clj
;;; before
(let [m {:hoge "ugeee" :fuga "ogeee"}]
  (str (:hoge m) (:fuga m)))

;;; after
(let [{:keys [hoge fuga]} {:hoge "ugeee" :fuga "ogeee"}]
  (str hoge fuga))
```

## paredit.el

pareditはClojureに限らず、Lisp系言語を使うときには必須となるかっこのバランスを維持してくれる拡張です。
これについてはすでに、次の素晴らしい記事があります。この記事内で解説されている機能は全て日常的に使うものばかりです。

[ParEdit チュートリアル](http://www.daregada.sakuraweb.com/paredit_tutorial_ja.html)

# Clojure

## これは便利だな！と思った関数

### get-in/assoc-in/update-in

これらはいずれもネストしたデータ構造から簡単にデータを取得したり、変更したデータを作ったりするときにとても便利な関数です。

```clj
(def m [{:name "John"
         :profiles {:zip "111-1111"}}
        {:name "Mickel"
         :profiles {:zip "765-4321"}}])

;;; get-in
(get-in m [1 :profiles :zip])
;;=> "765-4321"

;;; assoc-in
(assoc-in m [1 :profiles] {:zip "123-4567"})
;;=> [{:name "John", :profiles {:zip "111-1111"}} {:name "Mickel", :profiles {:zip "123-4567"}}]

;;; update-in
(update-in m [0 :name] clojure.string/upper-case)
;;=> [{:name "JOHN", :profiles {:zip "111-1111"}} {:name "Mickel", :profiles {:zip "765-4321"}}]
```

vectorにもmapにもよしなにアクセスできていて大変素晴らしいですよね。

### juxt

これも初めて知った時感動しました。
juxtについてはすでに以下の良い記事があります。

[filter と remove のふたつの結果を簡単に受け取る方法](http://qiita.com/ayato_p/items/db4d6bd8d453f14e13e2)

### cond->/cond->>

cond->/cond->>を使うとthreading macroのそれぞれの関数適用に条件をつけることができます。

```clj
(let [condition-a true
      condition-b false
      condition-c nil]
  (cond-> "hoge"
    condition-a (str "-fuga")
    condition-b (clojure.string/capitalize)
    condition-c (clojure.string/split #"-")))
;;=> "hoge-fuga"

(let [condition-a true
      condition-b true
      condition-c nil]
  (cond-> "hoge"
    condition-a (str "-fuga")
    condition-b (clojure.string/capitalize)
    condition-c (clojure.string/split #"-")))
;;=> "Hoge-fuga"

(let [condition-a true
      condition-b false
      condition-c true]
  (cond-> "hoge"
    condition-a (str "-fuga")
    condition-b (clojure.string/capitalize)
    condition-c (clojure.string/split #"-")))
;;=> ["hoge" "fuga"]
```

# 開発中に参照している資料

## 書籍

- [Living Clojure](http://www.amazon.co.jp/Living-Clojure-Carin-Meier/dp/1491909048 "Living Clojure")
Clojureの入門書です。この本の素晴らしいところは説明の構成です。前から読んでいけば段階的にわかるように書かれています。今現時点でこれ以上の入門書はないでしょう。

- [Clojure Applied](http://www.amazon.co.jp/Clojure-Applied-Practitioner-Ben-Vandgrift-ebook/dp/B016CJGHFE/ref=sr_1_1?s=english-books&ie=UTF8&qid=1458969611&sr=1-1&keywords=clojure+applied "Clojure Applied")
他の言語でいう、Effectiveシリーズくらいのレベル感の書籍です。文法を超えて実践的にはどうすればいいのかって疑問に答えてくれます。僕もまだ読み途中です。

## Web

- [CIDER Quick-Reference Card](https://github.com/clojure-emacs/cider/blob/master/doc/cider-refcard.pdf)
cider-modeの機能が見やすくまとまってます。

- [Clojure Destructuring Tutorial and Cheat Sheet](https://gist.github.com/john2x/e1dca953548bfdfb9844)
destructuringについてわかりやすく解説してくれているページです。よくお世話になっています。