Table of Contents
Clojure, ClojureScript 매크로 동작이 서로 다른가요?
"Clojure Programming" 에 나온 예제
(defmacro reverse-it [form]
(clojure.walk/postwalk #(if (symbol? %)
(symbol (clojure.string/reverse (name %)))
%)
form))
를 실행했는데 Clojure REPL에서는 잘 됐지만 CLJS REPL(lumo사용)에서는 제대로 동작을 안 하네요. 분명 뭔가 놓치고 있는데.. 뭔지를 모르겠습니다.
클로저스크립트의 매크로는 클로저에서와는 약간 다른 방식으로 처리됩니다.
클로저스크립트에서 매크로를 사용하려면, 매크로 코드는 *.clj
파일에 정의해 놓아야
합니다. 클로저스크립트 컴파일러가 매크로 코드를 만나면, 내부적으로 클로저 컴파일러를
호출해 매크로 확장을 한 후, 그 결과만을 넘겨받아 처리하기 때문입니다.
먼저 매크로를 .clj
파일에 정의해 놓습니다.
example.macro.clj
(ns example.macro
(:require [clojure.string :as str]
[clojure.walk :as walk]))
(defmacro reverse-it [form]
(walk/postwalk #(if (symbol? %)
(symbol (str/reverse (name %)))
%)
form))
다음은 lumo REPL에서 매크로를 호출하는 예입니다. 이때 require
가 아니라 require-macros
를
사용해야 합니다.
$ ls -l drwxr-xr-x 2 philos philos 4096 1월 31 11:21 example $ ls example macro.clj $ lumo Lumo 1.9.0 ClojureScript 1.10.439 Node.js v10.9.0 Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) Exit: Control+D or :cljs/quit or exit cljs.user=> (require-macros '[example.macro :refer [reverse-it]]) nil cljs.user=> (reverse-it #_=> (qesod [gra (egnar 5)] #_=> (nltnirp (cni gra)))) 1 2 3 4 5 nil