📜 ⬆️ ⬇️

Perl 6 / Rakudo Sequences

Perl 6 introduces a new statement ... to define sequences. Here's how it works:

my @even-numbers := 0, 2 ... *; #   my @odd-numbers := 1, 3 ... *; my @powers-of-two := 1, 2, 4 ... *; #   

Usage example:

 > my @powers-of-two := 1, 2, 4 ... *; 1; 1 > @powers-of-two[^10] 1 2 4 8 16 32 64 128 256 512 


(When specifying a geometric sequence in the REPL, which is infinite by definition, I put at the end of the line “1;”. As a result, the REPL outputs one and does not go into an infinite loop.)
')
To limit the endless "lazy" sequence, in the example I used the entry [^ 10], which means "the first ten elements". With this record, the calculated variables are remembered for further use.

The sequence operator ... is a powerful tool for creating lazy lists. If he is given one number, he starts counting from it. If you specify two, he regards them as an arithmetic sequence. If there are three — he checks if they are not the beginning of an arithmetic or geometric sequence — if so, then he continues them.

Of course, many sequences are not arithmetic or geometric. You can explicitly specify a function that defines the following number in the sequence:

 > my @Fibonacci := 0, 1, -> $a, $b { $a + $b } ... *; 1; 1 > @Fibonacci[^10] 0 1 1 2 3 5 8 13 21 34 


The part -> $ a, $ b {$ a + $ b} is a switch block (lambda function), which takes two arguments and returns their sum. The sequence operator calculates how many arguments the block takes and passes the required number from the end of the sequence to generate the next number.

So far, all the examples have an asterisk at the end, meaning “anything.” In this case, the list has no end. If you put a number there, it will be the end of the list.

 > 1, 1.1 ... 2 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 > 1, 1.1 ... 2.01 ...  Rakudo ,     ... > (1, 1.1 ... 2.01)[^14] 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 


The first list ends in a natural way, but the second passes by the limiter. As a result, we get an endless list - so I limited it to 14 elements, just to see what it gives out.

Programmers familiar with floating-point calculations probably grumble that it cannot be assumed that adding 0.1 to the number in succession will necessarily lead to a two. Perl 6 uses Rat math, which ensures the accuracy and availability of such calculations.

If I had to find all Fibonacci numbers less than 10,000, it would be difficult for me to calculate which number will be the last in the sequence. Fortunately, in addition to the block, we can use the block for the boundary condition to specify the sequence formula.

 > 0, 1, -> $a, $b { $a + $b } ... -> $a { $a > 10000 }; 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 


The switch block -> $ a {$ a> 10000} creates a check. It takes one argument and returns true when it becomes more than 10,000.

However, we wanted to get all the numbers less than 10,000. And we got one extra. For our task there is an alternative record of the block of the limiter, in which it is indicated that it is not necessary to include the last number in the sequence:

 > 0, 1, -> $a, $b { $a + $b } ...^ -> $a { $a > 10000 }; 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 


Using the closures "anything", this record can be altered as follows:

 > 0, 1, * + * ...^ * > 10000; 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 


Clearly such a record, or more difficult - you decide.

In addition, on the left side of the sequence can be any list, including a lazy one. That is, you can use a bounding box to get a limited portion of an existing lazy list:

 > my @Fibonacci := 0, 1, * + * ... *; 1; 1 > @Fibonacci ...^ * > 10000 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 > @Fibonacci[30] 832040 


In addition, the sequence operator is not limited to working exclusively with numbers. By setting your own function to calculate the next item in the list, you can compose it from any desired elements.

Source: https://habr.com/ru/post/253047/


All Articles