日曜プログラミング

休日趣味でやってるプログラミング関連記事をダラダラと

lazy-seq の 4 つのルール, 後 next と rest の違いとか

Joy of Clojure P115 にあったのをメモ。
プログラミングClojureにもあったと思うが結構忘れがちなので。

訳は適当。

  1. 遅延シーケンスが発生し得る式の上で lazy-seq マクロを使う
  2. もし処理中に別のシーケンスが発生するなら next の代わりに rest を使う
  3. シーケンス処理時には高階関数を使う
  4. シーケンスの頭を抱えない

別シーケンス発生時は 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:コード例知りたい場合は同じ意味合いのサンプル探すか、回しモンじゃないけど本購入して下さい。あんまり本にあるコード例そのまま書くのもアレなんで。