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 [EMAIL PROTECTED] should be distinct from [EMAIL PROTECTED] -- in the former case, we're deliberately taking a reference to the @orig variable. What I don't like is that [EMAIL PROTECTED] is distinct from [EMAIL PROTECTED] -- 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

Reply via email to