On Friday, 25 July 2014 at 20:07:08 UTC, Jacob Carlborg wrote:
On 2014-07-25 20:56, Jonathan M Davis wrote:
opEquals will now be used for AA keys, not opCmp.
Well, yes. But that was not the case when the code was written.
In that case it was to correct to defined opCmp.
Yes, but opCmp always had to be consistent with opEquals, or the
code was broken. If the code was "lucky," and the key type was
only ever used with opCmp and never opEquals, then the bug
wouldn't have manifested itself, but the odds of that are
probably low, and it's a bug regardless.
That's why git master
generates errors when you have a struct which defines opCmp
and not
opEquals, and you try and use it as an AA key. It was done on
the theory
that your opEquals and opCmp might not match (which would be
buggy code
to begin with, so it would be forcing everyone to change their
code just
because someone might have gotten their opEquals and opCmp
wrong).
If we keep the same behavior as 2.065 but still change the AAs
to use
opEquals, then there's no need to define opEquals unless the
type was
buggy and defined opCmp in a way that was inconsistent with
the default
opEquals and then didn't define one which was consistent. The
code will
continue to work.
H.S. Teoh wants to change the default-generated opEquals to be
equivalent to lhs.opCmp(rhs) == 0 in the case where opCmp is
defined in
order to avoid further breaking the code of folks whose code
is broken
and didn't define opEquals when opCmp didn't match the default.
So, if we remove the new check for a user-defined opEquals
when opCmp is
defined, then you don't have to define opEquals. If we do what
H.S. Teoh
suggests, then you'll have to define it if you want to avoid
the
additional checks that opCmp would be doing that opEquals
wouldn't do,
but if you didn't care, then you wouldn't. If we leave it as
it is in
git master, then you'd always have to define it if you defined
opCmp and
wanted to use it as an AA key, and since opCmp was used for AA
keys
before, that means that _every_ type which didn't define
opEquals but
was used as an AA key will suddenly have to define opEquals
and toHash
and will thus now be broken. So, the current situation in git
master is
the worst all around.
That's what I'm saying. I don't understand what you're arguing
for/against.
I'm arguing for _not_ have the compiler complain if you defined
opCmp but not opEquals but to do exactly what it did with 2.065 -
which is to automatically define opEquals and toHash for you if
you didn't define them.
H.S. Teoh is arguing for changing it so that the generated
opEquals uses opCmp if it's present, which generally makes the
performance of the generated opEquals worse if opCmp was
consistent with the default opEquals (which it should have been,
since it didn't define its own), and worse, it forces all types
used as keys in AAs to define toHash, because then the generated
opEquals is no longer consistent with the generated toHash.
What I'm arguing for would only break code which failed to define
opEquals to be consistent with opCmp - so only code which is
already broken. No other code would break. However, the current
situation with git master and H.S. Teoh's suggestion would both
break existing code.
- Jonathan M Davis