日曜プログラミング

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

Clojure で lazy-seq を生む関数についてのトラブルシューティング

Clojure で lazy-seq を生む関数と言うのは cheatsheetの Creating a Lazy Seq に書かれている関数の他に も良く使う所では map 関数なんかもそうだったりする。Programming Clojure を読んだ事があれば 何となく記憶してるかもしれない。

REPL で確かめてみると分かる。

(type (map inc [1 2 3]))
;=> clojure.lang.LazySeq

さて、今回改めて取り上げるのはこの lazy-seq、一部 NPE を誘発する状況があり、 その場合どうするかをメモしておこうと思う。

自分が発生した時の詳細な条件は掴みきれていないものの Java interop, nth 辺りを組み合わせて使っていた時に発生しており、 多分前者じゃないかと予想はしているが未検証。

この話で厄介なのは、REPL や println デバッグだと出ないという事。 REPL も println も lazy-seq を渡しても一度全て評価してから表示するためである。

その場しのぎ的な対応にはなるが、lazy-seq を生む関数なのかどうかは一旦忘れ、 NPE が発生したらシーケンス加工中に lazy-seq になってるのが原因かどうかを確認し そうであれば不格好だが doall とかかましていくように対処する事にした。 lazy-seq を全て避けた標準の代替関数を作るのもかったるいし。

これは機会があればどこで発生するのか改めて検証したい。