Traits as types of types

Whether the real number 1 and the complex number 1+0i are "the same thing" is mostly just a semantics game.

In mathematics, we generally treat them as identical, where the objects we call "real numbers" are just a subset of complex numbers. This is because all of the properties of 1 and theorems that apply to 1 also apply to 1+0i. Treating them as separate things would only add an annoying source of uninteresting complexity to all mathematical discussion of either thing.

In programming languages with type systems, we generally treat them as different, often simply because they have different implementations (with observably different properties like memory footprint). And even if their implementations were the same, it's often less error-prone to be specific about types in code that humans are meant to read, write and run on their computers. But math never has to think about "implementing" a type (unless you count "implementing" stuff in a mathematically idealized context like a Turing machine) or about "clients running" it.


Going back to the original question...

In the simplest and broadest possible sense, a mathematical "type" is just a set of values. No other restrictions.
{ 1, 2, 3, ... } is a type
{ 1 } is a type
{ 1, 3, 5, ... } is a type
{ apple, orange, kumquat } is a type
{ 1, kumquat, 42 } is a type

Programming languages usually define a "type" more restrictively than this for a bunch of practical reasons.

But in the original quote you were asking about:

Generic types describe ranges of types, just like types describe ranges of values, and traits are to generic types what properties are to structs. So a new trait actually defines a new type of types, and can be combined with other traits to form a hierarchy of traits.

I assume "type", "range" and "property" are all meant to be read in an extremely broad sense, effectively as synonyms for "set", as this is often how they're used in mathematics. Most of your post seems to be confused by trying to apply the usual meaning of "range" in ordinary colloquial English, and it's true that that meaning simply does not apply here.

"generic type" I assume refers to the part of concrete Rust syntax we usually call a type parameter, i.e. the T in fn foo<T>(t: T) { ... }. It's certainly true that this type parameter represents or describes a set of Rust types, in this case the set of all (sized) Rust types.

So if you squint at the original quote with all these synonyms in mind, its most literal meaning is just the tautology that a set of sets of Rust values is... a set of sets of Rust values.

What the quote is probably trying to do is point out that all these programming concepts, in their full generality, end up being equivalent or having similar relationships to each other that aren't obvious (or simply aren't true) from the perspective of any single concrete programming language. But I do think the exact intent of the quote is pretty muddled since it's unclear how concrete and how abstract they expect each word to be read. In other words, you're probably right to be confused by it (unless that quote had a lot of context you didn't link to).

EDIT: Oh, apparently this thread was split off TWiR quote of the week - #780 by L0uisc referring to Suggestion for making Rust's trait system more usable for generics - #68 by mankinskin I guess that doesn't change my post much though; I'm extremely unclear on what that thread was trying to propose.

4 Likes