clojure 2026-02-24

has anyone written about using vars for the dispatch function of multimethods? it's a habit i've picked up when doing repl-driven development, but i don't remember where i read about it or when i put it together

re: the cache: I think it's this https://github.com/clojure/clojure/blob/a3fa897590f70207eea3573759739810f2b6ab6c/src/jvm/clojure/lang/MultiFn.java#L26 I recall a discussion about the expectation that the dispatch function should return a small number of discrete values (EDIT: https://ask.clojure.org/index.php/10532/memory-leak-using-the-default-method-of-a-multimethod?show=10533#a10533). Doing something like a) using identity as the dispatch fn and then b) installing defmethods for like 0->"none", 1->"one", default->"many" and c) invoking it for every integer will grow the cache (2->default, 3->default, ... MAX_INT->default).

Wow, that feels very suspicious to me tbh, and at very least something worth documenting.

Oh good. Whatever the cache's quirks, interfering with the REPL benefits of using a Var as dispatch fn is not one of them.

👍 1

You don't have to use a var, you just want indirection (ab)use the compiler https://github.com/bsless/eta/blob/master/src/bsless/eta.clj#L3

that's naughty

😁 1

It works 🤷‍♂️

Bonus points - will get inlined well by the compiler when direct linking is enabled

hygiene concerns aside (this breaks with, say, ($ a)), the other two macros are just aliases right?

Asking because I feel that I'm missing a trick: this as you say should be good for direct linking on a few-args fn, but outside of that doesn't it just add a layer of indirection for no benefit (as the dynamism is achieved by derefing the var, i.e. the same way it'd happen with var punning)?

if you care about performance then your final artifact will be directly linked and it matters if you don't, then the added level of indirection does not matter (and the var read adds more overhead than a function call that will be inlined)

and fixed the hygiene issue

using vars as in doing something like

(defn io-dispatch [{:keys [input-type output-type]}]
  [input-type output-type])

(defmulti extensible-io #'io-dispatch)

(defmethod extensible-io [:edn :json] [m] (json/write-str (:data m)))
instead of
(defmulti extensible-io io-dispatch)

🎯 1

if so, this definitely would have helped me recently 😅

Is there a way to turn off the cache?

do you have a source for that which isn't from an llm?

➕ 1

If I could search the Clojure Jira... seems to me there was a bug (report) of a memory leak related to dispatch-function input values that lead to the default path.

might be worth asking in a new thread

Always regret when I don't

Seems like the same rule of thumb as passing a var to httpkit/run-server to me. Otherwise, it's not interactive!

➕ 2