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