July 26, 2014
On 26 July 2014 13:33, Manu <turkeyman@gmail.com> wrote:

> On 26 July 2014 06:38, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On 7/25/2014 4:10 AM, Regan Heath wrote:
>>
>>> Sure, Andrei makes a valid point .. for a minority of cases.  The
>>> majority case
>>> will be that opEquals and opCmp==0 will agree.  In those minority cases
>>> where
>>> they are intended to disagree the user will have intentionally defined
>>> both, to
>>> be different.  I cannot think of any case where a user will intend for
>>> these to
>>> be different, then not define both to ensure it.
>>>
>>
>> You've agreed with my point, then, that autogenerating opEquals as memberwise equality (not opCmp==0) if one is not supplied will be correct unless the user code is already broken.
>>
>
> No, because there's no obvious reason to define opEquals if you do define opCmp, and the opEq
>

Oops, sorry! Hit the send hotkey >_<

No, because there's no obvious reason to define opEquals if you do define
opCmp and the opEquals would be the same.
It seems to me, at face value, that opCmp is for full range of comparisons,
and opEquals is for unordered types. Surely this is a reasonable conclusion
to make?

I don't see how you can say that a compiler generated opEquals in the
presence of a user opCmp can reliably be correct.
It may be correct, if you're lucky, and that's the best offer you'll get.
opCmp==0 however is practically certain to be correct, since <= and >= are
required to work... and the api embodies the concept of equality, it would
be very hard to write an implementation where equal was broken, but
<,<=,>=,> all worked.


July 26, 2014
On 26 July 2014 06:35, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 7/25/2014 5:10 AM, Ary Borenszweig wrote:
>
>> Not at all.
>>
>> If you have a type that has partial ordering (only cares about opCmp, not
>> about
>> opEquals), but still keeps the default opEquals, then this would silently
>> break
>> someone's code by changing their opEquals semantic.
>>
>> THIS is the breaking change.
>>
>
> Yes. A subtle but extremely important point. Comparison and Equality are fundamentally different operations. Defining opEquals to be the equivalent of opCmp==0 is utterly breaking that.
>

Perhaps the problem here is that there is a missing concept.
There is equality and equivalence, and only equivalence is expressed in D
(ie, the one that is relevant among the suite of comparison operations).

Would you argue that == and != are unrelated, distinct and separate
operations from <,<=,>=,>, and they should never be used in conjunction, or
assumed to be related?
I think any reasonable person will assume that the suite of comparisons are
related operations.
So perhaps === is missing, and that's what should be used for AA's, and
also the thing that actually matches the compiler's generated opEquals...?


July 26, 2014
On 7/25/2014 8:41 PM, Manu via Digitalmars-d wrote:
> No, because there's no obvious reason to define opEquals if you do define opCmp
> and the opEquals would be the same.
> It seems to me, at face value, that opCmp is for full range of comparisons, and
> opEquals is for unordered types. Surely this is a reasonable conclusion to make?
>
> I don't see how you can say that a compiler generated opEquals in the presence
> of a user opCmp can reliably be correct.

You cannot say that opCmp can reliably be used for ==. Andrei provided a more specific example.


> It may be correct, if you're lucky, and that's the best offer you'll get.
> opCmp==0 however is practically certain to be correct, since <= and >= are
> required to work... and the api embodies the concept of equality, it would be
> very hard to write an implementation where equal was broken, but <,<=,>=,> all
> worked.

At this point, it's obvious we are going around in a circle. You ask the same questions over and over, and I answer them over and over. If you don't want to accept that equality and comparison are fundamentally different operations, I can only repeat saying the same things.
July 26, 2014
On 7/25/2014 8:47 PM, Manu via Digitalmars-d wrote:
> Would you argue that == and != are unrelated, distinct and separate operations
> from <,<=,>=,>, and they should never be used in conjunction, or assumed to be
> related?
> I think any reasonable person will assume that the suite of comparisons are
> related operations.

Any reasonable person would assume that floating point (a+b)+c == a+(b+c) but it does not work that way.

Andrei gave a specific example in this thread.

There is a reason that both opEquals and opCmp defined in the language, and that opEquals is for == and !=, and opCmp is for < <= > >=.

Conflating them together is a mistake.
July 26, 2014
On Fri, Jul 25, 2014 at 06:44:36PM -0700, Andrei Alexandrescu via Digitalmars-d wrote: [...]
> I think we should remove the breakage introduced by requiring opEquals if opCmp is defined. It breaks good code for no good reason.
[...]

