www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - why are opCmp and opEquals not pure.

reply Stefan Koch <uplink.coder googlemail.com> writes:
Hi,
is there any reason why opCmp and opEquals are not pure ?
I would argue it is very counter-intuitive to mutate any state 
when comparing objects.

opCmp and opEquals not being annotated pure is a major problem 
for me in writing ctfe-able code.

since any call to Object.opEquals need to be warped in another 
function to be able to cast the Function pure.
Sep 17 2015
next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Thu, Sep 17, 2015 at 06:37:04PM +0000, Stefan Koch via Digitalmars-d wrote:
 Hi,
 is there any reason why opCmp and opEquals are not pure ?
 I would argue it is very counter-intuitive to mutate any state when
 comparing objects.
[...] The way I understand it, this is a historical accident: opCmp and opEquals date back to the days before the const system was introduced to D, so they were never originally annotated. When the const system was introduced, a good amount of code is already using opCmp and opEquals, and some of them may mutate state (e.g., cache the result of previous comparisons in the object if the comparison operation is expensive), so adding the annotations would break existing code. At the time, a lot of the affected code was in Phobos, where there was a giant tangle of dependencies where changing the const annotation on a single function would percolate to almost half of the entire Phobos (if not more), breaking many other seemingly-unrelated things (and introducing potential for breakage of user code that use those things), so it was difficult to make the transition. Since that time, there has been talk of removing opCmp and opEquals from Object altogether, but so far we haven't managed to do this yet. T -- Acid falls with the rain; with love comes the pain.
Sep 17 2015
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 17 September 2015 at 19:30:09 UTC, H. S. Teoh wrote:
 On Thu, Sep 17, 2015 at 06:37:04PM +0000, Stefan Koch via 
 Digitalmars-d wrote:
 Hi,
 is there any reason why opCmp and opEquals are not pure ?
 I would argue it is very counter-intuitive to mutate any state 
 when
 comparing objects.
[...] The way I understand it, this is a historical accident: opCmp and opEquals date back to the days before the const system was introduced to D, so they were never originally annotated. When the const system was introduced, a good amount of code is already using opCmp and opEquals, and some of them may mutate state (e.g., cache the result of previous comparisons in the object if the comparison operation is expensive), so adding the annotations would break existing code. At the time, a lot of the affected code was in Phobos, where there was a giant tangle of dependencies where changing the const annotation on a single function would percolate to almost half of the entire Phobos (if not more), breaking many other seemingly-unrelated things (and introducing potential for breakage of user code that use those things), so it was difficult to make the transition. Since that time, there has been talk of removing opCmp and opEquals from Object altogether, but so far we haven't managed to do this yet.
It's not just a question of existing code. It can be perfectly legitimate to cache data or even to have to talk to stuff outside your program (e.g. in a database) to check for equality, even if that's not what the vast majority of programs should be doing. So, requiring pure, const, safe, or any attribute is overly restrictive, particularly considering that D is supposed to be a systems language. At the same time, if we don't have those attributes on the virtual functions on Object, then folks that do want to use those attributes are screwed (e.g. using == with const class objects only works because of a hack in druntime which casts away const and risks incorrect behavior). And that's why it was decided that we really needed to remove them from Object and just leave it up to the derived classes to declare them and choose what attributes they would use: https://issues.dlang.org/show_bug.cgi?id=9769 https://issues.dlang.org/show_bug.cgi?id=9770 https://issues.dlang.org/show_bug.cgi?id=9771 https://issues.dlang.org/show_bug.cgi?id=9772 Unfortunately, there are a number of technical issues in doing so from compiler bugs to changes that need to be made in druntime (e.g. changing the built-in AA implementation), and so while some work has been done towards that goal, we have yet to get there. And until we do, we're always going to have attribute problems with any of the virtual functions on Object. - Jonathan M Davis
Sep 17 2015
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/17/2015 08:37 PM, Stefan Koch wrote:
 Hi,
 is there any reason why opCmp and opEquals are not pure ?
Not all reasonable implementation are. Arguably, the methods shouldn't even be on Object.
 I would argue it is very counter-intuitive to mutate any state when
 comparing objects.
 ...
Not if it is done to improve performance, but not visible semantics.
 opCmp and opEquals not being annotated pure is a major problem for me in
 writing ctfe-able code.

 since any call to Object.opEquals need to be warped in another function
 to be able to cast the Function pure.
I don't get this point. You don't need any annotations to write ctfe-able code. Also, I think there were some efforts to make a template out of core.object.opEquals, in order to preserve the attributes. (Such that, as long as one doesn't work with plain Objects, the missing pure annotation would have no influence.)
Sep 17 2015
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/17/2015 09:47 PM, Timon Gehr wrote:
 Not all reasonable implementation are.
implementations
Sep 17 2015
prev sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Thursday, 17 September 2015 at 19:47:05 UTC, Timon Gehr wrote:

 I don't get this point. You don't need any annotations to write 
 ctfe-able code.
ctfe only works with pure functions. annotating your functions with the pure attribute helps you to pinpoint problems early. without having to do the actual ctfe every time you compile... which might take a considerable amount of time :)
Sep 17 2015
next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/17/15 4:24 PM, Stefan Koch wrote:
 On Thursday, 17 September 2015 at 19:47:05 UTC, Timon Gehr wrote:

 I don't get this point. You don't need any annotations to write
 ctfe-able code.
 ctfe only works with pure functions.
This is not a requirement of ctfe, although the set of functions that can be pure I think encloses the set of ctfe-able functions (there may be some exceptions, I'm not sure). The requirements are listed here: http://dlang.org/function.html#interpretation But you don't actually have to mark them pure, and a virtual pure function cannot be CTFE anyways, so this doesn't make a difference.
 I would argue it is very counter-intuitive to mutate any state when 
comparing objects. Then surely you meant const? pure functions can mutate state. I agree with your statement, though. I think Object.opEquals and Object.opCmp are going to eventually be removed, so you can define them however you want. -Steve
Sep 17 2015
prev sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 17-Sep-2015 23:24, Stefan Koch wrote:
 On Thursday, 17 September 2015 at 19:47:05 UTC, Timon Gehr wrote:

 I don't get this point. You don't need any annotations to write
 ctfe-able code.
ctfe only works with pure functions.
Wrong.
 annotating your functions with the pure attribute helps you to pinpoint
 problems early. without having to do the actual ctfe every time you
 compile... which might take a considerable amount of time :)
-- Dmitry Olshansky
Sep 17 2015