Search code examples
clojuremacros

Clojure custom function for threading macro


I have a map and I want to write a custom function for updating it.

(-> {:a 1 :b 2}
    (fn [x] (update x :a inc)))

This of course is a simple example and could be easily done without the function wrapped around the update, but it shows what I want to do. But this gives me the following error.

Syntax error macroexpanding clojure.core/fn at (core.clj:108:1).
{:a 1, :b 2} - failed: vector? at: [:fn-tail :arity-1 :params] spec: :clojure.core.specs.alpha/param-list
{:a 1, :b 2} - failed: (or (nil? %) (sequential? %)) at: [:fn-tail :arity-n] spec: :clojure.core.specs.alpha/params+body

I don't get why this is not working, since the threading macro should but my map as first parameter in the function, right?


Solution

  • You can always use macroexpand to see what happened. In your case, macroexpand will return you:

    (fn {:a 1, :b 2} [x] (update x :a inc))
    

    obviously this is not a valid function. But if you tweak it this way:

    (-> {:a 1 :b 2}
        (#(update % :a inc)))
    

    the expanded form will then become valid:

    (#(update % :a inc) {:a 1, :b 2})