Reference - Macros マクロ
Clojure has a programmatic macro system which allows the compiler to be extended by user code. Clojureにはプログラムによるマクロシステムがあり、それによって、ユーザのコードによりコンパイラを拡張できる。Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. 他の言語であれば組み込みの基本要素などとして実現するほかないような構文的要素を、マクロでならば定義できる。 Many core constructs of Clojure are not, in fact, primitives, but are normal macros. 一見Clojureの基本要素に見えるものの多くは実際には通常のマクロとして実装されている。
Some macros produce simple combinations of primitive forms. いくつかのマクロは基本的なフォームを単純に組み合わせたものだ。For example, when
combines if
and do
: 例えばwhen
はif
とdo
を組み合わせたものだ。
user=> (macroexpand '(when (pos? a) (println "positive") (/ b a))) (if (pos? a) (do (println "positive") (/ b a)))
Other macros re-arrange forms in useful ways, like the ->
macro, which recursively inserts each expression as the first argument of the next expression: また他のマクロは、与えられたフォームらを有意義な形に構成しなおす。例えば->
マクロはその一例であり、以下のように、次の式の第1引数としてそれぞれの式を再帰的に挿入する。
user=> (-> {} (assoc :a 1) (assoc :b 2)) {:b 2, :a 1} user=> (macroexpand '(-> {} (assoc :a 1) (assoc :b 2))) (assoc (clojure.core/-> {} (assoc :a 1)) :b 2)
Special variables 特別変数
Two special variables are available inside defmacro for more advanced usages: defmacroの中では、高度な利用のために、2つの特別な変数が使える。
&form
- the actual form (as data) that is being invoked 実際に呼び出されたフォーム(のデータとしての表現)&env
- a map of local bindings at the point of macro expansion. マクロ展開時点でのローカル束縛のマップ。The env map is from symbols to objects holding compiler information about that binding. envマップは、シンボルからオブジェクトへのマップである。そのオブジェクトには、その束縛についてのコンパイラの情報が保持されている。
All of the following macros are documented on the API page. 以下のマクロの全てはAPIのページに説明されている。Many are also discusses on topic pages as noted: 以下に示すように、いくつかのマクロについては特に解説した記事がある。
- Creating macros マクロを作る: defmacro definline macroexpand-1 macroexpand
- Branching 分岐: and or when when-not when-let when-first if-not if-let cond condp
- Looping (see also Sequences) 反復(シーケンスも参照のこと): for doseq dotimes while
- Working with vars (see also Vars and Environment) varに関する処理(Vars and Environmentも参照): ns declare defn defmacro definline defmethod defmulti defn- defonce defstruct
- Arranging code differently コードを構成しなおす: .. doto ->
- Dynamic scopes (see also Vars and Environment) 動的スコープ(Vars and Environmentも参照): binding locking time with-in-str with-local-vars with-open with-out-str with-precision
- Creating lazy things (see also Sequences) 遅延評価(シーケンスも参照): lazy-cat lazy-cons delay
- Java interop macros Java interopマクロ: .. amap areduce gen-class gen-interface proxy proxy-super memfn
- Documenting code ドキュメンテーション: assert comment doc
- Transactions トランザクション: dosync io!
A few special forms are actually implemented as macros, primarily to provide destructuring: fn let loop これら少数の特別形式は主に分割を提供するために実際にはマクロとして実装されている。