In this issue we’ll briefly talk about practical cases where junctions are really handy — both in syntax and in making the program simpler.
Any-appetizer
Here is an interesting example of how you can use the any-junction in a single operation where you would traditionally should have a loop.
my $a = 40;
my @b = 1..5;
say 'Found the answer' if $a + any(@b) == 42;
Examine the addition $a + any(@b)
. We compare its result with a single number 42
as if any(@b)
were a single integer.
An example of using any
A classical example of using any-junctions is something like this:
say 'There are negative ints' if 1 | -2 | 3 < 0;
An alternative syntax — use a function:
say 'There are negative ints' if any(1, -2, 3) < 0;
Another option — a method:
say 'There are negative ints' if (1, -2, 3).any < 0;
An example of using all
The following examples are similar to the examples from the previous section but employ the all-junction instead:
say 'Only positive ints' if 1 & 2 & 3 > 0; say 'Only positive ints' if all(1, 2, 3) > 0; say 'Only positive ints' if (1, 2, 3).all > 0;
Checking parameters of MAIN
Imagine a program that takes integer numbers from command line. You need to distinguish between the cases when the integers are either all positive or all negative.
One of the possible ways to check the input data is to use multi MAIN
functions and dispatch their calls using the where
clauses.
multi sub MAIN(*@a where @a.elems > 0 && .all ~~ Int && .all > 0) { say 'All positive integers' } multi sub MAIN(*@a where @a.elems > 0 && all(@a) < 0 && all(@a) ~~ Int) { say 'All negative integers' }
I am using two different forms of creating the all-junction: .all
and all(@a)
. You are free to build a WhateverCode block too.
There where
clauses demand that all of the input data (i.e., the elements in @a
) are integers (.all ~~ Int
) and either positive (.all > 0
) or negative (all(@a) < 0
).
Run the program with different input data:
$ raku all-1.raku 10 20 30 All positive integers $ raku all-1.raku -10 -20 -30 All negative integers $ raku all-1.raku -10 -20 30 Usage: all-1.raku [<a> ...] all-1.raku [<a> ...]
Using in subsets
The previous example can be re-written in a different style that introduces new data types to the program:
subset PositiveInt of Int where * > 0; subset PositiveIntArray of Array where .all ~~ PositiveInt && .elems > 0; subset NegativeInt of Int where * < 0; subset NegativeIntArray of Array where .all ~~ NegativeInt && .elems > 0; multi sub MAIN(*@a where * ~~ PositiveIntArray) { say 'All positive integers' } multi sub MAIN(*@a where * ~~ NegativeIntArray) { say 'All negative integers' }
The subsets define the rules, and you can use them directly in the where
clauses in other functions.
* * *
Find the code of this issue on GitHub and browse for more Raku Pearls.