Doing so at type / function level allows to introduce them gradually and with low ceremony, compared to parametrized modules (likely you mean OCaml here?). Gradual approaches seem to work best in real world, hence the prevalence of generic functions and parametrized types.
No, I was thinking of Ada or Oberon+. Here is a discussion: https://oberon-lang.github.io/2021/07/17/considering-generic...
Here is the specification: https://github.com/oberon-lang/specification/blob/master/The...
Here is a discussion why it is designed like this: https://oberon-lang.github.io/2021/07/17/considering-generic...
[1] https://ziglang.org/documentation/master/#comptime "Compile-time parameters is how Zig implements generics. It is compile-time duck typing." [2] https://ziglang.org/documentation/master/#import [3] https://ziglang.org/documentation/master/#void "By using void as the type of the value, the hash map entry type has no value field, and thus the hash map takes up less space. Further, all the code that deals with storing and loading the value is deleted, as seen above."