Warm tip: This article is reproduced from stackoverflow.com, please click
clojure macros

Clojure custom function for threading macro

发布于 2020-04-11 22:38:31

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?

Questioner
Codey
Viewed
63
rmcv 2020-02-02 23:19

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})