The cryptic title should not stop you from seeing bits of the regular Raku code. Namely, the two traits that you can add to function arguments: is rw
and is raw
.
These two traits may look confusing because both allow changing the passed variable:
sub f1($x is rw) { say $x; } sub f2($x is raw) { say $x; } my $a = 42; f1($a); # 42 f2($a); # 42
Neither of the functions changes the value of $a
, but that’s not that important now. They both can, would you add, for example, $x++
in each function:
sub f1($x is rw) { $x++; say $x; } sub f2($x is raw) { $x++; say $x; } my $a = 42; f1($a); # 43 f2($a); # 44
But what if you pass a constant integer value instead of a variable container?
f1(42); f2(42);
It is quite obvious that it is not possible to change a bare integer, which was not boxed in a variable. The call of the first function (having is rw
) fails:
Parameter '$x' expected a writable container, but got Int value in sub f1 at rw.rk line 1 in block <unit> at rw.rk line 15
Let’s comment it out and see what happens to the second call (with is raw
):
Cannot resolve caller postfix:<++>(Int); the following candidates match the type but require mutable arguments: (Mu:D $a is rw) (Int:D $a is rw) The following do not match for other reasons: (Bool:D $a is rw) (Bool:U $a is rw --> Bool::False) (Mu:U $a is rw) (Num:D $a is rw) (Num:U $a is rw) (int $a is rw) (num $a is rw --> num) in sub f2 at rw.rk line 7 in block <unit> at rw.rk line 16
Oh, my. The error message is big, but the main idea is clear. You cannot increment a constant integer.
Now step back to the original program. Remove increments and pass constant values:
sub f1($x is rw) { say $x; } sub f2($x is raw) { say $x; } f1(42); f2(42);
The first function still refuses to work:
Parameter '$x' expected a writable container, but got Int value  in sub f1 at rw.rk line 1  in block <unit> at rw.rk line 9
Even despite the fact that $x
is not modified in the function, its signature tells the compiler that the argument must be mutable.
Comment that line and call f2(42)
only.
$ raku rw.rk 42
It works! The is raw
trait did not affect the expectation: if you do not modify the variable ‘passed by reference’, just accept it.
One thought on “🦋 110. is rw vs is raw in Raku”