Rakudo gives some strange results when sorting a list
of mixed strings and numbers, which leads me to look
for some clarification on infix:<cmp> (which S03:2866 says
that sort uses by default). Here's the case I found
in Rakudo:
> say ('a', 1, 'b', 2 , 'c', 3, 'd', 4).sort.perl;
["a", "b", "c", 1, 2, 3, 4, "d"]
After tracking it down a bit -- it's not clear what
infix:<cmp> should do when given arguments of differing
types. S03:2855 says:
Binary C<cmp> is no longer the comparison operator that
forces stringification. Use the C<leg> operator for the old PerlĀ 5
C<cmp> semantics. The C<cmp> is just like the C<eqv> above except that
instead of returning C<Bool::False> or C<Bool::True> values it always
returns C<Order::Increase>, C<Order::Same>, or C<Order::Decrease>
(which numerify to -1, 0, or +1).
So, since C<cmp> is just like C<eqv>, here's the definition of C<eqv>
for immutable types (S03:2829):
Binary C<eqv> tests equality much like C<===> does, but does
so with "snapshot" semantics rather than "eternal" semantics. For
top-level components of your value that are of immutable types, C<eqv>
is identical in behavior to C<===>.
And if we look at C<===>, we have (S03:2802):
Binary C<===> tests immutable type and value correspondence:
for two value types (that is, immutable types), tests whether
they are the same value (eg. C<1 === 1>); [...]
Two values are never equivalent unless they are of exactly
the same type.
This means that C< 3 === '3' > would be false, and
since C<eqv> is identical to C<===> for immutable types,
C< 3 eqv '3' > would also be false.
But what to do with something like C< 3 cmp '3' >, or any
infix:<cmp> where the operands are of differing types?
Unlike C<eqv> and C<===> that can simply return false for
arguments of different types, C<cmp> wants to return an
ordering. Do we constrain C<cmp> to only work on similarly-typed
operands (in which case my sort above would fail), or am I
overlooking something obvious?
Pm