See also: The Introduction | Part 1: Raku Part 2: Arithmetic and Geometric Sequences
1
will evaluate to True
in Boolean context, so we can set up a
True Forever Sequence like this:
(1, 1 ... Inf) # 022
> say (1, 1 ... Inf)[^30];
(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
Using Inf
as the upper limit may lead you to think that we are expecting
the values to grow bigger and bigger. That is certainly not the case here, but that
is quite alright.
This does not work, even if the values are lower than the upper limit:
> say (1, 1 ... 2)[^10];
(Nil Nil Nil Nil Nil Nil Nil Nil Nil Nil)
Using -Inf
does work, though it is unwise:
> say (1, 1 ... -Inf)[^30];
(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
True
value instead:
This does not work:
> say (True, True ... Inf)[^10];
(True 1 1 1 1 1 1 1 1 1)
Using a rule works:
(True, !!* ... Inf) # 023a
> say (True, !!* ... Inf)[^10];
(True True True True True True True True True True)
We start with True
. The next value uses *
to access the
previous value (True
). We cannot use *
on its own, but
applying the Negating Operator !
twice, to get back to True
,
works:
But it is better to enforce Boolean context with the ?
or so
operators:
(True, so * ... Inf) # 023b
> say (True, so * ... Inf)[^10];
(True True True True True True True True True True)
(True, ? * ... Inf) # 023c
> say (True, ? * ... Inf)[^10];
(True True True True True True True True True True)
See
docs.raku.org/routine/so for more
for more information about the Boolean Context Operator so
.
See
docs.raku.org/routine/? for more
for more information about the Boolean Context Operator ?
.
The gather
/take
construct can also be used here:
gather { loop { take True }} # 023d
> say gather { loop { take True }}[^10]
(True True True True True True True True True True)
> my $true := gather { loop { take True }};
> say $true[^10];
(True True True True True True True True True True)
:=
) to a scalar, instead
of the normal assignment to an array. The latter will enforce non-lazy
context, and will go on forever:
> my @true = gather { loop { take True }}; # Will run forever
It is possible to ensure lazy context, with the lazy
keyword, so that we can use an array:
> my @true = lazy gather { loop { take True }}; # Works
> say @true[^10];
(True True True True True True True True True True)
See
docs.raku.org/routine/:=
for more information about the Binding Operator :=
.
See
docs.raku.org/language/statement-prefixes#index-entry-lazy_(statement_prefix)-lazy
for more information about lazy
.
0
and False
, as we did with
1
and True
above:
> (0, 0 ... Inf) # 024
> say (0, 0 ... Inf)[^25];
(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
(False, !!* ... Inf) # 025a
> say (False, !!* ... Inf)[^10];
(False False False False False False False False False False)
(False, so * ... Inf) # 025b
> say (False, so * ... Inf)[^10];
(False False False False False False False False False False)
(False, ? * ... Inf) # 025c
> say (False, ? * ... Inf)[^10];
(False False False False False False False False False False)
gather { loop { take False }} # 025d
> say gather { loop { take False }}[^10];
(False False False False False False False False False False)
1
and 0
is easy to set up with gather
/take
:
gather { loop { take 1; take 0 }} # 026
> say gather { loop { take 1; take 0 }}[^10];
(1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0)
True
and False
:
(True, !* ... Inf) # 027a
> say (True, !* ... Inf)[^10];
(True False True False True False True False True False)
With gather
/take
:
gather { loop { take True; take False }} # 027b
> say gather { loop { take True; take False }}[^10];
(True False True False True False True False True False)
False
2/3 of the time:
gather { loop { take True; take False; take False }} # 028a
> say gather { loop { take True; take False; take False }}[^12];
(True False False True False False True False False True False False)
(There was en error in the example above, spotted by Владимир Никитов. Fixed 6. November).
We can get the same with a Sequence, with a little care:
(True, False, ( * == * ) ... Inf) # 028b
> say (True, False, ( * == * ) ... Inf)[^12];
(True False False True False False True False False True False False)
True
2/3 of the time:
gather { loop { take True; take True; take False }} # 029a
> say gather { loop { take True; take True; take False }}[^12];
(True True False True True False True True False True True False)
As a Sequence, with even more care:
(True, True, False, ( * != * ) ... Inf) # 029b
> say (True, True, False, ( * != * ) ... Inf)[^12];
(True True False True True False True True False True True False)
(1, -* ... inf) # 030
> say (1, -* ... Inf)[^20];
(1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1)
All the Sequences shown so far are reproducible. They give the same result every time you generate them.
We'll conclude this part with some random sequences. The are not sequences in a mathematical sense, but can be useful in a real life situation.
gather { loop { take (True, False).pick }} # 031a
> say gather { loop { take (True, False).pick }}[^10];
(True True True True True False False False False False)
> say gather { loop { take (True, False).pick }}[^10];
(False True True False False False True False False False)
The name is in honour (or actually the opposite) of what is described in the Wikipedia Flip-flop_(politics) article.
Note that the generated sequence is random, but once generated a value at a given index stays the same - as shown below:
> my $random := gather { loop { take (True, False).pick }};
> say $random[^6]; # -> (True False True True False True)
> say $random[^6]; # -> (True False True True False True)
We can achieve the same with a Sequence:
( { (False, True).pick } ... Inf ) # 031b
> say ( { (False, True).pick } ... Inf )[^10];
(True False True False True True True False False True)
> say ( { (False, True).pick } ... Inf )[^10];
(True True False False True True True True False True)
gather { loop { take (1..100).pick }} # 032a
> say gather { loop { take (1..100).pick }}[^15];
(22 15 90 28 22 38 14 31 82 82 59 30 18 60 37)
> say gather { loop { take (1..100).pick }}[^15];
(34 98 10 94 14 73 56 14 80 93 79 29 2 7 73)
As a Sequence:
( { (1..100).pick } ... Inf ) # 032b
> say ( { (1..100).pick } ... Inf )[^15];
(93 3 82 77 90 89 6 67 16 75 3 53 35 44 2)
> say ( { (1..100).pick } ... Inf )[^15];
(59 94 71 69 33 29 30 89 76 14 28 99 18 35 80)
But enough of that. Entropy may not be your cup of tea.