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”