I read the excerpt.
I understand the current implementation just fine. The issue I have is with
the line:
return lhs.opEquals(rhs) && rhs.opEquals(lhs);
I thought maybe || would be a better idea, but after reading the text, I agree
the example shows that is not the best method.
Following the example in the book, let's say I make my own widget, called
StevesTextWidget, which inherits Widget, not TextWidget. It has some of the
same functionality as TextWidget, but it's not a TextWidget. If I want to be
able to compare StevesTextWidget to a TextWidget, it's not possible, because
the TextWidget will veto every time, even though StevesTextWidget has total
understanding of TextWidget and can correctly do the comparison. On the other
hand, if || was used, comparing StevesTextWidget to a Widget will allow
Widget's routine to override the opEquals of StevesTextWidget, and like the
example in the book, could possibly cause an invalid equal response.
If Widget's routine is rewritten to return false when the actual derived class
is not widget, then that forces derivative classes to always implement
opEquals, even if it just calls the base method (which it can't because it will
return false!).
We all agree that opEquals is a double-dispatch problem, but the "fix" being
introduced causes 1) unreasonable performance problems and 2) unreasonable
paranoia in some cases, to the point where opEquals will not be a universal way
to determine equality. You are making a decision both on equality and ability
to determine equality with one bit.
Maybe the answer is to give more information than one bit. This was my
original idea, and I guess I'm back to that. Like it or not, opEquals is a
complex problem to solve, and taking a simple approach to it results in it's
usefulness being extremely limited. To be able to just use == when you want
equality is a good goal to have, even if it means the opEquals regime is
slightly more complex.
What I'm looking for is a way to give more information to the opEquals global
function if you want to, but falls back to some reasonable default (such as the
current behavior), if you don't care about performance or dealing with the
complexity of the problem. In other words, you don't *have* to override/define
the canCompare function, the default simply always returns the same thing, and
if you don't, you get the current behavior. But if you want to optimize
opEquals for specific cases (or make specific cases possible), you can override
canCompare.
-Steve
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos