recursive equal, and firstDifference functions
Jonathan M Davis
jmdavisProg at gmx.com
Tue Mar 19 17:51:54 PDT 2013
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.
There _are_ defaults for ==, and it really does quite a lot for you (e.g.
recursively using == on each of a type's member variables), so you don't
always have to define opEquals, but as soon as you have a layer of indirection
(aside from arrays), you do have to define opEquals, or you'll generally end up
checking for reference/pointer equality rather than equality of the actual
objects. And in some cases, that's exactly the right thing to do. In others,
it's not. It all depends on the context.
As for comparing ranges, it would actually be very bad for performance if they
defaulted to what equal does (particularly with regards to strings), and the
language really doesn't do much to support ranges directly. Aside from
foreach, they're completely a library construct. And really, equal exists with
the idea that ranges of different types (but the same element type) can be
compared, which isn't what you're generally trying to do with opEquals at all.
If you want to avoid boilerplate, then use mixins. It should be fairly trivial
to define a mixin such that you can do something like
mixin(defineOpEquals!(typeof(this)));
which defines an opEquals which does deep comparison. But also remember that
what is necessary for deep comparison often depends on the types being
compared (e.g. a range may or may not require equal to get the comparison that
you want), so while it may be possible to define a mixin which creates an
opEquals which will work in most situations, there are plenty where it won't.
For instance, given that the standard library supports ranges, it's likely
that something like defineOpEquals would know about them and do what is most
likely to be the correct thing for them, but if ranges weren't part of the
standard library, thhen defineOpEquals wouldn't know about them and couldn't
handle them properly. The same will be true for any user-defined type that
requires a particular idiom in order to be compared correctly.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list