lazy-seq の 4 つのルール, 後 next と rest の違いとか
Joy of Clojure P115 にあったのをメモ。
プログラミングClojureにもあったと思うが結構忘れがちなので。
訳は適当。
- 遅延シーケンスが発生し得る式の上で lazy-seq マクロを使う
- もし処理中に別のシーケンスが発生するなら next の代わりに rest を使う
- シーケンス処理時には高階関数を使う
- シーケンスの頭を抱えない
別シーケンス発生時は next の代わりに rest のくだりはどうも評価時に微妙な違いがあるようで。next は次の頭は評価するが rest は評価しないっぽい事を書いているがちょっと自信なし。
また直訳的に「別のシーケンス」と書いているがこれはJoy of Clojureでの直後の例にもあるように元のシーケンスの最初と残りのシーケンスを引数にして再帰的に呼び出した結果を繋げるという、良くある再帰パターンにも当てはまるみたい。*1
また rest と next は nil と () の評価結果も違ったり。
user> (rest ()) () user> (rest nil) () user> (next ()) nil user> (next nil) nil
これは他のlisp方言もある程度知ってる自分みたいなのが
シーケンス回してる時に何の気なしに when 使ってたりするとハマるかも。
user> (when () "true") "true" user> (when nil "true") nil
公式の他の lisp との違いでも書いてはいるんだけどね。
そういや Clojure 界隈じゃ S 式って表現見ないな。
リストがコンスセルじゃないからなのかな。
*1:コード例知りたい場合は同じ意味合いのサンプル探すか、回しモンじゃないけど本購入して下さい。あんまり本にあるコード例そのまま書くのもアレなんで。