The fact that I've already started copy-pasting code between Typed Clojure projects makes me think that it would be valuable to collect this stuff together for general reuse. So, what do you all think about these two categories of Typed Clojure code?
- Host platform annotations
For example, (t/non-nil-return java.lang.String/substring :all) probably shouldn't have to be manually entered into everyone's projects. - "Utility" type definitions, particularly those that concisely express the preconditions of Clojure idioms.
Here are some examples of those "Utility" type definitions:
(require '[clojure.core.typed :as t :refer [defalias U I TFn ExactCount]])
(defalias Nameable (U String clojure.lang.Named))
;; I.e., anything you can safely call `clojure.core/name` on.
(defalias VPair (TFn [[x :variance :covariant]]
(I (t/Vec x)
(ExactCount 2))))
;; I.e., a homogeneous ordered tuple of length 2
(defalias HVPair (TFn [[k :variance :covariant]
[v :variance :covariant]]
(t/HVec [k v])))
;; I.e., a heterogeneous ordered tuple of length 2
(defalias PairsSeq (TFn [[k :variance :covariant]
[v :variance :covariant]]
(U (t/Map k v)
(t/Seq (HVPair k v)))))
;; `PairsSeq` captures the idiom of some collection being processable as pairs. Like, in `(doseq [[l r] ps] …)`, `ps` must be an instance of `(PairsSeq x y)` for some type `x` and some type `y`.