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