
- 作者: Stuart Halloway and Aaron Bedra,川合史朗
- 出版社/メーカー: オーム社
- 発売日: 2013/04/26
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (11件) を見る
前回に引き続き Clojure を勉強中。
do
if
の中などで戻り値とは別の式を評価したいときに使う。これは結局、副作用を導入することになる。
(defn is-small? [number] (if (< number 100) "yes" (do (println "Saw a big number" number) "no")))
when
は上記を省略してかける。
loop と recur
loop
と recur
による再帰。recur
により再帰のパフォーマンスを向上できる (末尾最適化を簡易にしたもの)
(loop [result [] x 5] (if (zero? x) result (recur (conj result x) (dec x))))
recur
は loop
の冒頭にジャンプする。 recur
の引数は loop
の引数に渡されて再帰呼び出しされる。
普通に再帰をするより recur
を使って再起したほうが最適化されてメモリーを上手に使える。
関数の中であれば loop
は省略できる。その場合、recur
は関数の冒頭にジャンプする。
(defn countdown [result x] (if (zero? x) result (recur (conj result x) (dec x))))
for
リストの内包表記。Haskell でいう所の [x | x <- [1..10]]
。
これを clojure で書くと (for [x (range 1 10)] x)
になる。
メタデータによる型情報の定義
メタデータで関数の引数と戻り値の型を指定できる。
(defn ^String shout [^String s] (.toUpperCase s)) (shout "abcde") ;=> "ABCDE" (shout 12345) ;=> ClassCastException java.lang.Long cannot be cast to java.lang.String user/shout
この場合、キャストが出来なければエラーになる。逆にいうと暗黙的なキャストはしているということか?
関数のメタデータには、型情報、メソッドのドキュメント、事前・事後条件がかけるので、結構使い勝って良さそう。
シーケンス
何かしらのコレクションのこと。
文字列やディレクトリ構造、I/Oストリームもシーケンスとして扱える。
シーケンスとして扱えることを seq-able (「シーカブル」)という。
Ruby の Enumerable のように同じインタフェースで操作できるメソッドがある。
map
とか reduce
とかが使える。
Javaのコレクションもシーケンスとして扱う。
進捗
10章まであるうち3章まで読んだ。