View mode: basic / threaded / horizontal-split · Log in · Help
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On 7/12/12 2:50 PM, H. S. Teoh wrote:
> On Thu, Jul 12, 2012 at 01:51:31PM -0400, Andrei Alexandrescu wrote:
>> On 7/12/12 1:40 PM, David Piepgrass wrote:
>>> 1. Most importantly, the C++ template approach is a big pain for
>>> large-scale systems, [...]
>>
>> The thing is, that can be done in an opt-in manner. People who want
>> methods in the root of the hierarchy can define a root that defines
>> them. But there's no way to opt out of inheriting Object. Basically
>> it's nice to not force people to buy into a constrained environment
>> without necessity.
>
> Having a class RawObject as a superclass of Object is an equally good
> solution.

As far as backward compatibility goes, I'm not sure. There's code out 
there that e.g. assumes Object has no supertype etc. (I wrote some.)

But one thing the recent discussion brought back to attention is that 
opEquals and opCmp are somewhat crappy. In D, they are in fact 
unnecessary, so it's better to undo that entire design if we can.


Andrei
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On 2012-07-12 20:50, H. S. Teoh wrote:

> Having a class RawObject as a superclass of Object is an equally good
> solution. Declare a class without a base class, and the base class
> defaults to Object.  Explicitly write "class MyClass : RawObject" and
> you get a class without the stuff in Object. If you want an entire
> hierarchy free of the stuff in Object, just write "class MyBaseClass :
> RawObject" and inherit everything from it.
>
> This has the advantage of _not_ breaking any existing code, and the
> people who want to opt out of Object, can.

Exactly, this is also what Ruby 1.9 does.

-- 
/Jacob Carlborg
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On 2012-07-12 16:28, kenji hara wrote:
> Is this really need?
>
> The four const operators in Object should not block the user-defined
> mutable operators.
>
> // My purpose for 2.060 release
> class C {
>    override opEquals(const Object o) const { ... } // or just alias
> super.opEquals opEquals;
>    bool opEquals(Object o) { ... } // add overload for mutable object comparison
> }
>
> auto c1 = new C(), c2 = new C2();
> c1 == c2;   // the both hand side is mutable, so mutable opEquals will run
>
> In git head, it is not disallowed, but it is a *compiler bug*.
> To fix the problem, I have a pull request for dmd.
> https://github.com/D-Programming-Language/dmd/pull/1042
> (The pull will kill attribute inference for const, but I think it is
> unnecessary for D.)
>
> ...But, I would never opposed to advancing toward the better language design.
>
> Kenji Hara

I would have thought that that already worked.

-- 
/Jacob Carlborg
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On Thursday, July 12, 2012 21:11:54 Jacob Carlborg wrote:
> On 2012-07-12 16:28, kenji hara wrote:
> > Is this really need?
> > 
> > The four const operators in Object should not block the user-defined
> > mutable operators.
> > 
> > // My purpose for 2.060 release
> > class C {
> > 
> > override opEquals(const Object o) const { ... } // or just alias
> > 
> > super.opEquals opEquals;
> > 
> > bool opEquals(Object o) { ... } // add overload for mutable object
> > comparison> 
> > }
> > 
> > auto c1 = new C(), c2 = new C2();
> > c1 == c2; // the both hand side is mutable, so mutable opEquals will run
> > 
> > In git head, it is not disallowed, but it is a *compiler bug*.
> > To fix the problem, I have a pull request for dmd.
> > https://github.com/D-Programming-Language/dmd/pull/1042
> > (The pull will kill attribute inference for const, but I think it is
> > unnecessary for D.)
> > 
> > ...But, I would never opposed to advancing toward the better language
> > design.
> > 
> > Kenji Hara
> 
> I would have thought that that already worked.

The recently added attribute inferrence for overridden functions in derived 
types makes it impossible to have a non-const overload of a const function.

- Jonathan M Davis
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On Thursday, July 12, 2012 20:42:49 David Piepgrass wrote:
> - 'const' is not overly harsh if the user has machanisms to make
> that mean 'logical const'.

