Day 10 – Feed operators

Day 10 – Feed operators

Anyone who has programmed in Perl 5 for a while has probably run across or written code similar to this:

    my @new = sort { ... } map { ... } grep { ... } @original;

In this construction, the data flows from the @original array which feeds into the grep, and that, in turn, feeds into the map, and then into the sort, and then finally, the result is assigned to the @new array. Because they each take a list as their final parameter, simply by juxtposition, the data feeds leftward from one operation to the next.

Perl 6, on the other hand, makes this idea of data flowing from one operation to another explicit by introducing the feed operator. The above Perl 5 code could be written like this in Perl 6:

    my @new <== sort { ... } <== map { ... } <== grep { ... } <== @original;

Note that TMTOWTDI is alive and well in Perl 6. You could have also written much the same as in Perl 5:

    my @new = sort { ... }, map { ... }, grep { ... }, @original;

The only difference would be the addition of commas.

So, what do we gain from these feed operators? Normally, when reading code, you read from left to right. In the original Perl 5 code you would read from left to right until you realize that you’re dealing with constructions where the direction of flow is right to left, then you jump to the end and follow the processing in a right-to-left manner. In Perl 6 there is now a prominent syntactic marker that clues you in to the leftward flowing nature of the data.

Still, the right-to-left nature of this code is somewhat troublesome. It may not seem so onerous if all of the code fits on one line as above. But imagine if the blocks associated with grep, map, and sort were little longer. Finding the end of the statement could be a bit annoying.

Luckily, Perl 6 has another feed operator that allows you to write the same code in a left-to-right fashion:

    @original ==> grep { ... } ==> map { ... } ==> sort { ... }  ==> my @new;

This works exactly the same as before only the direction of flow has been changed.

Here are a couple of examples of real, working Perl 6 code using the feed operators:

    my @random-nums = (1..100).pick(*);
    my @odds-squared <== sort() <== map { $_ ** 2 } <== grep { $_ % 2 } <== @random-nums;
    say ~@odds-squared;
    my @rakudo-people = <scott patrick carl moritz jonathan jerry stephen>;
    @rakudo-people ==> grep { /at/ } ==> map { .ucfirst } ==> my @who-it's-at;
    say ~@who-it's-at;

4 thoughts on “Day 10 – Feed operators

  1. I thought the “==>” way differs from the “=” way because it is lazy, or is this not so? So it would not be the same in all situations.

    1. Oh man, tell me about it.

      I do a lot of work in both Perl 5 and Perl 6. Going back and forth, I usually put in too many commas or too few, at least until the first compilation at which point my brain’s internal flags tend to update.

      Perl 6 takes the consistent route here. Perl 5 special-cases map/grep/sort syntax a bit to save you a comma. It’s possible to argue successfully for either solution, and I kinda like them both in their own way.

      If it’s any consolation, going back and forth between the two languages does help. I still make them mistakes, but less and less.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s