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^
.
Nice, but flipflop operators are not yet implemented in Rakudo Nom :-(-
Flip-flop isn’t implememented in Rakudo yet, but it is implemented in Niecza. I should have mentioned that.
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++
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?)
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. :-)
any example show the diffrence
between ff and fff ?