On Wed, Aug 24, 2005 at 12:43:46AM +0300, Yuval Kogman wrote: : On Tue, Aug 23, 2005 at 10:28:01 -0700, Larry Wall wrote: : > On Tue, Aug 23, 2005 at 06:19:33PM +0300, Yuval Kogman wrote: : > : "10" == "10"; # dispatches to Str, due to better match : > : > Nope, that will continue to coerce to numeric comparison. The design : > team did in fact consider pure "equivalence" MMD dispatch of == in : > the last meeting, but rejected it in favor of "eqv" : : BTW, regardless of whether it's called 'eqv' or '==', the semantics : shared between the MMD variants of ~~ and eqv as proposed in the : bottom of the message are not utter crap, right?
Hmm, well, I don't think >>&op<< is valid syntax, but you did say "semantics", so I can't criticize that part. :-) Not that the rest of what I say amounts to criticism. More just thinking in your general direction. I don't know how close ~~ and eqv will end up. There are some differences in emphasis, and when two operators get too much like each other, I tend to add more differences to make them inhabit different parts of the solution space. One current difference is that, despite the symmetry of ~~, it's not actually a symmetrical operator much of the time, such as when matching values to rules. ~~ is intended to be heavily dwimmical, so it's allowed to do various kinds of abstract coercions to figure out some mystical "good enough" quotient. But eqv on the other hand should probably be false in asymmetrical situations. The implementation of ~~ may delegate to eqv in certain symmetrical situations, of course. Another difference in emphasis is that eqv is intended to equate values (one of the reasons for the 'v') that would be treated as equal when used as keys of an object hash. Now the funny thing about an object hash is that you don't ever want to hash based on a mutable value. Ordinary value types are immutable, so this 42 is the same as that 42 over there. So we have $a = 42; $b = 42; $a eqv $b # always true $a =:= $b # might be true The =:= operator always compares object identities, even if the objects want to pretend to be values. So eqv lets them pretend, while =:= doesn't. But for objects that don't want to pretend to be values, eqv can delegate to =:=. On the other hand, it's not clear whether eqv (and by extension hashes) should take "snapshots" of mutable values. That is, it's not clear whether this should say "true true" or "false false": my %hash is shape(Object); %hash{ [1,2,3] } = 1; if exists %hash{ [1,2,3] } { say "true" } else { say "false" } if [1,2,3] eqv [1,2,3] { say "true" } else { say "false" } But whatever it says, I think it should say the same thing both times. Certainly if we had Pythonic immutable tuples if (1,2,3) eqv (1,2,3) { say "true" } else { say "false" } should say "true", since those are the same values, and they can't change. However, in Perl-5-Think, [1,2,3] produces mutable arrays, so unless we come up with some kind of fancy COW for [1,2,3] to be considered immutable until someone, er, mutes it, I think eqv would have to return false, and consider two such objects to be different values (potentially different if not actually different). It would be possible to declare %hash some way that forces a "snapshot" via some kind of serialization or other, but then it gets hard to keep the identity around. Then the question arises how we doctor if [1,2,3] eqv [1,2,3] { say "true" } else { say "false" } to do the same snapshot comparison. Arguably ~~ could do it, since it's explicitly *not* about identity. if [1,2,3] ~~ [1,2,3] { say "true" } else { say "false" } Or we could have a more explicit way of doing whatever it is that the snapshot hash does to each argument. if [1,2,3].snap eqv [1,2,3].snap { say "true" } else { say "false" } Or we could have a different operator that coerces like == and eq, only via .snap: if [1,2,3] equals [1,2,3] { say "true" } else { say "false" } (Actual name negotiable, of course). The advantage of the latter approach is that you can say @foo >>equals<< @bar and the .snaps are automatically distributed. Otherwise you'd have to say @foo<<.snap >>eqv<< @bar<<.snap which is a pain. On top of which, equals doesn't actually have to implemented in terms of .snap--it could just compare the current values of the mutable objects directly. (Just as =:= doesn't have to be implemented in terms of .id.) Larry