Another question that I can't quite seem to find the answer to in the docs / paper, I'm using this macro to define a kaocha plugin
(kp/defplugin background-check.kaocha/plugin
(post-run
[result]
(assert (map? result))
(runner/check-dirs (get result :background-check/dirs))
result))
Which expands to:
(do
(clojure.core/defn
plugin-background-check.kaocha/post-run-hook
[background-check.kaocha/result]
(clojure.core/assert
(clojure.core/map? background-check.kaocha/result))
(background-check.runner/check-dirs
(clojure.core/get
background-check.kaocha/result
:background-check/dirs))
background-check.kaocha/result)
(def
plugin-hooks
{:kaocha.plugin/id :background-check.kaocha/plugin,
:kaocha.plugin/description "",
:kaocha.hooks/background-check.kaocha/post-run
plugin-background-check.kaocha/post-run-hook})
(clojure.core/defmethod
kaocha.plugin/-register
:background-check.kaocha/plugin
[___22953__auto__ plugins__22954__auto__]
(clojure.core/conj plugins__22954__auto__ plugin-hooks)))I have this type error:
│ Multimethod requires dispatch type: kaocha.plugin/-register
│
│ Hint: defmulti must be checked before its defmethods
And I can't find how to type check a defmulti. I see t/MultiFn in the source code but I think that's commented out. Is this something that can be typed or should I kind of tag it in such a way that it skips typing?
I don't really need to type check this namespace but I want to force myself to so I learn how to type check everything instead of just when it's easy.I'm not sure there's a way to provide the dispatch function type explicitly.
The intended workflow is to give the multimethod a function type, then the dispatch function is inferred after checking the defmulti, which is then used to narrow the types in defmethod.
However in this case you're not going to check the defmulti.
And this whole thing should really use t/Multi which I never finished.
So you're stuck here. What you can do is add a custom rule for defplugin.
First, add a typedclojure_config.cljc at the root of the classpath like https://github.com/typedclojure/typedclojure/blob/main/typed/lib.clojure/src/typedclojure_config.cljc
In that example, the rule exists in typed.clj.ext.clojure.core. You will add it to your own namespace like background-check.ext.kaocha.core.
This namespace will automatically be loaded to collect rules before checking.
Taking the custom rule for clojure.core/assert as an example:
1. https://github.com/typedclojure/typedclojure/blob/0b3ffb01b6a943bdfe0c279cfc7aae78304bec7c/typed/lib.clojure/src/typed/clj/ext/clojure/core.clj#L13-L18 that contains the rule, for lazy loading
2. https://github.com/typedclojure/typedclojure/blob/0b3ffb01b6a943bdfe0c279cfc7aae78304bec7c/typed/lib.clojure/src/typed/clj/ext/clojure/core__assert.clj
As for what the rule should do, I'm not sure yet. But that should teach you something new 🙂
Also I'll add that the whole "defmulti must be check before defmethod" thing is thoroughly out of date since type checking has been parallelized!
Registering the inferred dispatch function is the remaining stateful output of type checking.
Nothing else learns new type information after checking a form. We're just in checking mode the whole time against type annotations. Which might also hint at why it was important to get annotations from malli or wherever you can get it, because the checker is hungry for top-level annotations.