Front page | perl.perl6.language |
Postings from August 2006
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
Thread Previous
|
Thread Next
From:
David Green
Date:
August 13, 2006 09:46
Subject:
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
Message ID:
a06230911c104d8339717@[172.27.1.7]
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, \@x];
> $b:=$a;
> $c=[1, 2, \@x];
> $d=[1, 2, \@y];
>
>
> $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, \@x and \@y are different refs
> $a eqv $d; #true, values of @x and @y happen to be the same
-David
Thread Previous
|
Thread Next
-
===, =:=, ~~, eq and == revisited (blame ajs!)
by Yuval Kogman
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
by Yuval Kogman
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
by David Green
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
by Larry Wall
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
by Smylers
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
by Charles Bailey
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained
by Jonathan Lang
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
by Darren Duncan
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
by Aaron Sherman
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
by Yuval Kogman
-
Re: ===, =:=, ~~, eq and == revisited (blame ajs!)
by Yuval Kogman