May 14, 2019
On 5/14/19 1:24 AM, Seb wrote:
> On Wednesday, 15 May 2019 at 00:08:10 UTC, Andrei Alexandrescu wrote:
>> On 5/14/19 12:36 AM, Seb wrote:
>>> On Tuesday, 14 May 2019 at 21:06:05 UTC, Mike Franklin wrote:
>>>> On Tuesday, 14 May 2019 at 20:36:08 UTC, Eduard Staniloiu wrote:
>>>>
>>>>> Should `opCmp` return a float?
>>>>>
>>>>> The reason: when we attempt to compare two types that aren't comparable (an unordered relationship) we can return float.NaN. Thus we can differentiate between a valid -1, 0, 1 and an invalid float.NaN comparison.
>>>>
>>>> Seems like a job for an enum, not a float or an integer.
>>>>
>>>> Mike
>>>
>>> +1 for enum. As far as I can see you only have four actual states:
>>>
>>> lower, equal, higher, nonComparable
>>
>> This won't work because the result of opCmp is compared against zero. Using a floating point number is likely to be more efficient.
> 
> A DIP should cite real evidence/data though.

I'm not sure I understand. I wouldn't know how to make an enum even work, let alone compare against that solution. I'd be in your debt if you showed how.

> Also, note that all other cases except comparing against NaN require more instructions with a floating point number:
> 
> https://d.godbolt.org/z/lwzBVn

Thanks. Looks like that's the price if we want to support unordered objects.
May 15, 2019
On Wednesday, 15 May 2019 at 00:32:32 UTC, Andrei Alexandrescu wrote:

>> Please consider the fact that some microcontrollers don't have an FPU.  Some may have a software floating point implementation but consider the cost in flash memory consumption and performance implementing such a thing in software.  It seems excessive.
>
> Writing D code assuming float comparison is prohibitively expensive seems an .

Not sure if that was an incomplete thought or not, but it doesn't seem like the right attitude for a systems programming language.


May 14, 2019
On 5/14/19 1:37 AM, Mike Franklin wrote:
> On Wednesday, 15 May 2019 at 00:32:32 UTC, Andrei Alexandrescu wrote:
> 
>>> Please consider the fact that some microcontrollers don't have an FPU.  Some may have a software floating point implementation but consider the cost in flash memory consumption and performance implementing such a thing in software.  It seems excessive.
>>
>> Writing D code assuming float comparison is prohibitively expensive seems an .
> 
> Not sure if that was an incomplete thought or not, but it doesn't seem like the right attitude for a systems programming language.

... anachronistic thing to do.
May 14, 2019
On 5/14/19 1:32 AM, Adam D. Ruppe wrote:
> On Wednesday, 15 May 2019 at 00:19:05 UTC, Andrei Alexandrescu wrote:
>> I repeat myself: this won't work.
>>
>> Recall that a < b is lowered into a.opCmp(b) < 0. So we have a comparison against the literal 0.
> 
> We could just as well change the definition of the lowering to
> 
> a.opCmp(b) == ComparisonResult.lessThan
> 
> 
> I understand the generated instructions would be slightly different and that might be relevant, but if we're talking about changing things, no need to arbitrarily draw the line like that.

The DIP does not set out to change the semantics of opCmp.

At a larger level I'm fascinated by our community's penchant to work on small problems. Comparisons in D work just fine, thank you very much, yet here we are calmly setting up the trench warfare. Must be an enum, must change opCmp, must do anything and everything as long as it's different from what we have. And we carefully pick up the least generous topics, too. In our search for water, we aren't happy until we find the driest patch of sand to drill into, while carefully avoiding the generous marshes.
May 15, 2019
On Wednesday, 15 May 2019 at 00:37:25 UTC, Andrei Alexandrescu wrote:
> Thanks. Looks like that's the price if we want to support unordered objects.

