grauzone wrote:
Andrei Alexandrescu wrote:
Here's an article about the perils of equals in Java (opEquals in D):

http://www.ddj.com/article/printableArticle.jhtml;jsessionid=GFKUCQH5S4IHNQE1GHOSKHWATMY32JVN?articleID=184405053&dept_url=/java/

It turns out this is a great example for NVI. In D, we could and should
do the following:

class Object {
    // Implement this
    private bool opEqualsImpl(Object rhs) {
        return false;
    }
    // Use this
    final bool opEquals(Object rhs) {
        if (this is rhs) return true;
        if (this is null || rhs is null) return false;
        return opEqualsImpl(rhs) && rhs.opEqualsImpl(this);
    }
}

I took advantage of the fact that in a final function this may be null
without an access violation. The implementation above ensures symmetry
of equality and has each class implement a simpler primitive.

What do you think?

Eh, now after all this discussion, we're going to allow even "this" to be null? That seems like a backstep...

How is it a backstep? It's perfectly valid behavior.

Object foo;
foo.opEquals(foo);

The call itself will *always* succeed, its when 'this' gets referenced in opEquals that the code will crash.

Implementing opEquals as a global/static function, that calls the actual Object.opEquals virtual method would be so much more straight forward.

I agree, I prefer methods to end with Impl to stay hidden instead of being the ones to override.

PS: I agree about the NVI thing. If you'd go to extend the language for "NVI", couldn't we just introduce a second type of virtual function that works this way:
1. the super class' implementation is _always_ called first
2. the super class function can decide to "call down" to the sub class' implementation of the same method => no extra do<something> method needed, and the code is (possibly) clearer.

Andrei

I don't know how useful that would be, when you override a method you usually want to call the super method somewhere in the new implementation, not always at the beginning.

Reply via email to