;;;; 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 (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 seen? [k $t] bool {:where (hashable? $t)} (let [m (map-new t i32)] (put m k 1) (let [answer (has-key? m k)] (free m) answer))) (defn main [] () (println (seen? 3)) (println (seen? 1.5)))