On Fri, 30 Sep 2011 11:48:02 -0400, kenji hara <[email protected]> wrote:

2011/10/1 Steven Schveighoffer <[email protected]>:
There is a debate in a sub-thread about logical const on whether
Object.opEquals should be const or mutable.

Right now, it's mutable. This disallows comparison between const objects
(except it is technically allowed because the compiler ignores const
correctness for this).

I think it should be const.

However, making it const disallows opEquals functions which mutate the
object (for lazy loading or caching purposes). I question that this is a
major concern, but I have discovered an easy fix that appeases all.

If we make opEquals a template (not Object.opEquals, but the free function opEquals(Object lhs, Object rhs) ), then the template has access to the full type information of the derived object. This means that Object.opEquals can be exclusively const, and you can overload this with a mutable version, and
everything just works.

I tried it out by making my copy of druntime use a template (it's actually
very few lines change).  Although I needed to use casts to compile some
parts of phobos (some opEquals calls depend on the compiler ignoring const guarantees as mentioned above), when compiling a simple test program, I can
prove it works without compiler changes.

Along with the ability to have both const and non-const (and even
technically immutable) opEquals, we have the following drawbacks and
benefits:

1. template bloat.  Every combination of two object types being compared
will generate a new template.
2. inlining of opEquals. Both the free function template, and possibly a
final-declared opEquals on a dervied object could be inlined.
3. possible specialization of opEquals(MyDerivedType obj). I don't remember
exactly the overloading rules, so this may be impossible.
4. Fixes the issue with interface comparison (see bug
http://d.puremagic.com/issues/show_bug.cgi?id=4088), not in the best way,
but it would be better than the current situation.

What do people think?

-Steve


I think your suggestion is almost same as mine.

Discussions: https://github.com/D-Programming-Language/phobos/pull/262
Implementations: https://github.com/D-Programming-Language/druntime/pull/72

My patch does not support #4 (interface comparison), but others are same.

Yes, you did almost exactly what I did, except I made it valid to call mutable opEquals for two unlike objects.

That is, I think there is no point for the static if in the middle, just do lhs.opEquals(rhs) && rhs.opEquals(lhs) for all cases.

-Steve

Reply via email to