That will _never_ happen. That completely destroys a number of the benefits of 
const, and it adds quite a bit of cognitive load in dealing with const, 
because all of a sudden, you have to worry about whether _this_ const means 
actual const or logical const. It would also complicate the compiler's 
handling of const by quite a bit. Not to mention, Walter hates logical const 
in general, so he wouldn't support it. So, no, it's not going to happen.

If we get any kind of logical const, it's going to be separate from const. 
const always has been and always will be physical const in D.

- Jonathan M Davis
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On Thursday, July 12, 2012 17:47:10 Mehrdad wrote:
> So if you're saying you can't use const with OOP, then I'm saying
> one of those needs to be fixed, and I was suggesting the former
> as a candidate.

You can use const and OOP together just fine, but that means that if you have a 
function which is marked as const in the base class, and you're operating on 
the objects through the base class pointer, then all of the derived classes 
must be able to have that function as const. In general, I really don' think 
that that's a big deal. The problem is that opEquals, opCmp, toHash, and 
toString affect _all_ classes, because they're in Object, and that 
unnecessarily restricts all classes. const is forced on you, and it's forced 
on you with incredibly common functions in a way that completely disallows 
some idioms (e.g. caching and lazy loading).

On the other hand, if you're dealing with your own class hierarchy, you can 
choose what you're going to mark as const or not, and so you can either forgoe 
const entirely or only use it on functions where you can reasonably require 
that they be const in all classes in that hierarchy. It's not being forced on 
you, and you can pick what works best for your set of classes.

The fact that const is restrictive isn't the problem. It's the fact that const 
is forced on you which is. As long as you have the choice whether to use it or 
not, then it's fine.

- Jonathan M Davis
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On Thu, 12 Jul 2012 14:43:57 -0400, Jacob Carlborg <doob@me.com> wrote:

> On 2012-07-12 15:39, Steven Schveighoffer wrote:
>
>> I think if we want a solution that allows old code to work, why not what
>> Timon suggested? Have a base class for Object (RawObject was suggested)
>> that does not implement the opFunctions.  It would still break code, but
>> would be easy to fix (just specify your class derives from Object, not
>> RawObject).
>
> Wouldn't the default be to inherit from Object?
>
> Like this:
>
> class RawObject {}
> class Object : RawObject {}
> class Foo {} // inherits from Object by default.
>
> Most people would not need to change anything, they can continue to use  
> Object. If they want to avoid the methods declared in Object they need  
> to explicitly inherit from RawObject.

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.

-Steve
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On 7/12/12 4:20 PM, Steven Schveighoffer wrote:
> I think this discussion is somewhat academic at this point, as Andrei
> seems not too keen on the idea of having dual base classes.

Well I wasn't keen on eliminating the four methods and look what happened!

Andrei
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On Thu, 12 Jul 2012 16:27:39 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail@erdani.org> wrote:

> On 7/12/12 4:20 PM, Steven Schveighoffer wrote:
>> I think this discussion is somewhat academic at this point, as Andrei
>> seems not too keen on the idea of having dual base classes.
>
> Well I wasn't keen on eliminating the four methods and look what  
> happened!

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'm also actually not liking using Object as the scorned child of  
RawObject, I'd rather keep Object as the base, and use something like  
OldObject as a different base class, or maybe use an interface.

I still am not keen on having a runtime vtable comparison to see if we  
want to mimic old behavior, how does one declare "this comparison isn't  
valid" to the compiler?  That is one of the main benefits I see with  
dumping the methods.

-Steve
July 12, 2012
Re: All right, all right! Interim decision regarding qualified Object methods
On Thursday, July 12, 2012 16:50:21 Steven Schveighoffer wrote:
> 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.

It's almost certainly bad code anyway. The free function version of opEquals 
specifically does extra work to make equality checks correct and avoids some of 
the pitfalls that opEquals causes in Java (e.g. doing comparison in both 
directions if the types aren't identical). So, if we break that, it's probably 
a _good_ thing. And if they _really_ want to do that, that can still do it 
with their derived classes which define opEquals. They just can't do it with 
Object.

- Jonathan M Davis
6 7 8 9 10 11 12 13 14
Top | Discussion index | About this forum | D home