swap!, reverse!, sort!, sort-by!, index-of, min-of, max-of, map!, reduce and filter, each written once over $t. Every call site in the corpus moves with them. min-of and max-of are not min and max because min and max are builtins over two or more numbers and nothing shadows a builtin. These reduce a slice, which is a different operation at a different arity. sort-bytes! did not collapse into sort!, and the reason is the point of the predicates: a [u8] is not ordered? and cannot be, because < is an instruction and comparing two slices lexicographically is a loop. It is sort-by! with bytes<? written in, one line, keeping its name and its stability note. sum-i32/sum-f32 and append-i64!/append-f64! stay for the reasons the spike gave. Not what the notes predicted: none of the ten collapses on a signature change alone. filter and reduce need copyable? because the checker demands it - reduce's accumulator at (Vec i32) is a double move - and the rest declare it because a slice of owning elements would have them duplicating headers.
16 lines
778 B
Plaintext
16 lines
778 B
Plaintext
;;;; The refusal, at the definition and not at a call site.
|
|
;;;;
|
|
;;;; A generic body is checked once with its type variables abstract, so an
|
|
;;;; operator the variable is not declared to support is refused here, naming
|
|
;;;; the variable — rather than at whichever call site first instantiated it
|
|
;;;; at a type that did not work. That is not Odin's model: Odin checks a
|
|
;;;; polymorphic body only per instantiation, so (+ a b) over a $T compiles
|
|
;;;; there and fails only if someone reaches it at a type without +.
|
|
;;;;
|
|
;;;; The way out is either predicate — {:where (numeric? $t)} — or the
|
|
;;;; parameter, a (Fn [$t $t] $t) the caller supplies. Neither is written
|
|
;;;; here, which is the point.
|
|
(defn add2 [a $t b $t] $t (+ a b))
|
|
|
|
(defn main [] () (println (add2 1 2)))
|