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); # 7

Here * + * 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 range

In @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 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.

  1. Whatever with map
  2. A two-argument Whatever
  3. An open-ended range

Course navigation

Quiz — Slurpy parameters   |   Whatever with map