develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About