|
In the previous post, we saw an interesting implementation for the factorial function: sub fac(Int $n) { [*] 1..$n } Okay, so how does that work? Perl 6 has a number of different "meta operators" that modify the existing operators to perform more powerful functions. The square brackets about are an example of the "reduce metaoperator"; they cause an infix operator to become a list operator that acts as though the infix was placed between each pair of elements. For example, the statement [+] 1, $a, 5, $b is essentially the same as writing 1 + $a + 5 + $b This gives us a handy mechanism to "sum all elements in a list": $sum = [+] @a; # sum all elements of @a Most of the infix operators (including user-defined operators) can be placed inside of square brackets to turn them into reductions: $prod = [*] @a; # multiply all elements of @a $mean = ([+] @a) / @a; # calculate mean of @a $sorted = [<=] @a; # true if elements of @a are numerically sorted $min = [min] @a, @b; # find the smallest element of @a and @b combined So, in the factorial subroutine above, the expression Another useful metaoperator is the "hyper" operator. Placing @c = @a »+« @b; In Perl 5, we'd generally write something like for ($i = 0; $i < @a; $i++) { $c[$i] = $a[$i] + $b[$i]; } which is quite a bit longer. As with the square brackets above, we can use hyper on a variety of operators, including user-defined operators: # increment all elements of @xyz @xyz»++ # each element of @x is the smaller of @a and @b @x = @a »min« @b; We can also flip the angles to enable a scalar to act like an array: # multiply each element of @a by 3.5 @b = @a »*» 3.5; # multiply each element of @x by $m and add $b @y = @x »*» $m »+» $b; # invert all elements of @x @inv = 1 «/« @x; # concatenate @last, @first to produce @full @full = (@last »~» ', ') »~« @first; Of course, reductions and hyper operators can be combined in expressions: # calculate the sum of squares of @x $sumsq = [+] ( @x »**» 2); There are many other metaoperators available, including $a += 5; # same as $a = $a + 5; $b //= 7; # same as $b = $b // 7; $c min= $d; # same as $c = $c min $d; |