Then at which point does a type become equivalent to a restriction that could be decoupled from the underlying type by choosing a broader type?
> No, you just have to be explicit about the possibility of a birthdate (or other fields) being of a wide type
Yes, you could recreate Clojure's semantics in Rust. More accurately, I'd say you'd be looking at defining it like so:
struct WbcCount {
wbc_count: Vec<u64>
}
struct BirthDate {
birth_date: Box<dyn Any>
}
Since we want to be able to reason about these keypairs individually. You might have a structure that has a WbcCount but not a BirthDate, or one with a BirthDate but not a WbcCount, or one with neither.We'd then be faced with the challenge of creating a type that could contain an arbitrary number of unique structs, and to be able to pull a struct out of that set by its type. Realistically we'd probably just use a HashMap at that point and discard all static typing.
Alternatively, we could create a mega struct that contains every possible field we could want to use, whether or not we know they are related, and use this data structure to represent all structured data in the application. The "if everything is coupled, nothing is" approach.
But both of those options are difficult or unidiomatic to write.
Languages like Rust, Java, etc. encourage coupling of data because it's more convenient and space efficient to group data together in records/structs. In Clojure, there's no need to do so; we can couple only when necessary. If we don't need to know the birthdate to calculate the white blood cell count, then we can exclude that field from the input type checking. Most statically typed languages find this difficult, with TypeScript being one of the few exceptions in this regard.