Yes, we should revert that.


T

-- 
If lightning were to ever strike an orchestra, it'd always hit the conductor first.
July 26, 2014
On Fri, Jul 25, 2014 at 09:22:26PM -0700, Walter Bright via Digitalmars-d wrote:
> On 7/25/2014 8:41 PM, Manu via Digitalmars-d wrote:
[...]
> >It may be correct, if you're lucky, and that's the best offer you'll get.  opCmp==0 however is practically certain to be correct, since <= and >= are required to work... and the api embodies the concept of equality, it would be very hard to write an implementation where equal was broken, but <,<=,>=,> all worked.
> 
> At this point, it's obvious we are going around in a circle. You ask the same questions over and over, and I answer them over and over. If you don't want to accept that equality and comparison are fundamentally different operations, I can only repeat saying the same things.

Well, we can argue about this until the cows come home, but at least for the present regression being addressed, I think Jonathan's fix is the best option (or the least of all evils): revert the compiler change that causes a compile error when the user defines opCmp but not opEquals.

In the meantime, I think much of the confusion comes from the current documentation not be adequately clear about the reasoning behind having opCmp and opEquals, so it's too easy to get the wrong impression that defining opCmp is enough to make things work, or to have a fuzzy inaccurate understanding for how opCmp interacts with opEquals, and when/why to use each. I think a documentation PR is in order.


T

-- 
I don't trust computers, I've spent too long programming to think that they can get anything right. -- James Miller
July 26, 2014
On Sat, Jul 26, 2014 at 01:47:20PM +1000, Manu via Digitalmars-d wrote:
> On 26 July 2014 06:35, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
[...]
> So perhaps === is missing, and that's what should be used for AA's, and also the thing that actually matches the compiler's generated opEquals...?

No! Please don't. '===' is one of the worst WATs of modern day language design, and only leads to confusion and pain. And endless bugs from people not understanding (and not bothering nor wanting to understand) what the difference is. One only has to look at the insanity surrounding === in Javascript and PHP for ample reasons why this is a bad idea. Please don't dainbramage D by introducing this nastiness.


T

-- 
Старый друг лучше новых двух.
July 26, 2014
On 7/25/2014 11:05 PM, H. S. Teoh via Digitalmars-d wrote:
> Well, we can argue about this until the cows come home, but at least for
> the present regression being addressed, I think Jonathan's fix is the
> best option (or the least of all evils): revert the compiler change that
> causes a compile error when the user defines opCmp but not opEquals.

His fix is also what I proposed - we both came to the same conclusion.


> In the meantime, I think much of the confusion comes from the current
> documentation not be adequately clear about the reasoning behind having
> opCmp and opEquals, so it's too easy to get the wrong impression that
> defining opCmp is enough to make things work, or to have a fuzzy
> inaccurate understanding for how opCmp interacts with opEquals, and
> when/why to use each. I think a documentation PR is in order.

I welcome a PR from you on this!

July 26, 2014
On 7/25/2014 10:40 PM, H. S. Teoh via Digitalmars-d wrote:
> On Fri, Jul 25, 2014 at 06:44:36PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
>> I think we should remove the breakage introduced by requiring opEquals
>> if opCmp is defined. It breaks good code for no good reason.
> Yes, we should revert that.


https://github.com/D-Programming-Language/dmd/pull/3813
July 26, 2014
On 26 July 2014 16:13, H. S. Teoh via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Sat, Jul 26, 2014 at 01:47:20PM +1000, Manu via Digitalmars-d wrote:
> > On 26 July 2014 06:35, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
> [...]
> > So perhaps === is missing, and that's what should be used for AA's, and also the thing that actually matches the compiler's generated opEquals...?
>
> No! Please don't. '===' is one of the worst WATs of modern day language design, and only leads to confusion and pain. And endless bugs from people not understanding (and not bothering nor wanting to understand) what the difference is. One only has to look at the insanity surrounding === in Javascript and PHP for ample reasons why this is a bad idea. Please don't dainbramage D by introducing this nastiness.
>

It's okay, I hate it too.
But I equally can't abide == meaning something different than <, <=, etc.
That's insane.
Like I said, I'm just absolutely astonished that people think the situation
in your OP is okay, especially when the solution is so obvious.