🦋 110. is rw vs is raw in Raku

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”

Leave a Reply