Centenary Sequences with Raku

Part 3# Not True, or Not

by Arne Sommer

Part 3

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
(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.