Earlier quoted context omitted.
That's something I have been pondering for some time. I believe it's a false dichotomy. My thought is still that structural supersedes nominal . A nominal interface is just another constraint added to the list of constraints of an underlying structural interface?
Nominal interfaces can still be useful though, as they convey a stronger sense of intent than structural. For example, java.io.Serializable is a completely empty interface that classes “implement” to signal that they are safe to serialize. As a structural interface, it’d be useless.
template concept serializable = requires { typename T::is_serializable_tag; };
void serialize(serializable auto x) {...};
struct NotSerializableClass { ... };
struct SerializableClass { using is_serializable_tag = void; ... };
serialize(NotSerializableClass{}); // error
serialize(SerializableClass{}); // all good
In C++, specializing a trait is also an option. So, while nominal and structural interfaces are not the same, sometimes the lines are blurred.