Peeyush Kushwaha
Peeyush Kushwaha

Reputation: 3623

Using a loop inside a macro

Consider this minimal example

(defmacro foo []
  `(list ,@(for [i [1 2 3]] (+ 1 i))))

I expect (foo) to expand to (list 2 3 4)

But instead, I get a bunch of indecipherable errors when I try (macroexpand-1 (foo)

Syntax error macroexpanding clojure.core/let at (*cider-repl <filepath>:localhost:43203(clj)*:366:22).
test/i - failed: simple-symbol? at: [:bindings :form :local-symbol] spec: :clojure.core.specs.alpha/local-name
test/i - failed: vector? at: [:bindings :form :seq-destructure] spec: :clojure.core.specs.alpha/seq-binding-form
test/i - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-bindings
test/i - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-special-binding

What's going wrong? Can't I use for loops inside my macro definitions?

Upvotes: 1

Views: 254

Answers (1)

Alex Miller
Alex Miller

Reputation: 70201

,@ should be ~@.

user=> (defmacro foo []
  `(list ~@(for [i [1 2 3]] (+ 1 i))))
#'user/foo

user=> (macroexpand-1 '(foo))
(clojure.core/list 2 3 4)

user=> (foo)
(2 3 4)

Upvotes: 3

Related Questions