@aud To be a little more precise, a function like `void foo(Bar bar)` and one like `fn foo<T: Bar>(bar: T) -> ()` are morally quite similar, if extremely different in literal meaning. They're both ways of saying "this function takes a value of any type that's Bar-like," but the former *also* adds that any individual value of a Bar-like type can be referred to by a binding of type Bar.
That's a very heavy additional assumption, and places severe constraints on how you organize code.
@aud So you can solve that with `T add<T>(T a, T b)`, but now you've lost the `Addable` constraint. The most common solution I've seen is to have `T add<T: Addable>(T a, T b)`.
But there's a word for "a collection of types that can be used to satisfy a constraint on valid type parameters." It's a typeclass, or in Rust terminology, a trait. Or in C++ terminology, a concept.
@trochee @aud I forgot! I wrote a whole newsletter on this!
https://buttondown.com/xgranade/archive/subclasses-and-typeclasses/
@trochee @aud But yes, the proliferation of names for the same thing is awful, especially when they have such common uses outside of programming. (Arguably, even the word "type" has that problem.)
I will posit that partially comes about because (a) the word "class" is already widely used in programming to indicate something different than a "typeclass," and (b) most people's introduction to "typeclass" is in the context of functional programming, which many of us are taught to hate.