Clojure記事紹介<百日修行>(5):「よりわかりやすいClojureを書く」
Clojure記事紹介<百日修行>では、英文で書かれたClojureの記事を要約してひたすら紹介していきます。モットーは「質より量」です。
紹介記事
他の言語と同様、Clojureにおいても、気づいたらわかりにくいプログラムを書いてしまうことはよくあります。特に、REPL上で試行錯誤しながら少しずつ書き進めたコードだと、そうなりがちです。そこでこの記事では、とあるClojureのコードを取りあげ、それをリファクタリングする過程を通して、わかりやすいClojureコードを書くコツが紹介されています。
例題となるコード
この記事で取りあげられているコードは、redditのClojureスレから持ってきたそうです。
(defn markov-data [text] (let [maps (for [line (clojure.string/split text #"\.") m (let [l (str line ".") words (cons :start (clojure.string/split l #"\s+"))] (for [p (partition 2 1 (remove #(= "" %) words))] {(first p) [(second p)]}))] m)] (apply merge-with concat maps))) (defn sentence [data] (loop [ws (data :start) acc []] (let [w (rand-nth ws) nws (data w) nacc (concat acc [w])] (if (= \. (last w)) (clojure.string/join " " nacc) (recur nws nacc)))))
コードの意味については、原文で軽く触れられているので参照してください。
リファクタリング
ここでは、記事で紹介されているテクニックを要約して紹介し、リファクタリング後のコードを紹介するにとどめるので、途中経過が見たい方は元記事を参照して下さい。
紹介されているテクニックは以下の通りです。
- 変数には長くてもわかりやすい名前を付ける
- 意味のまとまりがある部分を切り出して関数にする
- 深い
let
ネストをthreading macro->
で書き換える loop
構文で値をaccumulateしていくようなコードは、reduce
を使えないか検討するfirst
、second
等でシーケンスを切り出すときは、restructuringを活用する
結果
このようにしてリファクタリングされたコードが以下です。
(defn sentence->wordlist [sentence] (-> sentence (str ".") (clojure.string/split #"\s+") (->> (cons :start) (remove #(= "" %))))) (defn make-markov-mapping [sentence] (let [wordlist (sentence->wordlist sentence)] (for [[word & words] (partition 2 1 wordlist)] {word words}))) (defn markov-data [text] (->> (clojure.string/split text #"\.") (mapcat make-markov-mapping) (apply merge-with concat))) (defn pick-next-word [mapping this-word] (let [choices (get mapping this-word)] (rand-nth choices))) (defn sentence [mapping] (loop [words [] this-word :start] (let [next-word (pick-next-word mapping this-word) words (conj words next-word)] (if (= (last next-word) \.) (clojure.string/join " " words) (recur words next-word)))))
行数は長くなっていますが、関数名や変数名にわかりやすい名前が割り当てられ、ここの関数は短いので、理解しやすいコードになっています。
繰り返しですが詳しい説明や途中経過は記事を参照してください。
Clojure Applied: From Practice to Practitioner
- 作者: Ben Vandgrift,Alex Miller
- 出版社/メーカー: Pragmatic Bookshelf
- 発売日: 2015/10/07
- メディア: Kindle版
- この商品を含むブログを見る
- 作者: Stuart Halloway and Aaron Bedra,川合史朗
- 出版社/メーカー: オーム社
- 発売日: 2013/04/26
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (10件) を見る