0

I tried the following code (learning about macros):

(require '[clojure.template :as temp])

(defn fna [x] (println "a" x) x)
(defn fnb [x] (println "b" x) x)

(temp/apply-template '[& fns]
                     '(fn [payload] (-> payload fns))
                     '[fna fnb])
;; returns (fn [payload] (-> payload fnb))

I am surprised by the output, as I was expecting:

(fn [payload] (-> payload fna fnb))

Why is it producing this output, and what would be a way to achieve the above? I specifically says in the doc:

argv is an argument list, as in defn.

Note: it could be written like so, but I am trying to understand how to use template:

(defmacro wrap-fn-> [& fns]
  `(fn [~'x#]
     (-> ~'x
         ~@fns)))
1
  • I would say, if you are learning to use template because you hope it will be useful, don't bother. It is not used in real life outside of clojure.test, and it is a fairly limited tool; knowing how to write the macro yourself will serve you far better. Commented Mar 3, 2017 at 18:28

1 Answer 1

1

The examples here

do not show the use of "rest args" like [& fns]. I think that is where you are going wrong. Try this:

(println
  (temp/apply-template
    '[x y]
    '(fn [payload] (-> payload x y))
    '[fna fnb]))

=> (fn [payload] (-> payload fna fnb))

BTW, I've never seen clojure.template in use before - it looks like a very specialized tool.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes it would work like that, but for a fixed number of fns, I am trying to make it take a variadic number of arguments. Note, this is for learning purposes (never saw it before looking in the clojure.test source). And in practice I would use the defmacro to take a variable number of arguments, and pass it to apply-template anyway. This is pure curiosity (so far). Moreover I don't see why it would take fnb rather than fna.
It "takes" fnb because [& fns] is an argument list containing two symbols, & and fns. Your template definition ignores the first argument, named & and passed fna, and uses only the second argument, named fns and passed fnb.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.