The Flip-Flop operator

by

Perl 5 has a binary operator called flip-flop that is false until its first argument evaluates to true and it stays true (flips) until the second argument evaluates to true at which point it becomes false again (flops).  This is such a useful operator that Perl 6 also has flip-flop, only it’s spelled ff and has a few variants:

    ff
    ff^
    ^ff
    ^ff^

The circumflex means to skip the end point on that end.

Perhaps some examples are in order …

    for 1..20 { .say if $_ == 9  ff  $_ == 13; }     # 9 10 11 12 13
    for 1..20 { .say if $_ == 9  ff^ $_ == 13; }     # 9 10 11 12
    for 1..20 { .say if $_ == 9 ^ff  $_ == 13; }     #   10 11 12 13
    for 1..20 { .say if $_ == 9 ^ff^ $_ == 13; }     #   10 11 12

In each example we’re iterating over the range of numbers from 1 to 20 and output those numbers where the flip-flop returns true. Both the right hand side of the flip-flop ($_ == 9) and left hand side of the flip-flop ($_ == 13) are evaluated on each iteration of the loop. (I’ve used simple numeric comparison on both sides of the flip-flop operators here but, in general, any boolean expression could be used.)

Each instance of the flip-flop operator maintains it’s own little bit of internal state to decide when to return True or False. All flip-flop operators are born with their internal state set to return False waiting for the moment they can be flipped and start returning True.

In the first and second examples when $_ == 9, the flip-flop operators flips their internal state to True and immediately return True.  In the third and fourth examples when $_ == 9 the flip-flop operators set their internal state to True but they return False on that iteration because of the leading circumflex.

Similarly, in the first and third examples above, once the RHS evaluates to True, the flip-flop operators flop their internal state back to False on next evaluation and return True. In the third and fourth examples, the flip-flops operators flop sooner by returning False immediately upon evaluating the RHS True.

To make the flip-flop operator flip, but never flop, use a * on the RHS:

    for 1..20 { .say if $_ == 15 ff *; }     # 15 16 17 18 19 20

Perl 6 has another set of flip-flop operators that function similar to the ones mentioned above, except the RHS isn’t evaluted when the LHS becomes true. This is particularly important when both the RHS and the LHS of the flip-flop could evaluate to True at the same time. These operators are spelled fff, fff^, ^fff, and ^fff^.

About these ads

7 Responses to “The Flip-Flop operator”

  1. Software Enhanced Politics: Perl Flip-Flop : The Other McCain Says:

    [...] more than most other languages with which you’d care to tangle. The subject of the post is the flip-flop operator, which has massive political application.Perl 5 has a binary operator called flip-flop that is [...]

  2. Gernot Says:

    Nice, but flipflop operators are not yet implemented in Rakudo Nom :-(-

  3. perlpilot Says:

    Flip-flop isn’t implememented in Rakudo yet, but it is implemented in Niecza. I should have mentioned that.

  4. perlpilot Says:

    Mere moments ago, I noticed that jnthn added a preliminary implementation for flip-flop to Rakudo. I haven’t tried it yet, but presumably, if you obtain the latest sources from git and build Rakudo, you should have flip-flop.

    jnthn++

  5. microtherion Says:

    Hmm, is it really true that “Both the right hand side of the flip-flop ($_ == 9) and left hand side of the flip-flop ($_ == 13) are evaluated on each iteration of the loop.” ?

    I would have thought that at least the RHS is only evaluated when the state is true (And possibly that the LHS is only evaluated when the state is false?)

    • perlpilot Says:

      You are correct. It is just like the Perl 5 flip-flop in this respect. I don’t know what I was thinking when I wrote that. :-)

  6. Logger Says:

    any example show the diffrence
    between ff and fff ?

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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


Follow

Get every new post delivered to your Inbox.

Join 37 other followers

%d bloggers like this: