July 13, 2012
On Thu, 12 Jul 2012 18:38:06 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 7/12/12 4:50 PM, Steven Schveighoffer wrote:

>> My personal opinion is we should simply eliminate the four methods (or
>> at least the three required for AAs), fix AAs, and deal with the
>> fallout. I can't really remember the last time I simply used
>> obj1.opEquals(obj2) to do comparisons instead of obj1 == obj2 (which
>> should do the right thing if obj1.opEquals(obj2) is valid). The code
>> that relies on this is probably very rare. I certainly would *love* to
>> rewrite all my opCmp and opEquals functions to accept the minimal base
>> class instead of doing the dual dispatch dance with Object parameters.
>
> I agree not a lot of people use obj1.opEquals(obj2) instead of obj1 == obj2, but I assume quite a few override opEquals and rely on it being called.

(fixed above for you)

Yes, and why would that not work?  If opEquals is defined as:

bool opEquals(Object o)

Won't this still be called by the compiler, even if Object does not define it?  (assuming the extraneous override keyword is removed)

This would be an issue if people stored all their objects as Objects, which is very rare also I think.

-Steve
July 13, 2012
On Thu, 12 Jul 2012 21:30:36 -0400, Mehrdad <wfunction@hotmail.com> wrote:

> On Friday, 13 July 2012 at 01:22:59 UTC, Jonathan M Davis wrote:
>> There's big difference between a library and a the language itself.
>
> Surely that's a non sequitur... Aren't we modifying druntime here?
> What part of this has to do with the _language_? Isn't druntime a library?
>
> Also, why can't you tell the user, "it's open-source! If it doesn't suit your needs, go modify it! Removing const is trivial!"
> What makes it so easy to say that about every library /except/ druntime?

First, Object (and the functions in object_.d) is treated specially by the compiler.  For exammple, object.opEquals worked on const objects, even though the function parameters were not const.

Second, If you change druntime, you might as well be hacking the compiler.  Every *single* library depends on druntime, including phobos.  Are you going to change all them too?

It's like saying it's as easy to prune a tree trunk as it is to prune a branch.

> 1. Again, see above -- Object is also in a library. Why doesn't the reasoning apply there? It's trivial to remove const from the library and recompile it -- _FAR_ easier than it is to modify any arbitrary library. (Speaking of which, thanks for making it so easy to modify & recompile druntime!)

No, it's not.  Everything depends on druntime.  If you think it was so easy, look at the date of this bug report, which all the top dogs agreed with: http://d.puremagic.com/issues/show_bug.cgi?id=1824

> 2. Isn't it kinda /trivial/ to avoid opEquals? Just don't use it. Make up your own method. What's wrong with this?

Yes, it is.  There isn't anything wrong with that, and it has been suggested -- if you want non-const opEquals, write your own method.

But I think we are past that point, in all likelihood, opEquals is going away from Object.

-Steve
July 13, 2012
On Friday, July 13, 2012 03:30:36 Mehrdad wrote:
> On Friday, 13 July 2012 at 01:22:59 UTC, Jonathan M Davis wrote:
> > There's big difference between a library and a the language itself.
> 
> Surely that's a non sequitur... Aren't we modifying druntime here? What part of this has to do with the _language_? Isn't druntime a library?

druntime is the runtime for D. The compiler uses it to implement key aspects of the language (e.g. new). Without it, you don't have D. It's effectively part of the language. Yes, you can replace it with your own version if you want to, but if you do so, you're essentially make your own variant of the language.

> 2. Isn't it kinda /trivial/ to avoid opEquals? Just don't use it. Make up your own method. What's wrong with this?

Stuff like AAs rely on it. So yes, if opEquals, opCmp, toHash, and toString were all const, classes could just override them, put assert(0); as their bodies, and not use them, but then anything requiring those functions - including the built AAs and standard library stuff such as format and writeln - would not only not work right, but they would kill your program when they were used. == itself used on such an object would kill your program. So, as it stands, whole language features become impossible to use with classes which can't be implemented with those 4 functions being const. You could only use classes which can't be const by avoiding those language features completely.

The proposed changes would make it possible for all of those features to be used by programs which didn't use const.

- Jonathan M Davis
July 13, 2012
On Thursday, July 12, 2012 22:08:01 Steven Schveighoffer wrote:
> On Thu, 12 Jul 2012 18:38:06 -0400, Andrei Alexandrescu
> 
> <SeeWebsiteForEmail@erdani.org> wrote:
> > On 7/12/12 4:50 PM, Steven Schveighoffer wrote:
> >> My personal opinion is we should simply eliminate the four methods (or at least the three required for AAs), fix AAs, and deal with the fallout. I can't really remember the last time I simply used obj1.opEquals(obj2) to do comparisons instead of obj1 == obj2 (which should do the right thing if obj1.opEquals(obj2) is valid). The code that relies on this is probably very rare. I certainly would *love* to rewrite all my opCmp and opEquals functions to accept the minimal base class instead of doing the dual dispatch dance with Object parameters.
> > 
> > I agree not a lot of people use obj1.opEquals(obj2) instead of obj1 == obj2, but I assume quite a few override opEquals and rely on it being called.
> 
> (fixed above for you)
> 
> Yes, and why would that not work? If opEquals is defined as:
> 
> bool opEquals(Object o)
> 
> Won't this still be called by the compiler, even if Object does not define it? (assuming the extraneous override keyword is removed)

