[Issue 3659] Too much exegesis on opEquals

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Dec 31 07:37:34 PST 2009


http://d.puremagic.com/issues/show_bug.cgi?id=3659



--- Comment #3 from Andrei Alexandrescu <andrei at metalanguage.com> 2009-12-31 07:37:33 PST ---
(In reply to comment #2)
> Here is the issue.  The compiler now is required to generate an opEquals which
> calls x.m == y.m on all members m of the struct (this was to fix bug 3433). 
> However, in order for this opEquals to handle const and immutable versions of
> the struct, the opEquals generated needs to be const.  Given that, if member m
> is another struct with a *user defined* opEquals, that opEquals must *also* be
> const.

I see, thanks for explaining.

> The current rule is too strict, I agree.  For instance, you should not require
> that the argument be ref const if the argument type can be implicitly cast from
> const to mutable (i.e. a pure value type), but if the argument is ref, it
> *should* be const, and the opEquals function itself *should* be const. 
> Otherwise, you could be changing stuff just by doing a comparison.
> 
> What is the use case for an opEquals not being const?

I'm thinking of our current stance on const: if you don't care about const,
don't use it and for the most part it won't intrude on you. For example,
string's use of immutability is fairly confined.

opEquals is a stark deviation from the stance above. It *will* intrude. The
classic example is this:

class Widget {
    bool opEquals(Widget);
}    

Compiling this issues:

Warning: object.Object.opEquals(Object o) is hidden by Widget

It only gets downhill from there:

struct Widget {
    bool opEquals(Widget) { return true; }
}

This time it's an error:

Error: function test.Widget.opEquals type signature should be const bool(ref
const(Widget)) not bool(ref Widget)

So you simply can't "not care" about const. But then it's all getting viral
because cons is viral. Consider the user grudgingly agrees to add const, and
then...

class Widget {
    private Gadget g;
    bool opEquals(const Widget rhs) {
        return compatibleGadgets(g, rhs.g);
    }
}

But now it's still not fine because compatibleGadgets is also written without
caring about const. It's all a mess. 

Now consider that the user capitulates and decides to use const wherever
applicable. Things will still not work in certain cases. For example if
opEquals must compare members that are lazily computed, you can't make it
compile. Cheating by casting away const will mess up a variety of assumptions.

As an aside, I know what it takes to define lazily computed state to work with
const, but Walter is at the bottom of a 5000 TeV potential hole that spells
like "this is like C++ mutable and C++ mutable is incorrect, therefore I will
not process any information henceforth". So I am unable to even start
explaining that to him. Besides, assuming Walter is convinced of the
correctness of the feature, it's unclear whether it will pull its weight. It
will complicate the language, and the benefits, while there, are rather subtle.

So I don't know what to do.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list