Here's a counter example. I've seen numerous Java projects define a nominal predicate type, for example com.google.common.base.Predicate. None of these are interoperable without writing adapter code. ML and Haskell would essentially use a structural type:
t -> bool
Much simpler and easier to consume.
How would you assign a nominal type to the result of a SQL query?
So there are arguments on both sides. My point was that structural types can always easily be turned into a nominal type, but not the other way around. Therefore they should be the default.
The :: syntax minimizes the pain, but the fact you have to do it at all is still irritating, and IIUC it incurs a small runtime cost due to the intermediate object that's generated to convert between the two interfaces. I recently cleared out some of these intermediaries in a hot area of code and got a small but significant performance boost.
For example, although Java method definitions are essentially defined in terms of tuples, function classes and objects in Java are all entirely nominal.
How would you assign a nominal type to the result of a SQL query?
So there are arguments on both sides. My point was that structural types can always easily be turned into a nominal type, but not the other way around. Therefore they should be the default.