That raises an interesting point. With these changes, what should opEquals' signature be for classes? Right now, it's always

bool opEquals(Object obj);

Would it still have to be that? It wouldn't really make sense for it be, since you couldn't use == on Object. Would it then use the most basic class which uses (i.e. the least derived class) which implements opEquals? Or would each derived class implement it with their type? Doing that causes overload issues, because then you have to alias every base class' overload to be able to use == against every base class' type. Is the solution to then to template opEquals and make it non-virtual? I don't know. D's overload rules could make this a bit interesting. We need to figure out exactly what opEquals' and opCmp's signatures are going to need to look like.

- Jonathan M Davis
July 13, 2012
On Friday, 13 July 2012 at 02:11:02 UTC, Steven Schveighoffer wrote:
> No, it's not.  Everything depends on druntime.  If you think it was so easy, look at the date of this bug report, which all the top dogs agreed with: http://d.puremagic.com/issues/show_bug.cgi?id=1824

Thanks for providing the link, I'll take a look at it. I'd never known opEquals was treated specially by the compiler (aside from operator overloading of course), that would change a lot of things.


>> 2. Isn't it kinda /trivial/ to avoid opEquals? Just don't use it. Make up your own method. What's wrong with this?
> Yes, it is.  There isn't anything wrong with that, and it has been suggested -- if you want non-const opEquals, write your own method.
> But I think we are past that point, in all likelihood, opEquals is going away from Object.


Well I'm not understanding the point of this post then... though thanks for letting me know I guess.
July 13, 2012
On Thu, 12 Jul 2012 22:19:35 -0400, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> That raises an interesting point. With these changes, what should opEquals'
> signature be for classes? Right now, it's always
>
> bool opEquals(Object obj);
>
> Would it still have to be that?

Nope, it could be:

bool opEquals(WhateverYouWant x);

It all depends on the situation and the hierarchy.  If you are frequently using base classes, you will need to override the base class member.

You could duplicate the exact situation we have now in your own hierarchy if you wish.  You could add const if you wish.  or pure, or @safe.

With no base defined by the language, you are free to do whatever you want.

-Steve
July 13, 2012
On Friday, 13 July 2012 at 02:19:49 UTC, Jonathan M Davis wrote:
> That raises an interesting point. With these changes, what should opEquals' signature be for classes?

How about inout?
July 13, 2012
On Thu, 12 Jul 2012 23:51:22 -0400, Mehrdad <wfunction@hotmail.com> wrote:

> On Friday, 13 July 2012 at 02:19:49 UTC, Jonathan M Davis wrote:
>> That raises an interesting point. With these changes, what should opEquals' signature be for classes?
>
> How about inout?

No.  opEquals returns bool.

-Steve
July 13, 2012
On Friday, 13 July 2012 at 03:57:21 UTC, Steven Schveighoffer wrote:
> On Thu, 12 Jul 2012 23:51:22 -0400, Mehrdad <wfunction@hotmail.com> wrote:
>
>> On Friday, 13 July 2012 at 02:19:49 UTC, Jonathan M Davis wrote:
>>> That raises an interesting point. With these changes, what should opEquals' signature be for classes?
>>
>> How about inout?
>
> No.  opEquals returns bool.
>
> -Steve

I meant more like

bool opEquals(inout Object other) inout;
July 13, 2012
On 2012-07-12 22:20, Steven Schveighoffer wrote:

> Many (most?) classes never care about opHash, opCmp, opEquals and
> toString.  But Object defines them, incorrectly for most cases.
>
> These apathetic classes would not break at all.  And to make the default
> be to inherit those methods would promote their usage or reliance on them.
>
> Not only that, but you are almost *forced* to define them, because you
> don't want accidental incorrect usage of them.  We have lovely
> situations where the only solution is to define a version of the method
> that *always throws* in a statically typed language.
>
> It's really a terrible solution (to force the definition of them) which
> Andrei quite correctly pointed out only existed because of the lack of
> templates back then.
>
> I think this discussion is somewhat academic at this point, as Andrei
> seems not too keen on the idea of having dual base classes.

I was trying to suggest something that is mostly backwards compatible.

-- 
/Jacob Carlborg