A nominal type system is not a more constrained version of a structural one. That statement would imply that any program written for the former would work using the latter as well, which is false. Name collisions would simply not resolve.
For it to work, you need to add a namespace to all the colliding methods (a simple one would be a prefix like people do in C).
A nominal system is a more constrained structural system in some ways, but the opposite is true as well, so it's not as simple as 'nominal is subset of structural'.
Hmmh. You seem to be restating what was said above.
A nominal type system still is superseded by a structural type system.
The difference is in how a type is defined. Or what kind of constraints are in entailment said otherwise.
An interface enforces constraints. The difference here is merely that the current implementations only have either one of these type of interfaces. So for the structural type system, all methods are in the global namespace, somehow.
That's all. Because our current languages are this way doesn't mean that the two concepts cannot be reconciliated or that one is just better than the other.
> That's all. Because our current languages are this way doesn't mean that the two concepts cannot be reconciliated or that one is just better than the other.
I don't think I agree with this though, I believe they're fundamentally different. The whole point of structural constraints is that they don't need the type to be aware of them. The point of nominal constraints though is that they require the type to explicitly acknowledge them.
In an ideal situation, everyone names and types things the same ('logical') way, so structural constraints 'just work'. A type implements has_organ, and an interface requires has_organ, and the type is automatically compatible with the interface.
A nominal system is the opposite though; the type explicitly understands what a specific interface implies and formally states it.
I just can't see how there's a subset-superset relationship, or how they can somehow be reconciled.
One way to see it is that a type has a given methods located in a given namespace in the nominal type system.
A nominal type system doesn't necessarily enforce semantics either.
It just enforces the location of a method definition.
Seen that way, because the relation is dual, one could indeed claim that a structural interface is a nominal interface where the name constraint is elided.
But just as in subtyping, one less constraint also means bigger set.
Of course if one were to decide that an object satisfying a nominal interface doesn't satisfy the structural interface obtained by ignoring the namespace, then I'd agree as well, these concepts would be disjoint.
I don't think they are though but I don't know of a language that ever mixed both either.
AFAIK Python [optional] type system supports both.
The nominal types are the "common" types, while the protocols [1] are structural. It's quite cool, actually :)
The additional naming constraint added to a structural interface would form a sort of namespace for methods.
I think in the comments below that someone likens this to tags in C++.