digitalmars.D.learn - Comparison operator overloading
- =?UTF-8?B?TcOhcmNpbw==?= Martins (16/16) Dec 06 2015 I am writing a generic numerical array struct, and I can't find a
- cym13 (4/22) Dec 06 2015 Don't use opCmp, all binary operators should be overriden using
- Dominikus Dittes Scherkl (11/14) Dec 07 2015 Why should we don't use opCmp() ?
- Mike Parker (12/24) Dec 07 2015 That chapter actually shows quite clearly in the table in the
- Dominikus Dittes Scherkl (5/18) Dec 07 2015 Hmm. But it works just fine! It overloads also the special
- Anonymous (10/14) Dec 07 2015 Those are deprecated:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (9/11) Dec 06 2015 What do those operations do? Are you thinking of a special meaning for
- =?UTF-8?B?TcOhcmNpbw==?= Martins (14/27) Dec 07 2015 Yes, each expression involving these arrays will almost always
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?
Dec 06 2015
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
Dec 06 2015
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.htmlWhy 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.
Dec 07 2015
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: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.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.htmlWhy should we don't use opCmp() ? I can't see any recommendation about this in the cited book. InOn 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
Dec 07 2015
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: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)?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
Dec 07 2015
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%20operatorsAnd 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.
Dec 07 2015
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
Dec 06 2015
On Monday, 7 December 2015 at 00:43:50 UTC, Ali Çehreli wrote:On 12/06/2015 06:41 AM, Márcio Martins wrote: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?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
Dec 07 2015