34 lines
1.4 KiB
Plaintext
34 lines
1.4 KiB
Plaintext
;;;; A package whose exports are generic.
|
|
;;;;
|
|
;;;; The spike's "no plan" bucket named this one, and named what makes it
|
|
;;;; work: Load flattens every import into one namespace *before* the checker
|
|
;;;; runs, so the generic's body is present at the call site the way a C++
|
|
;;;; template's is because it sits in a header. Nothing here crosses a real
|
|
;;;; compilation-unit boundary, and the day a package becomes one, this is the
|
|
;;;; thing that has to change — a copy is made from a body, and a body that
|
|
;;;; did not cross cannot be copied.
|
|
;;;;
|
|
;;;; What this package is for: a generic called from the program at two types,
|
|
;;;; a bounded generic whose {:where} has to be readable from outside the
|
|
;;;; file that wrote it, and a generic that calls another generic in its own
|
|
;;;; package at its own variable, so the transitive copy is generated from a
|
|
;;;; call site two files away.
|
|
|
|
(defn last-of [s [$t]] $t
|
|
(at s (- (length s) 1)))
|
|
|
|
;;; Calls last-of at its own variable: the copy of last-of is generated when
|
|
;;; this is instantiated, and this is instantiated from the program.
|
|
(defn ends [s [$t]] $t
|
|
(last-of s))
|
|
|
|
;;; The bound travels with the signature. A caller that passes a type the
|
|
;;; clause refuses is refused at the call, against a requirement written in
|
|
;;; another file.
|
|
(defn largest [s [$t]] $t
|
|
{:where (is-ordered $t)}
|
|
(let [m (at s 0)]
|
|
(dotimes [i (length s)]
|
|
(set m (max m (at s i))))
|
|
m))
|