Re: ~ and + vs. generic eq
HaloO, Yuval Kogman wrote: No, the role installs homogenious targets into the generic binary-MMD comparator which I think is called eqv. Err, why? We already have that with regular MMD semantics. role Num { multi &*infix: ($x:, Num $y) { $x == $y } } What you mean is double dispatch, cascading, delegation or what ever. I had the two juxtapositions of $x eqv $y versus $x &ee $y # or even $x $ee $y when $ee is a coderef in mind. In the latter case you a get a complicated mix of parsing that in the first place and generating code for a three invocant anonymous dispatch or whatever it is. I mean with *no* : in the definition. multi &*infix: ($lhs, Compare &comp, $rhs) {...} BTW, is that now valid syntax? I thought there is no & sigil but one of the two keywords sub or method: multi sub *infix: ($lhs, Compare &comp, $rhs) {...} I'm not sure if I get you right, but I think we agree that there should be only one comparer for a certain type/class. Everything else is nonsense. I mean apples should know how to eqv to other apples and oranges with oranges. MMD enters the picture only if you want to compare apples with oranges. By color, by weight, as fruits in general, etc. Comparing apples with oranges should do two equivalent MMD lookups on coercion, one of apples to oranges, the other of oranges to apples (unless there is an MMD compare between apples and oranges already), and if they are equivalent then there is an error. Sorry, I don't understand what an "MMD lookup on coercion" should be? Do you think of eqv as a simple two parameter sub that *single* dispatches first on the $one then on the $other arg with the respective non-invocant as parameter and then xor's and negates the results for consistency? sub eqv ($one, $other --> Bit) { # .compare_to:(Object: Object --> Bit) note the single invocant! return !($one.compare_to($other) ^^ $other.compare_to($one)); } Apart from the fact that somehow two types are involved I don't see MMD in that. To me a method's name is a concept that is realized differently for different types of arguments. At hand we are discussion the well known problem of generic equality versus more specific equalities of strings, numbers or objects/refs. And now Perl6 addresses the ternary problem of remaining generic with respect of the infix operator name or precise concept such that it ends up comparing numbers numerically, strings textually, colors colorfully plus all the mixed cases while at the same time keeping compatible to Perl5's operator semantics. The first problem you face in this quest is naming the beast---and the three letters 'eqv' aren't it to me because variable stuff in Perl is expressed with sigils. I'm not sure if the above discribed extreme case if $x $ee $y { say "Hurray, we have equality" } has a chance not to end up with a 'two terms in a row' parse error. And I'm unsure if $x (+&eqv)() $y works even when prefix:<+>:(Comparor) exists and returns a numeric Comparor. But named params next to the operator could work I think it should even without the parens... isn't the & sigil enough to make it clear? & is just like $ in this respect Which parens? The ones around (+&eqv) or the trailing call op ()? Note that the precedence of postfix () is higher than prefix +. And +&eqv might simply mean a numerified coderef and not a dispatched call of prefix + where the returned value is type checked at runtime for infix operator type compatibility. And then after this successfull type check this returned operator is MM dispatched on ($x,$y). And I can increase the challenge level easily to my $o := &eqv; # or with \&eqv ? if $x +$o $y {...} # parseable without type info about $o? Just to mention one possible alternate interpretation, imagine prefix + on $o returning a postfix op that given $x returns yet another prefix op that given $y returns a value that is booleanized by the if which then executes or skips the trailing block correspondingly. That is with explicit parens we would get: if (($x(+$o))($y)) {...} # parseable? That is like parsing the sentence: "Time flies like an arrow", and asking yourself: "What are time flies and why do they like arrows?" If the above works, I guess variability against the if will not parse? sub foo ($i, $x, $y, $z) { $i $x $y $z { say "something got us here" } } Or does it? Actually sigiling i and y with & instead of $ reduces the possibilities a lot and might even imply to associate the trailing block literal with &i and default &y to an infix op. Thus a call foo( &*if, 42, &infix:<==>, 42); will indeed say "something got us here"---that something beeing the numeric equality of 42 and 42 :) With some parsing magic thrown in, I would still propose to make junctions in the style of the above foo such that if any( $points > @highscores ) { say "a new entry!" } means what auto-threaded ($points == any(@highscores)) means now, but makes
Re: ~ and + vs. generic eq
On Wed, Sep 21, 2005 at 13:53:20 +0200, TSa wrote: > HaloO Yuval, > > you wrote: > >On Mon, Aug 29, 2005 at 14:07:51 +0200, TSa wrote: > >> role Object does Compare[Object, =:=] > >> role Numdoes Compare[Num, ==] > >> role Strdoes Compare[Str, eq] > >What is the implication of from the perspective of the person using > >Object, Num and Str? > >Do they have one unified comparator? > > No, the role installs homogenious targets into the generic > binary-MMD comparator which I think is called eqv. Err, why? We already have that with regular MMD semantics. role Num { multi &*infix: ($x:, Num $y) { $x == $y } } > That's an interesting question which is related to my retention to metric > MMD. We must distinguish homogenous from heterogenous comparisons. My > role Compare from above ensures that the comparor can be deduced from the > unique (super)type of the two values to be compared. As such the comparator > indirectly is class or type specific. The heterogenous cases however have to > fallback to "real" MMD. Now metric MMD could spoils this approach by picking > the "wrong" eqv target even though a proper homogenous target were > available! Then MMD must be fixed, as I've argued several times before. MMD cannot work unless it does what almost everyone means and complains when there is no obvious way. What you're describing is a problem that a broken (by this definition) MMD system can provide. > I'm not sure if I get you right, but I think we agree that > there should be only one comparer for a certain type/class. > Everything else is nonsense. I mean apples should know how > to eqv to other apples and oranges with oranges. MMD enters > the picture only if you want to compare apples with oranges. > By color, by weight, as fruits in general, etc. Comparing apples with oranges should do two equivalent MMD lookups on coercion, one of apples to oranges, the other of oranges to apples (unless there is an MMD compare between apples and oranges already), and if they are equivalent then there is an error. > It seems that the Code type is still some kind of second class > citizen in Perl6 because you can't nicely apply prefix ops to > pending invocations without some help from the meta categories. > And I'm unsure if > >$x (+&eqv)() $y > > works even when prefix:<+>:(Comparor) exists and returns a > numeric Comparor. But named params next to the operator could work I think it should even without the parens... isn't the & sigil enough to make it clear? & is just like $ in this respect -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me tips over a cow: neeyah!! pgpihNFvtu8Pt.pgp Description: PGP signature
Re: ~ and + vs. generic eq
HaloO Yuval, you wrote: On Mon, Aug 29, 2005 at 14:07:51 +0200, TSa wrote: role Object does Compare[Object, =:=] role Numdoes Compare[Num, ==] role Strdoes Compare[Str, eq] What is the implication of from the perspective of the person using Object, Num and Str? Do they have one unified comparator? No, the role installs homogenious targets into the generic binary-MMD comparator which I think is called eqv. If so, this sounds like you are subverting MMD with some odd currying of the 'compare' method (whatever it's name may be) provided by the Compare role, instead of relying on the already existing semantics of MMD dispatch to give you the same name for several, superficially same meanings. The problem with equality checking is that there are several notions of equality :) And if you include them into the set of types used in the dispatch decision you end up with the very unspecific :( ::X, ::Y, Code.does(Compare) --> bool ) type and the difficulty of defining a nice call syntax for it! The driving idea here is that the syntactical choice of the programmer amounts to a type preference of the Comparer subtype. Do you mean on a per class or per comparison basis? That's an interesting question which is related to my retention to metric MMD. We must distinguish homogenous from heterogenous comparisons. My role Compare from above ensures that the comparor can be deduced from the unique (super)type of the two values to be compared. As such the comparator indirectly is class or type specific. The heterogenous cases however have to fallback to "real" MMD. Now metric MMD could spoils this approach by picking the "wrong" eqv target even though a proper homogenous target were available! I think that exceptions from the class perspective should not be done by parametrising the quality role, but overriding it, and that from the per comparison perspective we need to say either: coerce_to_other_type($value) generic_equality coerce_to_other_type($other_value) I'm not sure if I get you right, but I think we agree that there should be only one comparer for a certain type/class. Everything else is nonsense. I mean apples should know how to eqv to other apples and oranges with oranges. MMD enters the picture only if you want to compare apples with oranges. By color, by weight, as fruits in general, etc. and being an operator rich language we can specificate the generic comparator to make things a bit more fun like I proposed: $x +eqv $y; $x ~eqv $y; It seems that the Code type is still some kind of second class citizen in Perl6 because you can't nicely apply prefix ops to pending invocations without some help from the meta categories. And I'm unsure if $x (+&eqv)() $y works even when prefix:<+>:(Comparor) exists and returns a numeric Comparor. But named params next to the operator could work $x eqv:num $y and plain eqv could actually mean binary eqv:mmd on the lhs and rhs. Ofcourse, I think that s/eqv/==/;, but everyone hates that. Well, I wonder if ($x eqv $y) is the same as !($x xor $y) and as such we just lack a high precedence correspondence to ^^ :) H, the Mathematician in me sees <==> ... But wouldn't that mean that ^^ should be ... -- $TSa.greeting := "HaloO"; # mind the echo!
Re: ~ and + vs. generic eq
On Mon, Aug 29, 2005 at 14:07:51 +0200, TSa wrote: > HaloO, > > Damian Conway wrote: > >Just a meta-point...one thing we really do need to be careful of is not > >ending up with 17 different "equality" operators (like certain languages I > >shall refrain from naming). So far we're > >contemplating: > >=:= > >~~ > >== > >eq > >eqv > >equals > >Do we really need even that many??? > > My opinion is there should be a role Compare that takes a > Comparer as one of it's parameters. For the above we have > in pseudo syntax e.g.: > >role Object does Compare[Object, =:=] >role Numdoes Compare[Num, ==] >role Strdoes Compare[Str, eq] What is the implication of from the perspective of the person using Object, Num and Str? Do they have one unified comparator? If so, this sounds like you are subverting MMD with some odd currying of the 'compare' method (whatever it's name may be) provided by the Compare role, instead of relying on the already existing semantics of MMD dispatch to give you the same name for several, superficially same meanings. > The driving idea here is that the syntactical choice of the programmer > amounts to a type preference of the Comparer subtype. Do you mean on a per class or per comparison basis? I think that exceptions from the class perspective should not be done by parametrising the quality role, but overriding it, and that from the per comparison perspective we need to say either: coerce_to_other_type($value) generic_equality coerce_to_other_type($other_value) like: +$x eqv +$y; or: ~$x eqv ~$y; and being an operator rich language we can specificate the generic comparator to make things a bit more fun like I proposed: $x +eqv $y; $x ~eqv $y; Ofcourse, I think that s/eqv/==/;, but everyone hates that. > I fully agree that the number of standard Comparers should be kept > small---that is close to three, not counting ~~ as a Comparer but > as (the only) Matcher. I'm glad that you guys think so too =) -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: : neeyah! pgpUFzxDKzPTd.pgp Description: PGP signature
Re: ~ and + vs. generic eq
On Wed, Aug 24, 2005 at 16:57:30 +1000, Damian Conway wrote: This is what the operators mean to me: > =:= The right side and the left are the same thing, in the sense that: $x =:= $y; # if this is true $x.mutating_method; # and one side is changed $x =:= $y; # then this will always still be true This may describe either truely the same space in memory, or some sort of proxying. One scenario under which I think it's OK if they are not the same location in memory is if I have two proxy handles into the same remote object. They represent the same object, and are randomly interchangable in any point in the control flow. > ~~ Does the right side describe the left side? Is the left side "like" what the right side defines? This is variadic depending on the right side, WRT to the shape and type of the right side. It's truely a smart (polymorphic, dwimmy) match (the right side can describe any number of values) operator, and not equality in any sense. > == > eq > eqv > equals For all of these, The two are equal - the same value, but not necessarily the same thing: $x == $y; # if this is true (assume generic equality) $x.mutating_method; # and one side is changed $x == $y; # this might not be true anymore As I see it ==, eq, eqv and equals are overly verbose and redundant options for checking this same property WRT to the values involved. When we want to be truely sure that we are comparing the two values on a certain dimension of equality (numeric, stringwise or natural equality, as denoted by ==, eq and equals (not eqv if the previous posts in this thread are used)) then we force it anyway. In perl 5 when I want my code to be readable I don't say if (@array == @other) because I find that confusing. I try to remember to say: if (scalar(@array) = scalar(@array)) so that it's obvious I'm comparing a coercion of the array's value. Furthermore, I find even this repulsive... What kind of scalar value? Perl 6 has the ability to make this obvious by using the now standard prefixes: ~ - as a string + - as a number ? - as a boolean all of which are special cases of "natural" equality. When I say if ([EMAIL PROTECTED] == [EMAIL PROTECTED]) it's more obvious that I'm treating these as numerical values (I may be tempted to say @array.elems if i really want to be clear, but that's besides the point). If I say @array == @other, it's clear to someone ***WITH A PERL 5 BACKGROUND** that i'm forcing the array into numerical context, and then comparing that instead. I for one know that I'll always write if (... eqv ...) in perl 6, to avoid my tendency to compare strings and objects as numbers. I deeply regret that people from other language will mock me for having such an ugly operator, and that everyone who doesn't care enough will use == in a way that is broken 5% of the time. I regret most deeply of all that the amount inertia that == and eqv have is so imbalanced and unfair, that no one will implement 'eqv' for generic equality in their own classes, and we'll have something that looks like 'use overload' in perl 5. Oh well. > Do we really need even that many??? At the risk of sounding like a broken record, i think not -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: : neeyah! pgpN0hMFxD0BH.pgp Description: PGP signature
Re: ~ and + vs. generic eq
HaloO, Damian Conway wrote: Just a meta-point...one thing we really do need to be careful of is not ending up with 17 different "equality" operators (like certain languages I shall refrain from naming). So far we're contemplating: =:= ~~ == eq eqv equals Do we really need even that many??? My opinion is there should be a role Compare that takes a Comparer as one of it's parameters. For the above we have in pseudo syntax e.g.: role Object does Compare[Object, =:=] role Numdoes Compare[Num, ==] role Strdoes Compare[Str, eq] ::eqv ::= none(=:=); # non-Object Comparer The difficult part is the definition of inhomogenious cases by means of MMD unless we can form supertypes of Comparers easily: role Foo does Compare[Object|Num, =:= | ==] or with set syntax and a bit de-sugared on the op: role Foo does Compare[(Object,Num), (&infix:<=:=>, &infix:<==>)] The driving idea here is that the syntactical choice of the programmer amounts to a type preference of the Comparer subtype. I fully agree that the number of standard Comparers should be kept small---that is close to three, not counting ~~ as a Comparer but as (the only) Matcher. -- $TSa.greeting := "HaloO"; # mind the echo!
Re: ~ and + vs. generic eq
On Tue, Aug 23, 2005 at 16:32:37 -0700, Larry Wall wrote: > Hmm, well, I don't think >>&op<< is valid syntax, but you did say > "semantics", so I can't criticize that part. :-) What is >><<, btw? Is it &circumfix:{'>>','<<'} (Code &op --> Code); # takes some code, returns a listop or &precircumfix:{'>>','<<'} (Code &op, [EMAIL PROTECTED] --> List); > 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. Right... Magic is defined in the "base" definitions of ~~: &infix:<~~> ($x, Rule $r) { ... } &infix:<~~> ($x, Code &test) { code($x) } And so on and so forth, and then it is extended by the extender to make cool aggregate operations, but even this doesn't have to be the same for ~~ and eqv, it's just that eqv should have good builtins for collections, is all. > 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). Well, when I use it as if (@array eqv [1, 2, 3]) { } I think it's obvious that I'm checking "what is the value right now", and ditto when I say my $str = "foo"; $hash{$str} = 1; $str ~= "bar"; $hash{$str}; # not the same Arguably use of an array as a hash key is using a reference to a container, and use of a scalar as a hash key is using the value inside a container, so in a sense the hash key didn't change when I appended the string, but this distinction is subtle and mostly an implementation detail. > 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" } eqvs! it pronounces very well: 'eekyoovies'. Try it: if 1 2 3 eekyooviesses 1 2 3 say true, otherwise say false It's fun, but I hate it even more than eqv ;-) > 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" } But ~~ is not "is the same" it's "matches". This is also true, and not what I want eqv for: if [1, 2, 3] ~~ [code { 1 }, rx/\d+/, Num] { 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" } I think the opposite is better, make snapshotting by default, and mutable value equality false by saying [1, 2, 3] eqv [1, 2, 3] :always # or :forever -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: *shu*rik*en*sh*u*rik*en*s*hur*i*ke*n*: neeyah pgpqB6BHxX5TY.pgp Description: PGP signature
Re: ~ and + vs. generic eq
Larry wrote: 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.) Just a meta-point...one thing we really do need to be careful of is not ending up with 17 different "equality" operators (like certain languages I shall refrain from naming). So far we're contemplating: =:= ~~ == eq eqv equals Do we really need even that many??? Damian
Re: ~ and + vs. generic eq
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
Re: ~ and + vs. generic eq
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? -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me does a karate-chop-flip: neeyah!! pgpvpO6wniHfk.pgp Description: PGP signature
Re: ~ and + vs. generic eq
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", which has the benefit of looking more Huffmanly abstract to Perl 5 and C programmers. Otherwise we lose the main point of being an operator-rich language, which is to use the operators to drive coercion in the common cases instead continually casting between strings and numbers. Larry
Re: ~ and + vs. generic eq
On Tue, Aug 23, 2005 at 18:15:07 +0200, Ingo Blechschmidt wrote: > sorry, I've some problems with this proposal: > > == has always meant numeric equality in Perl and I'd like it to stay > that way. For "simple" values like numbers and strings == is numberic, because it's affinity to it. > > "10" == 10; # dispatched to Num, by means of coercion (== has some > > affinity to it for backwards compatibility) I guess the difference is that this will fallback to dispatching to strings if "10" can't be numified. I think what sets perl 6 apart from perl 5 is that it's 95% as optimized for "simple" values as perl 5 was, but a magnitude times better for complex types (first class functions, better objects), and in this sense generic equality is a place I find the current spec lacking. > More importantly, the distinction between +== and ~== is far too subtle, > I think -- the two long =s kind of hide the +~?. You have to look more > carefully to see the distinction between +== and ~==; == vs. eq is much > more apparent, IMHO. Arguably it should only matter when it's explicitly stated, so in this case I think your argument is very strong. The only difference is that I don't feel that ~== and +== are very close to == visually, and although they are hard to distinguish, they do stand apart from just bare ==. > > Oh and +== isn't as good huffmanized as == is. 99% of the time you should use == for numbers anyway... It's unambiguous. > > The "matchic MMD generator" in the prelude, that makes the complex > > set of rules found in s04 should simply apply to any infix operator > > (and should be applied in the prelude to ~~, as well as ==), so that > > ~~ and == on collections are defined with the same aggregate > > semantics, but MMD ~~ or == applies to the nested elements in the > > same "shape": > > > > sub extend_comparators (&op) { > [...] > > I think I like that idea, although I have to admit that I might have not > understood it fully. > > I wonder whether it's possible to use an adverbial modifier to specify > the comparator: > > say @foo ~~ @bar; # is really > say @foo ~~ @bar :comparator{ $^a ~~ $^b }; > > say @foo ~~ @bar :comparator{ $^a eq $^b }; > say @foo ~~ @bar :comparator{ $^a == $^b }; In this example I would say my sub comparator ($a, $b) { .. your comparison here }; Prelude::extend_comparators(&comparator); say comparator(@foo @bar); and the name "comparator" could be a lexically scoped &infix:<~~> just the same. It's not as short, but I'm sure an evil macro could be cooked up if it recurrs. We can even specify multi &infix:<~~> (Any $a, Any $b, :&comparator) { # what is the # syntax for mandatory positionals nowadays? my &augmented = &comparator; # a copy Prelude::extend_comparators(&augmented); &augmented($a, $b); } And have your interface wrap around this behavior. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me beats up some cheese: neeyah! pgpT5UYfABJHt.pgp Description: PGP signature
Re: ~ and + vs. generic eq
Hi, Yuval Kogman wrote: > I think this is more consistent, and just as useful: > > 10 == 10; # dispatches to num > "10" == 10; # dispatched to Num, by means of coercion (== has some > affinity to it for backwards compatibility) "10" == "10"; # dispatches > to Str, due to better match "10.0" == "10"; # unlike perl 5 this is > false "10.0" +== "10"; # but this is true > 10 ~== 10; # like eq sorry, I've some problems with this proposal: == has always meant numeric equality in Perl and I'd like it to stay that way. More importantly, the distinction between +== and ~== is far too subtle, I think -- the two long =s kind of hide the +~?. You have to look more carefully to see the distinction between +== and ~==; == vs. eq is much more apparent, IMHO. Oh and +== isn't as good huffmanized as == is. > The "matchic MMD generator" in the prelude, that makes the complex > set of rules found in s04 should simply apply to any infix operator > (and should be applied in the prelude to ~~, as well as ==), so that > ~~ and == on collections are defined with the same aggregate > semantics, but MMD ~~ or == applies to the nested elements in the > same "shape": > > sub extend_comparators (&op) { [...] I think I like that idea, although I have to admit that I might have not understood it fully. I wonder whether it's possible to use an adverbial modifier to specify the comparator: say @foo ~~ @bar; # is really say @foo ~~ @bar :comparator{ $^a ~~ $^b }; say @foo ~~ @bar :comparator{ $^a eq $^b }; say @foo ~~ @bar :comparator{ $^a == $^b }; --Ingo -- Linux, the choice of a GNU | "The future is here. It's just not widely generation on a dual AMD | distributed yet." -- William Gibson Athlon!|
~ and + vs. generic eq
I don't like eqv, because it's ugly, inconsistent with anything else in Perl 6, especially &&, ||, and ^^. It might be forced to fit into the and, or, and xor family, but you'd expect to find 'eq' there, and that's not what it means. IMHO == is as "generic" as && and ||, and is even more like ^^ since it also returns a boolean. the v in eqv is not much of a mnemonic, and overall looks like a typo more than a meaningful distinction. Furthermore, people culturally lean towards '==' for generic equality, and that's what 99% of 'use overload' uses choose on the CPAN. Moreover, after a while of programming only "real" apps, that is, few throw-away scripts (i think it was a period of 2-3 months) I suddenly found myself comparing strings with == in such scripts. I think this is more consistent, and just as useful: 10 == 10; # dispatches to num "10" == 10; # dispatched to Num, by means of coercion (== has some affinity to it for backwards compatibility) "10" == "10"; # dispatches to Str, due to better match "10.0" == "10"; # unlike perl 5 this is false "10.0" +== "10"; # but this is true 10 ~== 10; # like eq $obj == $obj; # if $obj.ref implements ==, then goody, if not, i guess it numifies, or falls back to =:= or whatever identity equality is this week $obj eq $obj; # just a wrapper for == that is parsed with lower precedence $obj +== $obj; # numifies $obj ~== $obj; # stringifies @array +== @array; # length @array == @array; # nested Here are some reference implementations: sub &infix:<+==> (Any $l, Any $r --> Bool) { +$l == +$r } sub &infix:<~==> (Any $l, Any $r --> Bool) { ~$l == ~$r } sub &infix: (Any $l, Any $r --> Bool) { ?$l == ?$r } # useless? multi sub &infix:<==> (Num $l, Num $r --> Bool) { ... } multi sub &infix:<==> (Str $l, Str $r --> Bool) { ... } multi sub &infix:<==> (@l, @r --> Bool) { @l.elems +== @r.elems and @l >>==<< @r } sub &infix: (Any $l, Any $r) is tighter(&infix:) { $l == $r } The behavior of == is akin to ~~, for example regarding: Array Array arrays are identical match if $_ >>=<< @x extracted from S04. The "matchic MMD generator" in the prelude, that makes the complex set of rules found in s04 should simply apply to any infix operator (and should be applied in the prelude to ~~, as well as ==), so that ~~ and == on collections are defined with the same aggregate semantics, but MMD ~~ or == applies to the nested elements in the same "shape": sub extend_comparators (&op) { ... my sub apply_to_arrays (Code &op, Array @l, Array @r) { @l >>&op<< @r } &op.add_mmd_variant(&apply_to_arrays.assuming(&op); } for (&infix:<~~> &infix:<==>) &extend_comparators; -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me whallops greyface with a fnord: neeyah!!! pgpISVweS3ChC.pgp Description: PGP signature