The code is defined in a name space which I’m required with :as ty.
When I call (ty/typep 3 :sigma) I get the error:
clojure-rte.core> (ty/typep 1 :sigma)
Execution error (ArityException) at clojure-rte.core/eval38624 (form-init8934354515316755715.clj:3267).
Wrong number of args (2) passed to: clojure-rte.type/eval38515/fn--38516
clojure-rte.core>
Any clue about what I’m doing wrong?
BTW I changed the anonymous function def to use [& others] because I wanted to see what it is being called with, but apparently the error occurs before it reaches that point, because the println doesn’t seem to happen.
I believe the issue is that repeatedly evaluating the defmulti form doesn’t actually change the dispatch function. If you look at the implementation of defmulti, you’ll see that the def form it produces is inside a when-not condition that is only truthy when the var doesn’t already refer to a multimethod. The solution is to just eval (def typep :whatever) to make it so that var no longer refers to a multimethod, then re-evaluate your defmulti form.
ouch. If I’m not mistaken there are some top-level forms in Common Lisp which have this type of ignore-the-second-time semantics. However, when slime explicitly re-evaluates then, it forces a seen-for-the-first-time semantics. E.g., defvar.
Multimethods offer an “open” kind of extensibility; the defmethod’s for a defmulti might be in any part of your program. Reinitializing the multimethod ditches all the methods that had registered to handle it - which can be, depending on your purposes, a major inconvenience. When the defmethod’s are colocated with the defmulti, I tend to put (def … nil) right before (defmulti …), to clear it so the defmulti will be heeded if I run it again.
I thought the requires didn’t reload something already loaded unless you forced it with reload. Was there a time where that wasn’t true and they needed to add an extra check on defmulti?
Interesting, I think maybe back then the trade-off back then made sense to choose defounce so as not to unload all defmethod applied by accident. At the same time, today most editor easily can re-load all sources, so you wouldn’t have to chase much.
I also personally think we lost in this trade. From the fact that many people are putting a (def nil ...) above their defmulti, and somehow not complaining about having to chase the demethods, I think the prior behavior might have been a better deal.
Any how, good to understand the history better. I also see that there’s no best way here.
Hum, that’s pretty cool. Why only while deving? This seems like a pretty good approach that has no compromise minus maybe the small Var indirection overhead, but most function call have it anyways, and I think direct linking could remove it? Not sure.