I’m having trouble getting a clojure defmacro to do what I want. I’ve reduced my actual code down to the following snippet.
This creates something close to what I want. I am trying to conditionally insert either (first p#) or (second p#) depending on a parameter passed into the macro.
(defmacro mmz1 [t]
`(map (fn [p#] (let [t1# (first p#)
t2# ~(if t `(first p#) `(second p#))]
(* t1# t2#)))
[ [1 2] [3 4] ]))
(macroexpand-1 '(mmz1 false))
shows
(map
(fn [p__18341__auto__]
(let [t1__18342__auto__ (first p__18341__auto__)
t2__18343__auto__ (second p__18340__auto__)]
(* t1__18342__auto__ t2__18343__auto__)))
[[1 2] [3 4]])
But, note that the variable in this form (second p_18340_auto_) does not match the anonymous function argument p_18341_auto_. So, executing the code results in an error since that second var is not defined. How can I get these vars to match? This is what I would like to accomplish.
For testing purposes, this code accomplishes what I want, but I don’t want the (if) form in the resulting macro code that sets t2#. A macro should allow me to do this–shouldn’t it?
(defmacro mmz0 [t]
`(map (fn [p#] (let [t1# (first p#)
t2# (if ~t (first p#) (second p#))]
(* t1# t2#)))
[ [1 2] [3 4] ]))
(macroexpand-1 '(mmz0 false))
shows
(map
(fn [p__18387__auto__]
(let [t1__18388__auto__ (first p__18387__auto__)
t2__18389__auto__ (if false
(first p__18387__auto__)
(second p__18387__auto__))]
(* t1__18388__auto__ t2__18389__auto__)))
[[1 2] [3 4]])
and the output of the code is the expected:
(mmz0 false) -> (2 12)
One of the solutions
Update. More general solution
You can replace
(fn [p#]...)inifbranches with more complex functions.Update2. Simpler solution that uses predefined function formal parameter
p