Macros: Clojure Reference 문서 번역

원문

Clojure has a programmatic macro system which allows the compiler to be extended by user code. 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.

Some macros produce simple combinations of primitive forms. For example, when combines if and do:

Clojure에는 사용자가 작성한 코드를 통해 컴파일러를 확장할 수 있는 프로그래밍 매크로 시스템이 있습니다. 매크로는 다른 언어였다면 기본으로 제공되고 있거나, 내부적으로 지원되어야 가능했을 구문 구조를 정의하는 데 사용됩니다. 실제로 Clojure의 다양한 핵심 구조는 매크로로 정의되어 있으며, 언어에서 기본적으로 제공하는 것이 아닙니다.

매크로는 기본적인 form들을 간단하게 조합해 만들 수도 있습니다.

예를 들어 whenifdo를 조합해서 만든 것입니다.

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:

-> 매크로처럼 유용성을 위해 form들을 재배치하는 매크로도 있습니다. -> 매크로는 각 표현식을 다음에 오는 표현식의 첫 번째 인자로 재귀적으로 삽입해 줍니다.

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:

  • &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.

defmacro 안쪽에서 사용할 수 있는 두 개의 특수 변수가 있습니다.

  • &form - 실제로 호출되는 (데이터로서의) form.
  • &env - 매크로 확장 시점에서의 로컬 바인딩을 위한 map. env map은 symbol에서 object까지 바인딩에 대한 컴파일러 정보를 갖고 있습니다.

All of the following macros are documented on the API page. Many are also discussed on topic pages as noted:

아래에서 소개하는 모든 매크로는 API 페이지에서 설명을 찾아볼 수 있습니다. 다음은 주제별 페이지를 모아놓은 것입니다.

A few special forms  are actually implemented as macros, primarily to provide destructuring: fn let loop

몇몇 special form들은 구조분해를 제공하기 위해 실제로 매크로를 통해 구현됩니다. fn, let, loop가 이에 해당됩니다.