リストではなくシーケンスに入っている関数呼び出しも実行できる
macroexpand は展開結果をリストじゃなくてシーケンスで返してくるのにちょっと驚いた。
user> (macroexpand '(-> 1 (+ 2) (- 3))) (- (clojure.core/-> 1 (+ 2)) 3)
user> (type (macroexpand '(-> 1 (+ 2) (- 3)))) clojure.lang.Cons
user> (seq? (macroexpand '(-> 1 (+ 2) (- 3)))) true
user> (list? (macroexpand '(-> 1 (+ 2) (- 3)))) false
えっ、リストじゃないの? ってことは関数はリストじゃなくてシーケンスに入っていても構わないって事か。
user> (eval [+ 1 2]) [#<core$_PLUS___4509 clojure.core$_PLUS___4509@2d0a5068> 1 2]
ベクタはベクタに評価される。けど、シーケンスにしてやれば
user> (eval (seq [+ 1 2])) 3
リストみたいに関数を実行できる。でも list? に対して false を返されるのってどうなんだろ。
関数の入ったリストかを判定するのには list? よりも seq? を使った方がいいのか。それじゃ、リストの存在意義って何なんだろ。
user> (type '(1 2)) clojure.lang.PersistentList
user> (list? '(1 2)) true
これは当然。
user> (type (seq '(1 2))) clojure.lang.PersistentList
user> (list? (seq '(1 2))) true
一回 seq を噛ませてもリストに対しては何も変換しないようだ。
ベクタやマップはシーケンスに変換される。
user> (type [1 2]) clojure.lang.PersistentVector
user> (type (seq [1 2])) clojure.lang.PersistentVector$ChunkedSeq
user> (type {:a 1}) clojure.lang.PersistentArrayMap
user> (type (seq {:a 1})) clojure.lang.PersistentArrayMap$Seq
シーケンスはリストじゃない。
user> (list? (seq [1 2])) false