Jump to page: 1 2
Thread overview
Re: WAT: opCmp and opEquals woes
Jul 23, 2014
H. S. Teoh
Jul 23, 2014
H. S. Teoh
Jul 24, 2014
deadalnix
Jul 24, 2014
Daniel Gibson
Jul 25, 2014
Marc Schütz
Jul 23, 2014
John Colvin
Jul 23, 2014
H. S. Teoh
Re: opCmp and opEquals woes
Jul 24, 2014
Daniel Murphy
Jul 24, 2014
Daniel Murphy
Jul 24, 2014
Jonathan M Davis
Re: opCmp and opEquals woes
Jul 24, 2014
Daniel Murphy
Jul 24, 2014
Jacob Carlborg
July 23, 2014
On Wed, Jul 23, 2014 at 11:48:42AM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
> On 7/23/14, 9:45 AM, H. S. Teoh via Digitalmars-d wrote:
> >Why isn't "a==b" rewritten as "a.opCmp(b)==0"?? I'm pretty sure TDPL
> >says this is the case (unfortunately I'm at work so I can't check my
> >copy of TDPL).
> >
> >https://issues.dlang.org/show_bug.cgi?id=13179
> >
> >:-(
> 
> It's a good decision. There are types that are comparable for equality but not compared for ordering. -- Andrei

That's the wrong way round. I fully agree that we should not autogenerate opCmp if the user defines opEquals, since not all types comparable with equality are orderable.  However, surely all orderable types are equality-comparable! Therefore, if opCmp is defined but opEquals isn't, then we should autogenerate opEquals to be the same as a.opCmp(b)==0.


T

-- 
No! I'm not in denial!
July 23, 2014
On 7/23/14, 11:52 AM, H. S. Teoh via Digitalmars-d wrote:
> On Wed, Jul 23, 2014 at 11:48:42AM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
>> On 7/23/14, 9:45 AM, H. S. Teoh via Digitalmars-d wrote:
>>> Why isn't "a==b" rewritten as "a.opCmp(b)==0"?? I'm pretty sure TDPL
>>> says this is the case (unfortunately I'm at work so I can't check my
>>> copy of TDPL).
>>>
>>> https://issues.dlang.org/show_bug.cgi?id=13179
>>>
>>> :-(
>>
>> It's a good decision. There are types that are comparable for equality
>> but not compared for ordering. -- Andrei
>
> That's the wrong way round.

No.

> I fully agree that we should not
> autogenerate opCmp if the user defines opEquals, since not all types
> comparable with equality are orderable.  However, surely all orderable
> types are equality-comparable!

http://en.wikipedia.org/wiki/Lattice_(order)

> Therefore, if opCmp is defined but
> opEquals isn't, then we should autogenerate opEquals to be the same as
> a.opCmp(b)==0.

It's a sensible decision, but I'm not so sure.


Andrei

July 23, 2014
On Wednesday, 23 July 2014 at 18:53:57 UTC, H. S. Teoh via Digitalmars-d wrote:
> However, surely all orderable types are equality-comparable!

just because 2 objects don't have a defined ordering between them doesn't mean they are equal in a more general sense.

Yes it's a gotcha but I think it's a worthwhile one.
July 23, 2014
On Wed, Jul 23, 2014 at 02:35:03PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
> On 7/23/14, 11:52 AM, H. S. Teoh via Digitalmars-d wrote:
[...]
> >I fully agree that we should not autogenerate opCmp if the user defines opEquals, since not all types comparable with equality are orderable.  However, surely all orderable types are equality-comparable!
> 
> http://en.wikipedia.org/wiki/Lattice_(order)
[...]

And why should this be the default behaviour? The <, <=, >=, > operators imply linear ordering, not general partial order. If you really want to implement a non-linear partial ordering, you can always define both opCmp and opEquals. This should be the *non*-default case, since in the vast majority of cases, defining opCmp means you want a linear ordering. Linear ordering should be default, and partial ordering possible if the programmer explicitly asks for it (by implementing opEquals manually).


T

-- 
Winners never quit, quitters never win. But those who never quit AND never win are idiots.
July 23, 2014
On Wednesday, 23 July 2014 at 18:53:57 UTC, H. S. Teoh via Digitalmars-d wrote:
> That's the wrong way round. I fully agree that we should not
> autogenerate opCmp if the user defines opEquals, since not all types
> comparable with equality are orderable.  However, surely all orderable
> types are equality-comparable! Therefore, if opCmp is defined but
> opEquals isn't, then we should autogenerate opEquals to be the same as
> a.opCmp(b)==0.

You can define an order for sets/intervals without equality... For fuzzy numbers it gets even worse. You can define it such that a<b and b>a both are true...

July 23, 2014
On Wed, Jul 23, 2014 at 10:42:19PM +0000, via Digitalmars-d wrote:
> On Wednesday, 23 July 2014 at 18:53:57 UTC, H. S. Teoh via Digitalmars-d wrote:
> >That's the wrong way round. I fully agree that we should not autogenerate opCmp if the user defines opEquals, since not all types comparable with equality are orderable.  However, surely all orderable types are equality-comparable! Therefore, if opCmp is defined but opEquals isn't, then we should autogenerate opEquals to be the same as a.opCmp(b)==0.
> 
> You can define an order for sets/intervals without equality... For fuzzy numbers it gets even worse. You can define it such that a<b and b>a both are true...

(a<b && b>a) is true for ints.


T

-- 
All men are mortal. Socrates is mortal. Therefore all men are Socrates.
July 23, 2014
On 7/23/14, 3:39 PM, H. S. Teoh via Digitalmars-d wrote:
> On Wed, Jul 23, 2014 at 02:35:03PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
>> On 7/23/14, 11:52 AM, H. S. Teoh via Digitalmars-d wrote:
> [...]
>>> I fully agree that we should not autogenerate opCmp if the user
>>> defines opEquals, since not all types comparable with equality are
>>> orderable.  However, surely all orderable types are
>>> equality-comparable!
>>
>> http://en.wikipedia.org/wiki/Lattice_(order)
> [...]
>
> And why should this be the default behaviour? The <, <=, >=, > operators
> imply linear ordering, not general partial order. If you really want to
> implement a non-linear partial ordering, you can always define both
> opCmp and opEquals. This should be the *non*-default case, since in the
> vast majority of cases, defining opCmp means you want a linear ordering.
> Linear ordering should be default, and partial ordering possible if the
> programmer explicitly asks for it (by implementing opEquals manually).

I'm unconvinced. Most algorithms that need inequality don't need equality comparison; instead, they consider objects for which both !(a < b) && !(b < a) in the same "equivalence class" that doesn't assume they are actually equal.

Bottom line, inferring opEquals from opCmp seems fishy.


Andrei

July 24, 2014
On Wednesday, 23 July 2014 at 18:53:57 UTC, H. S. Teoh via Digitalmars-d wrote:
> On Wed, Jul 23, 2014 at 11:48:42AM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
>> On 7/23/14, 9:45 AM, H. S. Teoh via Digitalmars-d wrote:
>> >Why isn't "a==b" rewritten as "a.opCmp(b)==0"?? I'm pretty sure TDPL
>> >says this is the case (unfortunately I'm at work so I can't check my
>> >copy of TDPL).
>> >
>> >https://issues.dlang.org/show_bug.cgi?id=13179
>> >
>> >:-(
>> 
>> It's a good decision. There are types that are comparable for equality
>> but not compared for ordering. -- Andrei
>
> That's the wrong way round. I fully agree that we should not
> autogenerate opCmp if the user defines opEquals, since not all types
> comparable with equality are orderable.  However, surely all orderable
> types are equality-comparable! Therefore, if opCmp is defined but
> opEquals isn't, then we should autogenerate opEquals to be the same as
> a.opCmp(b)==0.

That would incur a silent performance hit. We should either force the programmer to define opEquals (even if they just make it return a.opCmp(b) == 0) or we should keep the normal, generated one.

The best option though would be to provide some way for the programmer to tell the compiler that they want to use the default one so that they still have to declare opEquals when they define opCmp (to make sure that the programmer didn't forget it), but they're still able to use the built-in one rather than writing it themselves. IIRC, C++11 has a way of doing that. Maybe we should add something similar.

- Jonathan M Davis
July 24, 2014
On Wednesday, 23 July 2014 at 23:52:01 UTC, Andrei Alexandrescu
wrote:
> On 7/23/14, 3:39 PM, H. S. Teoh via Digitalmars-d wrote:
>> On Wed, Jul 23, 2014 at 02:35:03PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
>>> On 7/23/14, 11:52 AM, H. S. Teoh via Digitalmars-d wrote:
>> [...]
>>>> I fully agree that we should not autogenerate opCmp if the user
>>>> defines opEquals, since not all types comparable with equality are
>>>> orderable.  However, surely all orderable types are
>>>> equality-comparable!
>>>
>>> http://en.wikipedia.org/wiki/Lattice_(order)
>> [...]
>>
>> And why should this be the default behaviour? The <, <=, >=, > operators
>> imply linear ordering, not general partial order. If you really want to
>> implement a non-linear partial ordering, you can always define both
>> opCmp and opEquals. This should be the *non*-default case, since in the
>> vast majority of cases, defining opCmp means you want a linear ordering.
>> Linear ordering should be default, and partial ordering possible if the
>> programmer explicitly asks for it (by implementing opEquals manually).
>
> I'm unconvinced. Most algorithms that need inequality don't need equality comparison; instead, they consider objects for which both !(a < b) && !(b < a) in the same "equivalence class" that doesn't assume they are actually equal.
>
> Bottom line, inferring opEquals from opCmp seems fishy.
>
>
> Andrei

NaN is a good example.
July 24, 2014
On Wednesday, 23 July 2014 at 23:02:48 UTC, H. S. Teoh via Digitalmars-d wrote:
>> fuzzy numbers it gets even worse. You can define it such that a<b and
>> b>a both are true...
>
> (a<b && b>a) is true for ints.

That was a typo, for fuzzy numbers you can define less than such that a<b and b>a both are true.

Fuzzy(-1,0,1) vs Fuzzy(-2,0,2)


« First   ‹ Prev
1 2