Why is Perl 6's loop variable declaration in the outer scope?

Viewed 321

In Perl 6, a variable declared in the for-style loop is in the outer scope. This works and is documented.

loop ( my $n = 0; $n < 3; $n++ ) {
    put $n;
    }

say "Outside: $n";

The $n is visible outside of the block:

0
1
2
Outside: 3

Is there a motivating trick here that makes this different from what one would expect from Perl 6's ancestors? I didn't see a mention of this in the design docs (but try searching "loop" sometime). I couldn't come up with an example where this would make things easier.

In Perl 5, the same thing is a strict error:

use v5.10;
use strict;

for ( my $n = 0; $n < 3; $n++ ) {
    put $n;
    }

say "Outside: $n";  # Nope!

And, in C (those that let you do this), it's a similar error:

#include <stdio.h>

int main () {

   for( int a = 10; a < 20; a = a + 1 ){
      printf("value of a: %d\n", a);
   }

   printf("value of a: %d\n", a);  /* Nope! */

   return 0;
}

As usual with my questions, I'm not interested in workarounds. I know how to do those.


As I noted in the comments, Synopsis 4 pushes the implementation to declare lexicals only inside the block where they will appear.

The $n appears before the { so it's not "inside" the block.

However, what about pointy blocks?

-> $a { put "a is $a" }

And, subroutine signatures?

sub ( $a ) { put "a is $a" }

These variables are first typed before the {.

I don't particularly care about this but if I have to explain this break with tradition by saying that you have to declare lexical variables in the blocks where you will use them, someone can point out these cases.

2 Answers
Related