Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture in lexical scope in a Clojure macro?

Tags:

scope

clojure

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?

like image 544
Duncan Bayne Avatar asked Nov 02 '15 06:11

Duncan Bayne


1 Answers

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
like image 139
sloth Avatar answered Nov 19 '22 12:11

sloth