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

Reply via email to