# Wiki: Raku

Some external Raku golf tips

# The sequence operator (`...`)

This is one of the more powerful tools in Raku, especially for the numerous sequence holes. The general formation is:

``````\$initialisation,&generator...&endpoint
0,1,*+*...*>32  # Fibonacci
``````

These can be mix and matched. If you leave out the initialisation, if the code uses `\$_`, it will take the value of that variable for the first iteration from the outer scope (defaulting to `(Any)` if you're in the base program). If you leave out the generator, it will try to interpolate the sequence from the initial list, otherwise just incrementing the last value. Using `*` as the termination will make it loop forever (if you want until the value is falsey, you'll have to do `?*`).

``````{\$_+1}...10    # (Any) turns into a 0, so this is the range 1 to 10. Note that you can't use *+1
0,2...10       # Even numbers from 0 to 10
1...*          # Infinite range
``````

If a range is assigned to a variable or returned, it will probably stay lazy. If you have it as a base statement, it will be evaluated.

Rather than generate a sequence and then print the values, you can print the values inside either the generator or the termination, as both are executed for each element.

``````(0,1,*+*...*>32)>>.say;
0,1,{say \$^a;\$a+\$^b}...*>32;
0,1,*+*...{.say;\$_>32};
0,1,*+*...*.say+*>35;
``````

## Lambda/Blocks

The generator is a function, which can either be block `{}` or a Whatever lambda. Both of these can take multiple previous elements (as shown above in the Fibonacci example), but the block can also take a list of all the previous elements as `@_` (this is mutually exclusive with `\$_`), or no input at all. Also note that `\$` variables will persist in each block as usual, which can let you keep track of the length of the list, or some persistant value.

``````{@_.sum+@_}...*   # 2**n-1
{2**\$++-1}...*
{2**@_-1}...*
0,2* *+1...*
``````

## Termination

Termination is interesting. Mechanically, it functions like the smartmatch operator (`~~`), which calls the `ACCEPTS` method, which has some interesting interactions. This means you can use:

• String/Number. Obviously, this just terminates when that number or string appears, however it also can convert the element to that type to compare. For example, to terminate when an array reaches a certain size.
• Positional. True if the element exists in the positional (this seems a bit buggy when used on its own).
• Callable. As detailed above, the callable just needs to return something truthy. If the lambda takes more than one input (e.g. `*+*+*`), it will only start executing once the the list reaches that length.
• Regex. This will terminate if the regex matches the element. Useful for bigger numbers or strings when you can safely match only part of the element.
• Pair. For a Hash, this just looks up the value in that hash. Against a pair, it checks the value of the pairs are equal. For everything else, the weirdest (but most useful) interaction is that "the invocant Pair's key is treated as a method name". So practically, `1...:is-prime` will be the same as `1...&is-prime`, which can be combined well with the next item.
• Junction. These are combinations of the above types that will all be called (including with shortcircuiting!). There are three types of useful junctions here, `&|^`, all similar to their bitwise formulations. If you need to terminate for two conditions, you can have a termination `&cond1& &cond2` (or, if you do it right, `&cond1&:cond2`). If you remember that `say` and `put` always return True, this can be combined in some very unique ways, such as
``````1...&say&100;            # Print 1 to 100
1...{\$_%2}&:say&99;      # Print odds from 1 to 99
1...*%2&:say&99;         # Doesn't work, * swallows surroundings
``````

## Example Templates

Most sequence holes involve either filtering from 0 to n, or some transformation of previous elements, so a good start is to use one of these templates:

``````0...&cond&:say&n
1,&gen...&say&n
1,{.say;code}...n
1,&gen...*.say+*>n
1,&gen...&say^ ^n
``````

Remember to be creative with termination conditions, as well as where you put the printing section of the code.