;;;; A generic defined in a package, instantiated by the program. ;;;; ;;;; The copies are made here, from a body written there. Three things are ;;;; being asserted and only the first is obvious: that the call works at all; ;;;; that instantiation is still transitive across the boundary, so gen/ends ;;;; asking for gen/last-of at its own variable generates that copy from this ;;;; file's call site; and that a {:where} clause written in the package is ;;;; what a caller here is judged against. ;;;; ;;;; And one thing in the other direction: a generic written *here* calling a ;;;; generic written *there* at its own variable, which is the shape that only ;;;; resolves once both bodies are in one namespace. (import gen "pkgs/gen") ;;; Local generic over the imported one, at this file's variable. (defn tail-twice [s [$t]] $t {:where (numeric? $t)} (+ (gen/ends s) (gen/ends s))) (defn main [] i32 (let [ns [5 3 9 1] fs [2.5 0.5 1.5]] ;; One package generic at two element types: two copies, one body. (println (gen/last-of (slice ns 0 4))) (println (gen/last-of (slice fs 0 3))) ;; The transitive one, also at two. (println (gen/ends (slice ns 0 4))) (println (gen/ends (slice fs 0 3))) ;; The bounded one. (println (gen/largest (slice ns 0 4))) ;; And the local generic that calls across the boundary at its own $t. (println (tail-twice (slice ns 0 4))) (println (tail-twice (slice fs 0 3)))) 0)