On Wednesday, March 20, 2013 01:17:13 Dan wrote: > This is true, but then my code is by definition not standard. > However, theoretically, the language writers could. For example, > any '==' could be lowered to a 'standard' function, probably > better named 'intancesDeepEqual(a,b)' and that function could use > reflection to provide equal when not available else call opEquals > if it is available. Similar with opCmp, dup, idup, ... > In other words, in the vein of the original poster, why not allow > all of these nice goodies (equality comparison, opCmp comparison, > dup) without requiring boilerplate code while still > honoring/using it when it is provided.
Okay. I'm going to take a second stab at replying to this, because I think that I can explain it much better. The standard function that == lowers to is opEquals. Nothing else is needed. The way that == works is integral types, char types, pointers, and bool: bitwise comparison floating point types: equality which is similar to bitwise comparison but takes NaN into account arrays: The ptr and length attributes are checked, and if the lengths are equal but the ptrs are not, then element-wise comparison is used, where each element is compared with == (whereas if the lengths are different or if the ptr and length attributes are identical, no further comparison is needed). structs and classes: Their opEquals is used. If a struct or class does not define opEquals, then one is generated where each member variable is compared in turn with ==. So, they are compared recursively. They _only_ times that you need you need to worry about defining opEquals are when 1. the default comparison is comparing pointers, and you want to compare what they point to rather than the pointers themselves. 2. you want equality to mean something other than calling == on each member variable (including doing something other than == on a particular member variable as might be the case with a member variable which is a range). The way == is defined is very clean and straightforward. There _are_ bugs which complicate things (e.g. http://d.puremagic.com/issues/show_bug.cgi?id=3789 ), but those can and will be fixed. The design itself is solid. It's true that equal is often need for comparing ranges of the same type, but that's arguably a defect in the implementations of those ranges. equal is specifically designed to compare ranges which are different types but have the same element type. == is what's for comparing objects of the same type. But most ranges don't currently define opEquals, even when they need it in order for it to do a proper comparison. That's arguably something that should be fixed, but it's a design issue of ranges, not ==. But if you want to ensure that equal is used, you can always use a mixin to define opEquals that way (though you actually risk making the comparison less efficient than it would be if the ranges themselves defined opEquals). So, I can see a definite argument that ranges should make sure that they define opEquals (which wouldn't negate the general need for equal as that's specifically for comparing ranges of different types which have the same element type), but there's no need to change how == works. The design is actually very clean. - Jonathan M Davis
