매크로

매크로 (Macros)

Clojure에는 사용자 코드가 컴파일러를 확장할 수 있게 해 주는 프로그램적 매크로 시스템이 있어요. 매크로는 다른 언어에서는 원시(primitive) 기능이나 내장 지원이 필요했을 구문 구성소를 정의하는 데 사용될 수 있어요. Clojure의 많은 핵심 구성소는 사실 원시 기능이 아니라 평범한 매크로예요.

일부 매크로는 원시 폼의 단순한 결합을 만들어내요. 예를 들어 whenifdo를 결합해요:

user=> (macroexpand '(when (pos? a) (println "positive") (/ b a)))
(if (pos? a) (do (println "positive") (/ b a)))

다른 매크로는 폼을 유용한 방식으로 재배치해요. pass:[->] 매크로처럼, 각 표현식을 다음 표현식의 첫 번째 인자로 재귀적으로 삽입해요:

user=> (-> {} (assoc :a 1) (assoc :b 2))
{:b 2, :a 1}
user=> (macroexpand '(-> {} (assoc :a 1) (assoc :b 2)))
(assoc (assoc {} :a 1) :b 2)

출처: Clojure 공식 문서 - Macros

본문

특수 변수 (Special variables)

defmacro 안에서 더 고급 용도를 위해 두 가지 특수 변수가 제공돼요:

  • &form - 호출되고 있는 실제 폼(데이터로서)
  • &env - 매크로 확장 지점에서의 지역 바인딩 맵. env 맵은 해당 바인딩에 대한 컴파일러 정보를 담고 있는 객체로의 심볼 맵이에요.

다음 매크로들은 모두 API 페이지에 문서화되어 있어요. 많은 것들이 명시된 대로 주제 페이지에서도 논의돼요:

몇몇 특수 폼은 실제로 매크로로 구현되는데, 주로 구조 분해(destructuring)를 제공하기 위해서예요: fn let loop

더 알아보기