| |
 | Posted by Jonathan M Davis in reply to SimonN | Permalink Reply |
|
Jonathan M Davis 
Posted in reply to SimonN
| On Sunday, February 21, 2016 04:25:59 SimonN via Digitalmars-d-learn wrote:
> Hi,
>
> immutable class A {
> int i;
> this(int arg) { i = arg; }
> override bool opEquals(Object rhsObj)
> {
> auto rhs = cast (immutable(A)) rhsObj;
> return rhs && i == rhs.i;
> }
> }
>
> Error by dmd 2.070:
>
> ./immutclass.d(4): Error: function immutclass.A.opEquals
> does not override any function, did you mean to override
> 'object.Object.opEquals'?
>
> My understandings:
>
> 1. immutable class A means: All methods have immutable tacked
> on them implicitly.
> 2. Object.opEquals doesn't have immutable tacked on it. If I
> want to override Object.opEquals, I should override without
> 'immutable'.
> 3. Overriding opEquals and toHash are necessary to make A
> behave properly as AA key type. This is incompatible with
> (2) in an immutable class.
> 4. I found this thread:
> How to turn an inout(Object) into a string
>
> http://forum.dlang.org/thread/dcobmtogyrmnaqnqyvbz@forum.dlang.org
> that I interpret as: The need for the currently-impossible
> override is acknowledged, but the implementation would bring
> significant changes to the language, therefore the solution
> is postponed. The above thread was from mid-2015, but I guess
> it's still relevant.
>
> My workaround is: Make class _A private, and declare every method immutable, except for what Object decrees to be mutable/const/... Then make a public alias A = immutable(_A).
>
> Is there something better than this?
>
> Has there been any new development on Object method removal? Jonathan M Davis has been pushing this hard 2 years ago, I'd love to see the efforts make it into the language. :-)
Okay. Until opEquals, toHash, toString, and opCmp have been removed from Object, you can't override any of them as anything other than mutable. opEquals still works with const and immutable objects via a hack in druntime (it casts away const inside of the free function opEquals which works if your opEquals behaves but results in undefined behavior if it mutates anything). So, I expect that it's simply not possible right now to use a class as a key in an AA, though a struct should work if it's defined appropriately. Certainly, if it's legal to use a class as the key in an AA, it's a bug given that there's no guarantee that it's immutable like a key needs to be.
As for actually getting rid of opEquals and friends from Object, no real progress has been made. I finally have a working version of the PR to templatize the free function opEquals such that it will work with opEquals that take a derived class instead of Object (previously, compiler bugs kept getting in the way of it working), but it hasn't even been looked at yet from what I can tell, and it's the simplest of the bits that need to be done (https://github.com/D-Programming-Language/druntime/pull/1439). The overhaul of the AA implementation to templatize it needs to be completed (and I'm not sure where it currently stands) and there will likely have to be some clever compiler changes to make it so that we can remove those 4 functions from Object without breaking code in the process. So, it's going to take a variety of people to get it done, and unfortunately, it hasn't been high on much of anyone's todo list.
- Jonathan M Davis
|