Skip to content

Commit 80c0da6

Browse files
committed
Document .toggle method
This is how it fits into my brain. Feel free to reword/rewrite if the description is confusing. Closes #1716 Rakudo impl: rakudo/rakudo@78caeb6bceb5ab99 Spec: Raku/roast@0bca7906b7
1 parent ec139cb commit 80c0da6

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

doc/Type/Any.pod6

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,95 @@ Returns an empty List.
729729
730730
say Any.kv; # OUTPUT: «()␤»
731731
732+
=head2 method toggle
733+
734+
Defined as:
735+
736+
method toggle(Any:D: *@conditions where .all ~~ Callable:D, Bool :$off --> Seq:D)
737+
738+
L<Iterates|/routine/iterator> over the invocant, producing a L<Seq>, toggling
739+
whether the received values are propagated to the result on and off, depending
740+
on the results of calling L<Callables|/type/Callable> in C<@conditions>:
741+
742+
say ^10 .toggle: * < 4, * %% 2, &is-prime; # OUTPUT: «(0 1 2 3 6 7)␤»
743+
say ^10 .toggle: :off, * > 4; # OUTPUT: «(5 6 7 8 9)␤»
744+
745+
Imagine a switch that's either on or off (C<True> or C<False>), and values are
746+
produced if it's on. By default, the initial state of that switch is in "on"
747+
position, unless C<:$off> is set to a true value, in which case the initial
748+
state will be "off".
749+
750+
A L<Callable> from the L<head> of C<@conditions> is taken (if any are available)
751+
and it becomes the current tester. Each value from the original sequence is
752+
tested by calling the tester L<Callable> with that value. The state of our
753+
imaginary switch is set to the return value from the tester: if it's thruthy,
754+
set switch to "on", otherwise set it to "off".
755+
756+
Whenever the switch is I<toggled> (i.e. switched from "off" to "on" or
757+
from "on" to "off"), the current tester L<Callable> is replaced by the next
758+
L<Callable> in C<@conditions>, if available, which will be used to test any
759+
further values. If no more tester Callables are available, the switch will
760+
remain in its current state until the end of iteration.
761+
762+
=begin code
763+
# our original sequence of elements:
764+
say list ^10; # OUTPUT: «(0 1 2 3 4 5 6 7 8 9)␤»
765+
# toggled result:
766+
say ^10 .toggle: * < 4, * %% 2, &is-prime; # OUTPUT: «(0 1 2 3 6 7)␤»
767+
768+
# First tester Callable is `* < 4` and initial state of switch is "on".
769+
# As we iterate over our original sequence:
770+
# 0 => 0 < 4 === True switch is on, value gets into result, switch is
771+
# untoggled, so we keep using the same Callable:
772+
# 1 => 1 < 4 === True same
773+
# 2 => 2 < 4 === True same
774+
# 3 => 3 < 4 === True same
775+
# 4 => 4 < 4 === False switch is now off, "4" does not make it into the
776+
# result. In addition, our switch got toggled, so
777+
# we're switching to the next tester Callable
778+
# 5 => 5 %% 2 === False switch is still off, keep trying to find a value
779+
# 6 => 6 %% 2 === True switch is now on, take "6" into result. The switch
780+
# toggled, so we'll use the next tester Callable
781+
# 7 => is-prime(7) === True switch is still on, take value and keep going
782+
# 8 => is-prime(8) === False switch is now off, "8" does not make it into
783+
# the result. The switch got toggled, but we
784+
# don't have any more tester Callables, so it
785+
# will remain off for the rest of the sequence.
786+
=end code
787+
788+
Since the toggle of the switch's state loads the next tester L<Callable>,
789+
setting C<:$off> to a C<True> value affects when first tester is discarded:
790+
791+
=begin code
792+
# our original sequence of elements:
793+
say <0 1 2>; # OUTPUT: «(0 1 2)␤»
794+
# toggled result:
795+
say <0 1 2>.toggle: * > 1; # OUTPUT: «()␤»
796+
797+
# First tester Callable is `* > 1` and initial state of switch is "on".
798+
# As we iterate over our original sequence:
799+
# 0 => 0 > 1 === False switch is off, "0" does not make it into result.
800+
# In addition, switch got toggled, so we change the
801+
# tester Callable, and since we don't have any more
802+
# of them, the switch will remain "off" until the end
803+
=end code
804+
805+
=begin code
806+
# our original sequence of elements:
807+
say <0 1 2>; # OUTPUT: «(0 1 2)␤»
808+
# toggled result:
809+
say <0 1 2>.toggle: :off, * > 1; # OUTPUT: «(2)␤»
810+
811+
# First tester Callable is `* > 1` and initial state of switch is "off".
812+
# As we iterate over our original sequence:
813+
# 0 => 0 > 1 === False switch is off, "0" does not make it into result.
814+
# The switch did NOT get toggled this time, so we
815+
# keep using our current tester Callable
816+
# 1 => 1 > 1 === False same
817+
# 2 => 2 > 1 === True switch is on, "2" makes it into the result
818+
=end code
819+
820+
732821
=head2 method tree
733822
734823
Defined As:

0 commit comments

Comments
 (0)