develooper Front page | perl.perl6.language | Postings from August 2006

Re: === and array-refs

Thread Previous | Thread Next
Darren Duncan
August 15, 2006 18:39
Re: === and array-refs
Message ID:
It seems to me that there is some confusion being given in this 
thread and the most recent parts of its predecessor (which can lead 
to FUD in the wrong hands), so I'll briefly try to clear it up, as I 
would like to think I understand the issues.

At 2:51 PM -0600 8/15/06, David Green wrote:
>On 8/14/06, Smylers wrote:
>>David Green writes:
>>>  I guess my problem is that [1,2] *feels* like it should === [1,2].
>>>  You can explain that there's this mutable object stuff going on, and I
>>>  can follow that (sort of...), but it seems like an implementation
>>>  detail leaking out.

There are no implementation details leaking out, but rather we are 
just dealing with the declared interface behaviour of different types 
and operators.

>I agree that \@orig should be distinct from [@orig] -- in the former 
>case, we're deliberately taking a reference to the @orig variable. 
>What I don't like is that [@orig] is distinct from [@orig] -- sure, 
>I'm doing something similar to Array->new(1,2) followed by another 
>Array->new(1,2), but I still want them to be the same, just as I 
>want Str->new("foo") to be the same as Str->new("foo").  They're 
>just constants, they should compare equally regardless of how I 
>created them.  (And arrays should work a lot like strings, because 
>at some conceptual level, a string is an array [of characters].)

You are right, but we have both Seq and Array types, so depending 
which one you use, you want either the === or eqv operators to do 
what you want.  There is no reason that === should say 2 Array are 
equal; we have eqv for that, or use 2 Seq instead of 2 Array if you 
want === to return true on the same values.

So, (1,2) always === and eqv (1,2), but [1,2] only eqv [1,2] and 
[1,2] generally !=== [1,2].

First of all, in Perl 6, there are no separate "arrays" and "array 
refs"; we simply have the 'Array' type, which is treated as a lump on 
its own.

More generally, there are no "reference" types in Perl 6.  We do have 
a concept of multiple symbols being aliases for the same container, 
and they only come to be that way if they are explicitly aliased, 
such as with "$a := $b"; only in those cases, the operator =:=, which 
sees if 2 symbols represent the same container, would return true. 
If you create 2 values separately and don't explicitly alias them 
like that, =:= will return false, even if the 2 containers have 
appearances of the same value.

Both the === and eqv operators test the actual values of 2 
containers, but that their semantics differ in regards to mutable 
containers.  Given an immutable container/type, such as a number or 
Str or Seq, both will always return true if the values are the same. 
With a mutable container, such as an Array, only eqv will return true 
if the value is the same, and === will return false for 2 containers 
having the same value.

The difference between === and eqv is that, if you have 2 symbols, $a 
and $b, and $a === $b returns true, then that result is guaranteed to 
be eternal if you don't assign to either symbol afterwards.  For a 
mutable type like an Array, === returns false on 2 containers because 
it can't guarantee that someone else holding another symbol for 
either container won't change its content, and so $a or $b could 
change after we made the === test, without us causing that to happen, 
and so for mutable types, === only returns true for 2 aliases, 
because that is the most it can guarantee that they will be the same. 
By contrast, eqv does not make the eternal guarantee, and works only 
on snapshots, so eqv can safely deep-compare mutable types like 
Arrays, since even if one of them changes afterwards, it doesn't 
matter, since eqv only guaranteed them equal for that point in time 
when it executed.

It is important for some applications to distinguish whether the 
result of an equivalence test will be valid eternally or not, and 
hence we have multiple analagous types and multiple equality tests, 
where pairwise they distinguish eternally vs snapshot.  We can say 
exactly what we mean, and it is unambiguous, which is a GOOD thing.

-- Darren Duncan

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About