clojure

2026-02-24T03:29:23.363249Z

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

lassemaatta 2026-02-25T18:11:28.420099Z

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

exitsandman 2026-02-25T19:20:20.379349Z

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

2026-02-25T23:35:03.932319Z

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
Ben Sless 2026-02-26T04:31:30.192409Z

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

2026-02-26T04:40:10.277169Z

that's naughty

😁 1
Ben Sless 2026-02-26T04:43:44.108799Z

It works 🤷‍♂️

Ben Sless 2026-02-26T04:44:15.215779Z

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

exitsandman 2026-02-26T07:32:54.864649Z

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

Ben Sless 2026-02-26T07:34:39.169539Z

Yes

exitsandman 2026-02-26T07:42:34.355889Z

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

Ben Sless 2026-02-26T08:05:04.082679Z

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)

Ben Sless 2026-02-26T08:05:18.687069Z

and fixed the hygiene issue

respatialized 2026-02-24T13:08:20.820699Z

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
respatialized 2026-02-24T13:08:37.766379Z

if so, this definitely would have helped me recently 😅

2026-02-24T13:14:17.932449Z

yes! exactly

2026-02-24T23:27:47.847779Z

2026-02-24T23:28:40.910439Z

Is there a way to turn off the cache?

2026-02-24T23:33:46.141989Z

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

➕ 1
2026-02-24T23:36:42.667069Z

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.

2026-02-24T23:37:39.970379Z

might be worth asking in a new thread

dpsutton 2026-02-24T03:37:39.284979Z

Always regret when I don't

2026-02-24T04:13:25.675649Z

big same

teodorlu 2026-02-24T06:37:49.667239Z

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

➕ 2