rakuroutines

Why do the default Raku if/while/loop/when blocks all have the same identity value (.WHICH)?


Except for the block where I declared a signature, all of the blocks have the same identity value, and claim to be declared on line 1 regardless of where they occur. Could anyone shed some light as to why this is the case?

say 「Let's look at some blocks…」;

if True {
  &?BLOCK.say;
}

while True {
  &?BLOCK.say;
  last;
}

loop {
  &?BLOCK.say;
  last;
}

if True -> | {
  「I'm different!」.say;
  &?BLOCK.say;
}

when ?True {
  &?BLOCK.say;
}

Solution

  • First of all: .say does NOT give you the identity value, because that calls the .gist method on the given expression. For the identity value, you need to call the .WHICH method. Fortunately, the Block.gist method does include the identity value in its stringification. But that is not guaranteed to be the case for all objects.

    What you see there, is the static optimizer at work: because nothing is happening inside the block, it can be discarded. In the one case where it is different (where you specified an alternate signature), it is different. If you run this script with --optimize=0 or --optimize=1, then all blocks will have different identity values.

    I guess you could call it an issue that mentioning &?BLOCK does not inhibit the static optimizer from flattening the scope. On the other hand, you could also call this a case of DIHWIDT (Doctor, It Hurts When I Do This). So don't do that then :-)

    UPDATE: it is the different signature that made the difference. Daniel Mita++