But DO we want to support unordered objects?
May 14, 2019
On 5/14/19 1:52 AM, Adam D. Ruppe wrote:
> On Wednesday, 15 May 2019 at 00:37:25 UTC, Andrei Alexandrescu wrote:
>> Thanks. Looks like that's the price if we want to support unordered objects.
> 
> But DO we want to support unordered objects?

In the rather general context of classes, it would be quite desirable.

The nice thing is if we opt for a statically-checked solution the user will be able to make a decision on the signature of opCmp in their base class, and then go with it. Different hierarchies may even support different flavors of comparisons.
May 15, 2019
On Wednesday, 15 May 2019 at 00:37:25 UTC, Andrei Alexandrescu wrote:
> On 5/14/19 1:24 AM, Seb wrote:
>> On Wednesday, 15 May 2019 at 00:08:10 UTC, Andrei Alexandrescu wrote:
>>> On 5/14/19 12:36 AM, Seb wrote:
>>>> On Tuesday, 14 May 2019 at 21:06:05 UTC, Mike Franklin wrote:
>>>>> On Tuesday, 14 May 2019 at 20:36:08 UTC, Eduard Staniloiu wrote:
>>>>>
>>>>>> Should `opCmp` return a float?
>>>>>>
>>>>>> The reason: when we attempt to compare two types that aren't comparable (an unordered relationship) we can return float.NaN. Thus we can differentiate between a valid -1, 0, 1 and an invalid float.NaN comparison.
>>>>>
>>>>> Seems like a job for an enum, not a float or an integer.
>>>>>
>>>>> Mike
>>>>
>>>> +1 for enum. As far as I can see you only have four actual states:
>>>>
>>>> lower, equal, higher, nonComparable
>>>
>>> This won't work because the result of opCmp is compared against zero. Using a floating point number is likely to be more efficient.
>> 
>> A DIP should cite real evidence/data though.
>
> I'm not sure I understand. I wouldn't know how to make an enum even work, let alone compare against that solution. I'd be in your debt if you showed how.

Well, you already plan to change the compiler, so changing it to create a different opCmp lowering when it sees this special enum wouldn't be so hard, no?

i.e. if both opCmps return a special CompEnum, do sth. like this:

a < b => a.opCmp(b) == lowerCmp
...


There's no price to pay this way.
May 15, 2019
On Wednesday, 15 May 2019 at 00:54:20 UTC, Andrei Alexandrescu wrote:
> The nice thing is if we opt for a statically-checked solution the user will be able to make a decision on the signature of opCmp in their base class, and then go with it. Different hierarchies may even support different flavors of comparisons.

Yes, I agree with this.

I think the opCmp discussion should be moot, as a ProtoObject should not be comparable anyway; it'd simply be a compile error to try. Just like with trying to call any other method on it, you need to explicitly cast it to some interface you've defined first.
May 14, 2019
On 5/14/19 1:57 AM, Seb wrote:
> Well, you already plan to change the compiler, so changing it to create a different opCmp lowering when it sees this special enum wouldn't be so hard, no?

The DIP's charter does not include modifying opCmp.

> i.e. if both opCmps return a special CompEnum, do sth. like this:
> 
> a < b => a.opCmp(b) == lowerCmp
> ...
> 
> 
> There's no price to pay this way.

Well there would be in some instances. People often implement comparisons as a - b currently, where a and b are int expressions. That would need to become...

return a < b ? lowerCmp : a > b ? upperCmp : equivCmp;

That's definitely liable to be worse for those cases.

Overall: I dream of a D landscape whereby this is enough of a problem to deserve discussion, a DIP, review, and implementation. As things are there are sufficient things to discuss and improve in D to make this exchange ironic.
May 15, 2019
So, going back to where the int/float/enum tangent started....

On Tuesday, 14 May 2019 at 20:36:08 UTC, Eduard Staniloiu wrote:
> interface Ordered(T)
> {
>     int opCmp(scope const T rhs);
> }
>
> Since we are here, I want to raise another question:
> Should `opCmp` return a float?


We'd then have two interfaces: Ordered!T, which returns the int, and then PartiallyOrdered!T that can return the float. You pick which one works best for your particular class.