|Posted by Oleg B||PermalinkReply|
For example we can imagine struct Version.
Version can be old or new and can be 'badly formed' or 'undefined' or other 'not comparible' ('uncompatible') state.
Logically we can compare versions, but what must return `opCmp` if one of versions has 'not comparible' state?
I think strategy of throwing exception in `opCmp` is bad because some types can be 'not comparible' not because they is `null` or `undefined`, 'not comparible' can be two objects in some working states.
If we add `opEquals` we can check 'not comparible' and return `false`, but operators `a <= b` and `a >= b` not expands under the hood as `a < b || a == b`, they only call `opCmp` and if it returns 0 considered arguments are equals.
Rewrite `a <= b` as `a < b || a == b` is not intuitive and can get bugs if new user will use code (or old user forgot about this). Checking 'not comparible' state before `a <= b` is not intuitive too.
`opBinary` can't overload comparison.
We have same type of problem if wrap simple `double` into struct and try overload comparison (double.nan has own behavior).
Problem can be solved if we add new `opCmpEx` into language spec that return 4 states: more, less, equal, not equal.
Or if we allow `opBinary` overload comparisons.
May be I don't understand something important and this problem is not exists?
May be in cases where can be 'not comparible' state we should not use overload of comparison operators? But it looks like overloading conception isn't completed and can be improved.