What about a 32 bit unsigned integer and a 64 bit unsigned integer? Are they still separate values?
You appear to be saying that the values of a type cannot be a subset of another type; that is, there is no '1', only a '1' that is an integer, a '1' that is a short, and so forth, and every '1' is distinct.
Fine, that's a possible way of looking at it, but why is that more valid or consistent than a model that allows subtypes? That, for example, the value '1' could be both a Number, an Integer, and a NaturalNumber?
Further, what's the practical difference between a type defined as consisting of the numbers [1 2 3], and an integer that's restricted to those values?
> This works in Clojure only because Clojure couples some semantics (data semantics plus operations on runtime type information) into every value, i.e. it restricts what values are even representable in the language in order to ensure that this function will always be safe to write.
Even if we view a Clojure value as a coupling between type and data, that's only a coupling between two things, and it ensures we can avoid further coupling caused by large record types. On net, we reduce the amount of coupling a statically typed language that uses closed record types would require.
For instance:
(defn average-wbc-count [{:patient/keys [wbc-counts]}]
(/ (apply + wbc-counts) (count wbc-counts)))
This function is coupled to only one key/value pair. Any other information in the map is irrelevant, which is why an invalid :patient/birthdate doesn't cause the function to fail. There's no coupling between :patient/birthdate and average-wbc-count.Conversely:
fn average_wbc_count(patient: &Patient) -> f64 {
patient.wbc_counts.iter().sum::<f64>() / patient.wbc_counts.len() as f64
}
This function requires patient to be a Patient struct, and therefore the function is implicitly coupled to every field in the struct, regardless of whether that field is ever actually used. I need to ensure that a patient has some birthdate that's an anticipated type (even if that's an error type) before I can call the function.