If someone encodes "Meter" and "Yard", your type system wouldn't provide any errors if a meter is used in a yard calculation or vice versa. If someone encodes "RGBColor" and "LinearRGBColor", both structs with 3 floats, your type system wouldn't provide any errors if a LinearRGB color is passed into an RGB calculation. You also wouldn't have any error if you accidentally passed a Vertex3 (again, struct of 3 floats) into your RGB calculation.
Preferred by me, I'm not trying to speak for anyone else. In fact I'd say it's a somewhat minority opinion.
When talking about types like `Meter` and `Yard` in a structural system, the "type" of the data is also data. In a nominal system that data is encoded in the type system, but that's not the only place it can be. For example, if I asked you how far the nearest gas station is, you wouldn't respond with "10", but rather "10 minutes", or "10 kilometres", etc. Both the value and unit of measurement are relevant data, and thus both of those would be part of the structural type as well.
{ unit: yard, value: 20 }
This is real, concrete data that you can see all at once. You can feed it into different functions, create aliases for it (unlike objects where you'd need to make snapshots or copies when they might change), compare it with other data to check equality, transmit it across networks, and work with it easily in other programming languages since they all understand basic types. When you stick with this kind of data, you can use general-purpose functions that work on any data rather than being locked into specific methods tied to particular types or interfaces - methods that won't exist when you move to different languages or systems.
In a nominal system you might end up with a generic Measurement<T> type that contains the unit inside, which can help with code reuse but it's not at the same level as pure data.
Structural types does not preclude having some names that prevent mix-ups. Haskell’s `data` keyword doesn’t let you confuse structurally-identical things.
> If someone encodes "RGBColor" and "LinearRGBColor", both structs with 3 floats, your type system wouldn't provide any errors if a LinearRGB color is passed into an RGB calculation.
It 100% would, unless you were silly enough to use a bare tuple to do it. Again, defining a type with `data` in Haskell wouldn’t get confused.
> Structural types does not preclude having some names that prevent mix-ups. Haskell’s `data` keyword doesn’t let you confuse structurally-identical things.
Haskell doesn't let you confuse structurally-indentical things because it is nominal, not structural.
Also, preferred by who?