I am trying to write a macro similar (I think) in function to the threading macro, however this would allow me to specify a keyword where the previous form's insertion would happen. I was planning on using clojure.walk/prewalk-replace, but I am getting a clojure.lang.ArityException. Here is the code:
(defmacro streamops [data form]
(let [keewurd :...]
(cond
(not (seq? form)) form
(= (count form) 0) data
:else (streamops ~(clojure.walk/prewalk-replace
{keewurd data} (first form))
~(rest form)))))`
but when I try to apply the unit test:
(= (macroexpand '(streamops 3 ( (+ 1 :...) (* :... 2))))
'(* (+ 1 3) 2))
It produces:
clojure.lang.ArityException: Wrong number of args (-1) passed to: walk$prewalk-replace
Compiler.java:6473 clojure.lang.Compiler.macroexpand1
core.clj:3633 clojure.core/macroexpand-1
core.clj:3642 clojure.core/macroexpand
What am I doing wrong?
You seem to have a misplaced syntax-quote `
in the definition of your macro, since it is placed at the end of it in the code you posted, but there's no syntax-quoting in the forms where you use unquote ~
.
The following works just fine:
(defmacro streamops [data form]
(let [keewurd :...]
(cond
(not (seq? form)) form
(= (count form) 0) data
:else `(streamops ~(clojure.walk/prewalk-replace
{keewurd data} (first form))
~(rest form)))))
(= (macroexpand '(streamops 3 ( (+ 1 :...) (* :... 2))))
'(* (+ 1 3) 2))
;= true
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.