;;;; The map operations over a type-variable key, refused at the call site. ;;;; ;;;; A generic body is checked once with its type variables abstract, and the ;;;; map operations are one of the few forms that cannot be answered there: ;;;; the hash and the equality are emitted as concrete symbols chosen from the ;;;; concrete key type, and there is none until a copy exists. So they are ;;;; deferred to the instantiation, the way print and println are. ;;;; ;;;; What makes deferring them safe — and different from an unconstrained ;;;; (+ a b), which stays refused at the definition — is the clause. The ;;;; signature says {:where (is-hashable $t)}, so a call site that asks for a ;;;; key type with no usable equality is refused against a requirement the ;;;; author wrote down, at the call that asked for it. A float is that type: ;;;; NaN is not equal to itself, and 0.0 and -0.0 are equal while differing ;;;; bytewise. (defn is-seen [k $t] bool {:where (is-hashable $t)} (let [m (map-new t i32)] (put m k 1) (let [answer (has-key m k)] (free m) answer))) (defn main [] () (println (is-seen 3)) (println (is-seen 1.5)))