trait is pure

Documentation for trait is pure, assembled from the following types:

class Routine

From Routine

(Routine) trait is pure

multi sub trait_mod:<is>(Routine $r:$pure!)

Marks a subroutine as pure, that is, it asserts that for the same input, it will always produce the same output without any additional side effects.

You can mark function as pure even if they throw exceptions in edge cases, or if they modify temporary objects; hence the is pure trait can cover cases that the compiler cannot deduce on its own. On the other hand, you might not want to constant-fold functions that produce a large return value (such as the string or list repetition operators, infix x and xx) even if they are pure, to avoid large precompilation files.

The is pure trait is a promise by the programmer to the compiler that it can constant-fold calls to such functions when the arguments are known at compile time.

sub double(Numeric:D $xis pure {
    2 * $x;
}

To see it an action with a particular compiler you can try this example:

sub double-pure($ais pure {
    say pure;
    $a × 2
}
sub double-dirty($a{
    say dirty;
    $a × 2
}
BEGIN { say Begin }
say Start;
say double-pure(40+ double-pure(40for ^2;
say Middle;
say double-dirty(5+ double-dirty(5for ^2;
say End
 
# Example output: 
# Begin 
# pure 
# pure 
# Start 
# 160 
# 160 
# Middle 
# dirty 
# dirty 
# 20 
# dirty 
# dirty 
# 20 
# End 

Essentially this allows the compiler to perform some operations at compile time. The benefits of constant-folding may include better performance, especially in cases when the folded code is precompiled.

In addition, using a pure function or operator in sink context (that is, where the result is discarded) may lead to a warning. The code

sub double($xis pure { 2 * $x };
double(21);
say "anything";
# WARNING: «Useless use of "double(21)" in expression "double(21)" in sink context (line 2)»