Course of Raku / Advanced / Subroutines
The Whatever star 🆕
You may have seen the * used in expressions like
* * 2 or * %% 2 when calling map
and grep. That * is the Whatever
star, and the expression around it builds a small one-argument
function on the fly. This section explains what it really is, how it
relates to a block, and where the bare star means simply “whatever you
want”.
A star makes a function
When * appears in an expression, Raku turns the whole
expression into a function — a WhateverCode — in which the
star stands for the argument:
my $double = * * 2;
say $double.^name; # WhateverCode
say $double(21); # 42* * 2 is a function that multiplies its one argument by
two. This is why (1..5).map(* * 2) works: map
is handed exactly such a one-argument function.
Whatever versus a block
A Whatever expression is a shorter way of writing a function you could also write as a block. These three are equivalent:
* * 2
{ $_ * 2 }
-> $x { $x * 2 }The Whatever form names no parameter; the block form uses the topic
variable $_; the pointy form names $x. That
last one, -> $x { ... }, is a small function in its own
right — you will meet it properly in Anonymous subroutines; here
it is enough to read it as a third way to spell the same one-argument
function. For a simple expression the star is the most compact, which is
why it is so common with map, grep, and
sort:
say (1..5).map(* * 2); # (2 4 6 8 10)
say (1..5).map({ $_ * 2 }); # (2 4 6 8 10)
say (1..5).map(-> $x { $x * 2 }); # (2 4 6 8 10)Reach for a block when the logic needs more than one expression, or when a clearer named parameter helps. Reach for the star when a short expression says it all.
More than one star
Each * in the expression is a separate argument, in
order. So two stars make a two-argument function:
my $add = * + *;
say $add(3, 4); # 7Here * + * is a two-argument function that adds its
arguments — for example a running total and the next element.
The bare Whatever
On its own, * means “whatever” — as much as there is, or
no limit. Two everyday uses:
my @a = 10, 20, 30;
say @a[*-1]; # 30 — * is the array length, so *-1 is the last index
say (1..*).head(3); # (1 2 3) — 1..* is an open-ended rangeIn @a[*-1] the star stands for the number of elements,
and in 1..* it stands for “no upper bound”. Whether it
builds a function or means “whatever you want”, the star is one of
Raku’s most useful pieces of shorthand.
Practice
Complete the 1 quiz that covers the contents of this topic.
Exercises
This section contains 3 exercises. Examine all the topics of this section before doing the coding practice.