Duncan Bayne
Duncan Bayne

Reputation: 3959

How to capture in lexical scope in a Clojure macro?

In Common Lisp, I can define and use a macro that captures a variable from lexical scope, so that I can use it within a let form:

CL-USER> (defmacro plus9 () `(+ 9 woo))
PLUS9
CL-USER> (macroexpand '(plus9))
(+ 9 WOO)
T
CL-USER> (let ((woo 1)) (plus9))
10

However, when I define a similar macro in Clojure, it's looking for a definition of woo in the user namespace:

user=> (defmacro plus9 [] `(+ 9 woo))
#'user/plus9
user=> (macroexpand '(plus9))
(clojure.core/+ 9 user/woo)
user=> (let [woo 1] (plus9))

CompilerException java.lang.RuntimeException: No such var: user/woo

Clearly I'm misunderstanding how scopes work in Clojure. What's the correct way of achieving this macro with Clojure?

Upvotes: 6

Views: 501

Answers (1)

sloth
sloth

Reputation: 101162

I'm a macro noob, but how about

user=> (defmacro plus9 [] `(+ 9 ~'woo))
#'user/plus9
user=> (macroexpand '(plus9))
(clojure.core/+ 9 woo)
user=> (let [woo 1] (plus9))
10

Upvotes: 9

Related Questions