Programmer's Note

コード読み書きの備忘録。

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

マクロの場合は引数を評価せずに、そのままリストとして渡すのに対して、 関数の場合は引数を評価してから渡す。

というところまでは分かったが、まだまだ感覚をつかめていない。