On Tuesday, 19 March 2013 at 23:13:19 UTC, Jonathan M Davis wrote:
On Tuesday, March 19, 2013 22:43:10 Dan wrote:
The above works with the built-in AAs.
Please offer an example.
It works because the outer type defines toHash. Without toHash,
the built-in
AAs won't work. If you're dealing with member variables which
don't have
toHash, then doing something like you did is an option, but the
outer type
still needs toHash, and if any of the member variables define
an opEquals but
not a toHash, then you risk having your hash change when a
member variable
changes even when the new value of the member variable is
considered equal to
the old one (e.g. because a cached value or some other member
variable in that
type is not considered to be part of the equality of an object
but _would_ be
considered to be part of the hash if you use reflection to
generate a hash from
all of that type's member variables). So, using reflection to
generate hashes
for arbitrary types can be risky. Whether it works on not
depends on how those
types are defined and what you're doing with them.
For hashing it is not foolproof as you mentioned. It is important
to understand that opEquals and toHash should share the same
semantics (i.e. if they are equal they should hash the same).
But, in general, when you control the code you don't need toHash
or opEquals at every level of composition and it will still work
fine (compile-time recursively) as a key in a AA.
But the main problem that I'm pointing out is that you can't
define your own,
non-standard functions for equality or hashing or whatever and
expect your
types to play nicely with other stuff. If your stuff is wrapped
in types that do
define the proper functions for that (like in your example),
then it can work,
but the types which were wrapped won't play nice outside of the
wrapper.
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.
Thanks
Dan