Perl6: comparison operator ~~
The literals you wrote are Array
s:
say WHAT [1,2,3,4] ; # (Array)
Plain Array
s are eagerly evaluated, so their contents are known at all times. So the ~~
operator yields True
when applied to Array
s with identical types and contents:
say [1,2,3,4] ~~ [1,2,3,4] ; # True
But you are applying a function, so you must pay attention to what that function returns.
The sort
function returns a Seq
, a sequence, which is a fundamentally different type.
Seq
s are lazily evaluated, so their contents are not computed until they have been completely iterated, exhausting them. It would not make sense to run through two Seq
s to see if they equivalent because then they'd be exhausted.
So two Seq
s whose elements would turn out to be identical are not themselves identical:
say Seq.new([1,2,3,4].iterator) ~~ Seq.new([1,2,3,4].iterator) ; # False
The key observation is that sort
doesn't actually return a list:
> sort([1,2,3,4]).^name
Seq
The documentation for sort seems to be out of date :(. I'll try to fix that soon.
So, a Seq is a sequence, basically an iterator that you can also try to use like a list.
But, in its default mode, when you iterate a Seq
, it doesn't store the old elements, mostly to enable code like
for $filehandle.lines -> $line {
# do something with $line here
}
to not leak memory. (This is comparable to python's iterators.)
So, that's probably why nobody implemented Seq.ACCEPTS
(the smart match operator ~~
calls ACCEPTS
on the right argument) to behave as you would expect in this case, as that might be a destructive operation. So the default ACCEPTS
behavior kicks in, which does an identity comparison, and returns False
.
If you change your code to
> sort([1,2,3,4]) ~~ sort([1,2,3,4]).list
True
it behaves the way you want it to.
I'll discuss with the other Perl 6 developers if Seq.ACCEPTS
could be changed to behave more sensibly.