On 8/13/06, Smylers wrote:
  Please could the proponets of the various behaviours being discussed
  here share a few more concrete examples which start by explaning a
  scenario in which there is a desire to do something, preferably one
  that Perl 5 coders can identify with, and then show how one of these
  new operators would meet that desire (and that without that operator
  it would be hard or clumsy to achieve the same thing)?

OK, if I can come up with examples that make sense, then that probably means I actually understand it myself!


eqv
...is your standard equality-of-values, which would be just = or == in many languages, and which Perl has never really had. == and eq coerce their operands to be numbers or strings, which was fine back in days or yore when Perl only had nums and strings. With the introduction of references/objects, Perl effectively got user-definable types without a user-definable equality operator, so you either had to rely on suitable numifications (or stringifications) of your objects to make sense, or overload stuff, or something. In P6 you can just compare their values in a "normal" way (or still numify/stringify them using == or eq if that's what you want).

Example: I have a Date class that lets each of its objects carry around its own different epoch value, so using == won't work (unless both dates that I'm comparing happen to share the same epoch -- a yucky work-around might be "if $a==$b && $a.epoch==$b.epoch"). And let's suppose my Dates are text-insensitive-but-preserving, meaning that objects created as "2006/1/1" and as "Jan. 1, 2006" return those exact strings when stringified, even though they represent the same date: so comparing with eq won't work either.

Instead I want to compare my dates with eqv which compares their "real" values. ("Real" is determined by the class -- this is where the Special Key ID stuff comes in. In this example, the SKID for a date might be an int using a fixed epoch; or it might be a text representation in canonical form. The user doesn't have to care, of course.)

(eqv also means you no longer need code like "if (we're using ints) return $a==$b else if (we've got strings) return $a eq $b", which was occasionally a pain even in those Days of Yore. Now that P6 can use variable types, you don't [necessarily] need to specify the type in the equality operator, you can just use eqv to do the appropriate kind of comparison. (And "cmp" is becoming the analogue of "eqv" instead of "eq".))


===
...is equality-of-contents, basically meaning that the things you're comparing contain the same variables and values. (E.g. things that are references to other variables, possibly nested in some kind of data structure.) Now if you have a couple of plain old ints, then it's the same as testing whether they have the same values ("eqv"). But if $a contains a ref to @x and $b contains a ref to @y, then $a will not === $b. (Unless @x and @y are really the same variable in disguise, of course. $a might *eqv* $b, because @x and @y could have the same value, but as long as $x and $y are different guys, then $a !=== $b. Conversely, if $a does === $b, then they must have the same value too, i.e. it follows that $a eqv $b.)

Example: Suppose I have some employee objects, and I employ two John Smiths. They have the same name, work in the same department, and by stunning coincidence everything my class knows about them just happens to be the same. So they're basically indistinguishable (serialising one John Smith object produces the same results as the other -- and indeed, $john1 eqv $john2). But they're still different objects (the payroll system definitely needs to produce two cheques, although since they earn the same salary, it doesn't matter which one of them gets which cheque); so $john1 !=== $john2, and I can tell them apart.

In fact, === is how a hash tests its keys (assuming it's a hash that uses objects rather than a P5-like hash that uses stringy keys -- of course, for a string hash, === wouldn't work out any different from eqv anyway).


=:=
...is equality-of-variable, or binding -- it simply checks whether its operands are both the same variable (possibly under different names). This might be a little esoteric for "ordinary" code (if there is any such thing), but binding is pretty common in P6, even if inconspicuous: sub foo($a, $b) will bind $x to both $a and $b if I call foo($x, $x). I might want to know whether my $a and $b really are the same variable passed in twice or not.

Example: a fairly simple reason why you might care whether you've got the same variable twice is if you're doing some expensive comparison -- an easy optimisation is to check whether the two things you're comparing are really the same thing to start with.

(Or, going back to my double John Smiths setup, my payroll functions can make sure that all the John Smith really are different people, and not a single object trying to scam the company.)


For reference, I'm including my trivial but technically correct examples from a previous message. (Of course, I'm ignoring funky details like what would happen if your variables are changing while you're trying to compare them, etc.)

Examples:

   @x=<foo bar>;
   @y=<foo bar>;

   $a=[1, 2, [EMAIL PROTECTED];
   $b:=$a;
   $c=[1, 2, [EMAIL PROTECTED];
   $d=[1, 2, [EMAIL PROTECTED];


        $a =:= $b;      #true, same variable with two names
        $a === $b;      #true   _/ $b just another name for $a,
        $a eqv $b;      #true    \ so comparable at all levels

        $a =:= $c;      #false, different variables
        $a === $c;      #true, same elements make up $a and $c
        $a eqv $c;      #true, same elements therefore same values

        $a =:= $d;      #false, different variables
        $a === $d;      #false, [EMAIL PROTECTED] and [EMAIL PROTECTED] are 
different refs
        $a eqv $d;      #true, values of @x and @y happen to be the same


-David

Reply via email to