Bug 7430 – opCmp doesn't support unordered value comparison.

Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-02-03T08:55:39Z
Last change time
2020-08-14T12:43:40Z
Assigned to
No Owner
Creator
Gor Gyolchanyan

Comments

Comment #0 by gor — 2012-02-03T08:55:39Z
I have a structure, that represents an element of a range. Let's say a character. That character can be invalid. I need all comparison operators to return false of at least one of the operands is invalid. with opCmp, the expression a @ b is rewritten as a.opCmp(B) @ 0, which doesn't allow me to define such a logic. A rewrite of opCmp to test for exact values -1, 0 and 1 would solve the problem, because any value beyond the expected three would cause all comparisons to fail.
Comment #1 by issues.dlang — 2012-02-03T10:41:55Z
So, what are you really asking here? That opCmp in general require that the result be -1, 0, or 1 or it will return false? That's not going to work. Too much code relies on the current semantics of opCmp, and it's often _desirable_ that it not matter whether the values are exactly -1 or 1 but rather just require that they be less than or greater than 0 as they are now. Also, making it so that both <, <=, >=, and > were all false (or all true) would thoroughly break boolean logic and could have all kinds of nasty consequences - especially in generic code. One of the major reasons of creating opCmp instead of having operator<, operator<=, etc. is so that those operations be consistent, which your suggestion violates completely. Why can't you just use a custom comparison function for whatever comparisons you're trying to do? Not to mention, I believe that the common way to handle the use case of an invalid element is to throw. That's what Phobos' UTF stuff does. What are you really asking here? That opCmp always test that its return value is -1, 0, or 1? Because if that's what you're really asking here, then that's not going to happen. It would break a lot of existing opCmp functions and quite purposely is not how opCmp works.
Comment #2 by gor — 2012-02-03T11:52:59Z
What i want is a floating-point style comparisons, where there's a NaN, which fits perfectly in the comparison operators and really does return false in all cases. (In reply to comment #1) > So, what are you really asking here? That opCmp in general require that the > result be -1, 0, or 1 or it will return false? That's not going to work. Too > much code relies on the current semantics of opCmp, and it's often _desirable_ > that it not matter whether the values are exactly -1 or 1 but rather just > require that they be less than or greater than 0 as they are now. > > Also, making it so that both <, <=, >=, and > were all false (or all true) > would thoroughly break boolean logic and could have all kinds of nasty > consequences - especially in generic code. One of the major reasons of creating > opCmp instead of having operator<, operator<=, etc. is so that those operations > be consistent, which your suggestion violates completely. > > Why can't you just use a custom comparison function for whatever comparisons > you're trying to do? > > Not to mention, I believe that the common way to handle the use case of an > invalid element is to throw. That's what Phobos' UTF stuff does. > > What are you really asking here? That opCmp always test that its return value > is -1, 0, or 1? Because if that's what you're really asking here, then that's > not going to happen. It would break a lot of existing opCmp functions and quite > purposely is not how opCmp works.
Comment #3 by simen.kjaras — 2012-02-03T12:55:20Z
"a @ b is rewritten as a.opCmp(B) @ 0" And there you have it. What return type and value for opCmp fulfills this requirement? I'll tell you: float and nan. Example: struct Foo { float opCmp(Foo other) { return float.nan; } } unittest { assert( !(Foo() < Foo() )); assert( !(Foo() <= Foo()) ); assert( !(Foo() > Foo() )); assert( !(Foo() >= Foo() )); }
Comment #4 by simen.kjaras — 2012-02-03T12:57:09Z
Oh, there is one problem - opEquals. If it returns true for ==, it returns false for !=.
Comment #5 by code — 2012-02-03T13:56:07Z
Probably making opCmp templated would make sense, wouldn't work for classes though. Adding more return values is a bad idea. It is already difficult enough to write an efficient opCmp with three cases.
Comment #6 by simen.kjaras — 2020-08-14T12:43:40Z
As described in comment 4, opCmp *does* support unordered value comparison.