In Control flow§

See primary documentation in context for for

The for loop iterates over a list, running the statements inside a block once on each iteration. If the block takes parameters, the elements of the list are provided as arguments. By default, the block takes one parameter, $_:

my @foo = 1..3;
for @foo { $_.print } # prints each value contained in @foo 
for @foo { .print }   # same thing, because .print implies a $_ argument 
for @foo { 42.print } # prints 42 as many times as @foo has elements

Pointy block syntax or a placeholder may be used to name the parameter:

my @foo = 1..3;
for @foo -> $item { print $item }
for @foo { print $^item }            # same thing

Multiple parameters can be declared, in which case the iterator takes as many elements from the list as needed before running the block.

my @foo = 1..3;
for @foo.kv -> $idx$val { say "$idx$val" }
my %hash = <a b c> Z=> 1,2,3;
for %hash.kv -> $key$val { say "$key => $val" }
for 11.122.1 { say "$^x < $^y" }  # OUTPUT: «1 < 1.1␤2 < 2.1␤»

Parameters of a pointy block can have default values, allowing the code to handle lists with missing elements.

my @list = 1,2,3,4;
for @list -> $a$b = 'N/A'$c = 'N/A' {
    say "$a $b $c"
}
# OUTPUT: «1 2 3␤4 N/A N/A␤»

When no parameters are specified for a for loop's block, when can be used within it similarly to how it's used in a given block:

# A solution for FizzBuzz: 
for 1..100 {
    when * %% 15 { say 'FizzBuzz' }
    when * %% 3  { say 'Fizz' }
    when * %% 5  { say 'Buzz' }
    default      { say $_ }
}

If the postfix form of for is used, a block is not required and the topic is set for the statement list.

say $_ butterflies! for <♥ ♥ ♥>;
# OUTPUT: «I ♥ butterflies!␤I ♥ butterflies!␤I ♥ butterflies!␤»

A for may be used on lazy lists – it will only take elements from the list when they are needed, so to read a file line by line, you could use:

for $*IN.lines -> $line { .say }

Iteration variables are always lexical, so you don't need to use my to give them the appropriate scope. Also, they are read-only aliases. If you need them to be writable, use <-> instead of ->. Alternatively, you can add the is rw trait; this performs a binding operation so assigning to the parameter changes the value of the variable at the caller side. If instead you want to modify copies of the arguments within the block, add is copy.

my @foo = 1..3;
for @foo <-> $value {
    $value = $value %% 2 ?? "Even" !! "Odd"
}
 
say @foo# OUTPUT: «[Odd Even Odd]␤» 
 
@foo = 1..3;
for @foo -> $value is rw {
    $value = $value %% 2 ?? "Even" !! "Odd"
}
 
say @foo# OUTPUT: «[Odd Even Odd]␤» 
 
@foo = 1..3;
my @bar;
for @foo -> $value is copy {
    $value = $value %% 2 ?? "Even" !! "Odd";
    @bar.push: $value
}
 
say @foo# OUTPUT: «[1 2 3]␤» 
say @bar# OUTPUT: «[Odd Even Odd]␤» 

This rule also applies to the topic variable $_, which by default is a read-write alias; it will become read-only if it's used in a -> loop.

my @foo = 1..3;
for @foo -> $_ { $_.say }
 
# Error: ...require mutable arguments 
for @foo -> $_ { $_++ }

A for loop can produce a List of the values produced by each run of the attached block. To capture these values, put the for loop in parenthesis or assign them to an array:

(for 123 { $_ * 2 }).say;              # OUTPUT: «(2 4 6)␤» 
my @a = do for 123 { $_ * 2 }@a.say# OUTPUT: «[2 4 6]␤» 
my @b = (for 123 { $_ * 2 }); @b.say;  # OUTPUT: «[2 4 6]␤»

This implies that, if the results of the loop are not assigned, they will be in a sink context:

class Sunk {
    has $.titanic;
    method sink {
        say "Sinking $!titanic";
    }
}
Sunk.new:titanic($_) ) for ^3;
for 1 {
    say "About to sink";
    Sunk.new:titanic($_) );
}
# OUTPUT: 
# Sinking 0 
# Sinking 1 
# Sinking 2 
# About to sink 
# Sinking 1 

The first loop creates three elements but they are in a sink context, so its sink method is called. In the second loop, its last statement will be in a sink context, so it will be also sunk (from version 6.d).

The Empty constant will act as a no-op for a loop:

say "Not here" for Empty;

Will not do anything. This constant is equivalent to a empty Slip or List.

Undefined values will behave in the same way:

my @array := Empty;
.say for @array;
say @array# OUTPUT: «()␤» 

Assigning Empty will effectively undefine an Array, using for over an undefined array will not even enter the loop, as shown, effectively behaving in the same way as above when Empty was used directly.

With hyper and race, the for loop is potentially iterated in parallel. See also the documentation for hyper and race in class Map.

my $primes_h = hyper for ^10_000 -> $number { $number if $number.is-prime };
say $primes_h.elems;   # OUTPUT: «1229␤» 
say $primes_h.tail: 5# OUTPUT: «(9931 9941 9949 9967 9973)␤» 

with hyper the order of elements is preserved.

my $primes_r = race for ^10_000 -> $number { $number if $number.is-prime };
say $primes_r.elems# OUTPUT: «1229␤» 

Unlike hyper, race does not preserve the order of elements.