Re: Comparison operator overloading
On Monday, 7 December 2015 at 11:49:51 UTC, Dominikus Dittes Scherkl wrote: On Sunday, 6 December 2015 at 15:01:08 UTC, cym13 wrote: Don't use opCmp, all binary operators should be overriden using opBinary. For more information I recommend this page http://ddili.org/ders/d.en/operator_overloading.html Why should we don't use opCmp() ? I can't see any recommendation about this in the cited book. In That chapter actually shows quite clearly in the table in the Binary Operators section that opCmp is used for <, <=, >, and >=, which is also exactly what the language reference says. There's also another section further down the page that covers opCmp explicitly. I have no idea what cym13 is looking at. On the other hand the chapter also states that opCmp() should always return "int" - which is a bad idea if you e.g. want to provide a "NaN" value in your type. For that "float" is a much better return type for opCmp(). So you should not weight in gold for the words in the cited book, I think. This is not something the author is just making up. opCmp is expected to return int because of the way the compiler rewrites comparison expressions. See the table at [1]. It wouldn't do to return NaN from opCmp. [1] http://dlang.org/spec/operatoroverloading.html#compare
Re: Comparison operator overloading
On Monday, 7 December 2015 at 13:31:52 UTC, Mike Parker wrote: On Monday, 7 December 2015 at 11:49:51 UTC, Dominikus Dittes Scherkl wrote: On the other hand the chapter also states that opCmp() should always return "int" - which is a bad idea if you e.g. want to provide a "NaN" value in your type. For that "float" is a much better return type for opCmp(). So you should not weight in gold for the words in the cited book, I think. This is not something the author is just making up. opCmp is expected to return int because of the way the compiler rewrites comparison expressions. See the table at [1]. It wouldn't do to return NaN from opCmp. [1] http://dlang.org/spec/operatoroverloading.html#compare Hmm. But it works just fine! It overloads also the special floatingpoint operators <> !<> !<= and so on. And how else could I handle a self-defined type that happens to have a NaN value (like my save-signed intergers do)?
Re: Comparison operator overloading
On Sunday, 6 December 2015 at 15:01:08 UTC, cym13 wrote: Don't use opCmp, all binary operators should be overriden using opBinary. For more information I recommend this page http://ddili.org/ders/d.en/operator_overloading.html Why should we don't use opCmp() ? I can't see any recommendation about this in the cited book. In the chapter is only mentioned that opSliceAssign() and the like are discouraged - but without stating a reason or a replacement. On the other hand the chapter also states that opCmp() should always return "int" - which is a bad idea if you e.g. want to provide a "NaN" value in your type. For that "float" is a much better return type for opCmp(). So you should not weight in gold for the words in the cited book, I think.
Re: Comparison operator overloading
On Monday, 7 December 2015 at 00:43:50 UTC, Ali Çehreli wrote: On 12/06/2015 06:41 AM, Márcio Martins wrote: > auto m = (a > b) * a + 15; > auto c = a.choose(a > b)^^2; What do those operations do? Are you thinking of a special meaning for '>', perhaps common in numerical computations, which I'm not familiar with? If I understand correctly, 'a > b' in choose(a > b) is the condition to pick elements from a. If so, it is better to pass a lambda in such cases: a.choose!((i, j) => i > j); However, as I understand it, the whole expression is supposed to generate an array-like result. Is that right? :) Ali Yes, each expression involving these arrays will almost always also result in another array, sometimes with a different type. For example, a > b returns an array of bools whose elements are the the result of the condition applied to each individual element of a and b. This makes writing numerical code very easy, and with fewer bugs, because it's all very succinct and each operation is very simple and well defined. My initial intuition was that opBinary and opBinaryRight would be used if suitable and opCmp/opEquals would be the fallback. That didn't seem to work, so I quickly realised this is not possible in D. I'm wondering if it is an oversight in the language design or there are real reasons for this limitation?
Re: Comparison operator overloading
On Monday, 7 December 2015 at 17:18:20 UTC, Dominikus Dittes Scherkl wrote: Hmm. But it works just fine! It overloads also the special floatingpoint operators <> !<> !<= and so on. Those are deprecated: http://dlang.org/deprecate.html#Floating%20point%20NCEG%20operators And how else could I handle a self-defined type that happens to have a NaN value (like my save-signed intergers do)? Something like this: http://dlang.org/phobos/std_math.html#isNaN Or maybe this: http://dlang.org/phobos/std_typecons.html#Nullable Obviously, you'd want to do what makes sense for your type and its semantics. That probably doesn't involve using NCEG operators.
Comparison operator overloading
I am writing a generic numerical array struct, and I can't find a way to do element-wise comparison operators. What I had envisioned was something like the following, assuming a, b, c and m are array-like, and all operations return arrays. auto m = (a > b) * a + 15; auto c = a.choose(a > b)^^2; However, it seems this can't be achieved at the moment, as far as I can tell. The rewriting of a >= b to a.opCmp(b) >= 0 seems limiting in the sense that it assumes scalar-like operands and semantics, which is surprising, and goes against the awesome flexibility of the remaining operator overloads. Tried to look around, but according to google, the only reference I have seen to this was someone with a similar question in 2004, which is surprising to say the least. I suppose either I am missing something really obvious, or I am out of luck?
Re: Comparison operator overloading
On Sunday, 6 December 2015 at 14:41:01 UTC, Márcio Martins wrote: I am writing a generic numerical array struct, and I can't find a way to do element-wise comparison operators. What I had envisioned was something like the following, assuming a, b, c and m are array-like, and all operations return arrays. auto m = (a > b) * a + 15; auto c = a.choose(a > b)^^2; However, it seems this can't be achieved at the moment, as far as I can tell. The rewriting of a >= b to a.opCmp(b) >= 0 seems limiting in the sense that it assumes scalar-like operands and semantics, which is surprising, and goes against the awesome flexibility of the remaining operator overloads. Tried to look around, but according to google, the only reference I have seen to this was someone with a similar question in 2004, which is surprising to say the least. I suppose either I am missing something really obvious, or I am out of luck? Don't use opCmp, all binary operators should be overriden using opBinary. For more information I recommend this page http://ddili.org/ders/d.en/operator_overloading.html
Re: Comparison operator overloading
On 12/06/2015 06:41 AM, Márcio Martins wrote: > auto m = (a > b) * a + 15; > auto c = a.choose(a > b)^^2; What do those operations do? Are you thinking of a special meaning for '>', perhaps common in numerical computations, which I'm not familiar with? If I understand correctly, 'a > b' in choose(a > b) is the condition to pick elements from a. If so, it is better to pass a lambda in such cases: a.choose!((i, j) => i > j); However, as I understand it, the whole expression is supposed to generate an array-like result. Is that right? :) Ali