Perl6: comparison operator ~~

The literals you wrote are Arrays:

say WHAT [1,2,3,4] ; # (Array)

Plain Arrays are eagerly evaluated, so their contents are known at all times. So the ~~ operator yields True when applied to Arrays 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.

Seqs 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 Seqs to see if they equivalent because then they'd be exhausted.

So two Seqs 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.

Tags:

Operators

Raku