Clojureを遊ぶ:リストとマクロ
「7つの言語7つの世界」 を読んでClojureを始めた。
まったく思考がLISPerになってなく、すらすらプログラムが組める状態ではない。が、実に面白い。
Clojureの強力な点は、コレクションに対する操作を、非常に簡潔に書けるところだ。
まずはリスト。
リストは(list 1 2 3)
と書く。あるいはリーダーマクロの'
を使って'(1 2 3)
と書く。
user=> (def a '(1 2 3)) #'user/a user=> a (1 2 3) user=> (take 2 a) (1 2)
LISPのプログラムそのものがリストで構成されているデータで、
user=> (def b '(println 1)) #'user/b user=> b (println 1) user=> (eval b) 1 nil user=>
なんか、これだけでミニマクロみたいなものだな。
本当のマクロを使ってみる。
user=> (defmacro hello [txt] (println "Hello," txt)) #'user/hello user=> (hello "Clojure") Hello, Clojure nil
これくらいなら、普通に関数を定義すればよさそうだ。 実際やってみる。
user=> (defn hello_f [txt] (println "Hello," txt)) #'user/hello_f user=> (hello "Clojure") Hello, Clojure nil
同じ結果が出る。
しかし、以下で明確に処理の違いが分かる。
user=> (hello (print 1)) Hello, (print 1) nil user=> (hello_f (print 1)) 1Hello, nil nil
マクロの場合は引数を評価せずに、そのままリストとして渡すのに対して、 関数の場合は引数を評価してから渡す。
というところまでは分かったが、まだまだ感覚をつかめていない。