Name

Yet Another Perl 6 Operator: Comparisons - Part II

Version

Maintainer: Adriano Ferreira <ferreira@cpan.org>
Date: 29 Sep 2007
Last Modified: 2 Oct 2007
Number: 6
Version: 3
Status: Draft

Body

In the the last article, we've seen some of the usual relational operators in Perl 6 and their enhanced syntax through chaining (which allows expressions like a < b < c).

Another kind of comparison operators are those that, instead of true/false returns, identify the relative order between its operands: before, equal, or after.

For numbers, there is the spaceship operator (just like in Perl 5):

0 <=> 1    # returns that 0 is before 1
0 <=> 0    # returns that 0 equals 0
1 <=> 0    # returns that 1 is after 0

But there is a change: instead of -1, 0, 1, the return is Order::Increase, Order::Same, Order::Decrease, the values of an enumeration, which in numeric context reduces into -1, 0, 1.

For strings, the sort comparator was renamed. After the triad le, eq, and gt, it is now called the leg operator.

'a' leg 'b'   # Order::Increase
'a' leg 'a'   # Order::Same
'b' leg 'a'   # Order::Decrease

That was done on purpose, to leave the Perl 5 string sort comparator cmp free to be a generic sort comparison, in the same way that before and after were conceived.

$dt_today cmp $dt_tomorrow  # Order::Increase
$dt_today cmp $dt_today     # Order::Same
$dt_today cmp $dt_yesterday # Order::Decrease

The cmp operator is the operator of choice when comparing any items: numbers, strings, and objects. With respect to numbers and strings, its default is to act just like '<=>' and leg, respectively. In turn, objects may have their comparison behavior customized by the author of the code.

Chaining does not make sense to these operators. But for ordering operations like sorting, finding the minimum and maximum, they are just perfect. Some examples of sorting expressions follow. (Notice that these could be made shorter using the new signatures of the sort method and other Perl 6 novelties.)

@values.sort; # use default 'cmp'
@values.sort: { $^b cmp $^a }; # reverse order

@values.sort: {    $^a<name> leg $^b<name>
                || $^a<id>   <=> $^b<id>   };
    # a sort based on values keyed by 'name' and 'id'
    # respectively

$Revision: 73 $