Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Making control variables local in a loop statement

31 views
Skip to first unread message

Joe Gottman

unread,
Jan 13, 2005, 7:35:19 PM1/13/05
to perl6-l...@perl.org
In Perl5, given code like

for (my $n = 0; $n < 10; ++$n) {.}

the control variable $n will be local to the for loop. In the equivalent
Perl6 code
loop my $n = 0; $n < 10; ++$n {.}

$n will not be local to the loop but will instead persist until the end of
enclosing block.

It would be nice if there were some easy way to mimic the Perl5 behavior
in Perl6. In Perl6, the canonical way to make a variable local to a block
is by making it a parameter. I therefore suggest allowing the following
syntax:

loop 0 -> $n; $n < 10; ++$n {...}

This will declare $n as a control variable to the loop and initialize it to
0. Like any parameter, it will then be local to that block (assuming the
comparison and update portions of the loop statement are injected into the
block). One subtlety is that $n should probably be treated as if it were
declared with the "is copy" attribute, so that it can be modified inside the
loop (by the update portion if nothing else), but does not alias a variable
it was initialized from.

Joe Gottman

Luke Palmer

unread,
Jan 13, 2005, 8:34:07 PM1/13/05
to Joe Gottman, perl6-l...@perl.org
Joe Gottman writes:
> It would be nice if there were some easy way to mimic the Perl5 behavior
> in Perl6. In Perl6, the canonical way to make a variable local to a block
> is by making it a parameter. I therefore suggest allowing the following
> syntax:
>
> loop 0 -> $n; $n < 10; ++$n {...}

That doesn't make any sense. A nice property of -> is that it's like
"sub" without the parentheses. So your proposal looks like:

loop 0 sub ($n); $n < 10; ++$n {...}

Which is confusing. I don't think we want to break the equivalence of
-> and "sub".

I'm disregarding readability problems with the C-style for "loop" these
days, since most of them can be rewritten with Perl 6's "for". What I'm
interested in is those common things that can be expressed with "loop"
but not with "for"---where "loop" is the most readable solution.

Luke

Juerd

unread,
Jan 13, 2005, 8:07:42 PM1/13/05
to Joe Gottman, perl6-l...@perl.org
Joe Gottman skribis 2005-01-13 19:35 (-0500):

> In Perl5, given code like
> for (my $n = 0; $n < 10; ++$n) {.}
> the control variable $n will be local to the for loop. In the equivalent
> Perl6 code
> loop my $n = 0; $n < 10; ++$n {.}
> $n will not be local to the loop but will instead persist until the end of
> enclosing block.

What is wrong with { loop my $n = 0; $n < 10; ++$n { ... } }? I find
that syntax much easier to read and certainly more clearly indicating
scope.

With loop 0 -> $n; ...; ... { ... }, the -> is too far away from the
block, imho.


Juerd

David Storrs

unread,
Jan 14, 2005, 1:22:26 PM1/14/05
to perl6-l...@perl.org
On Thu, Jan 13, 2005 at 07:35:19PM -0500, Joe Gottman wrote:
> In Perl5, given code like
>
> for (my $n = 0; $n < 10; ++$n) {.}
>
> the control variable $n will be local to the for loop. In the equivalent
> Perl6 code
> loop my $n = 0; $n < 10; ++$n {.}
>
> $n will not be local to the loop but will instead persist until the end of
> enclosing block.

Actually, I consider this a good thing. There are lots of times when
I would LIKE my loop variable to persist and, in order to get that, I
need to do the following:

my $n;
for ($n=0; $n<10; ++$n) {...}
...do stuff with $n...

It's a minor ugliness, but it itches at me. Under the new Perl6
rules, I can easily have it either way.

{for (my $n=0; $n<10; ++$n) {...}} # Local to loop
for (my $n=0; $n<10; ++$n) {...} # Persistent

--Dks

Austin Hastings

unread,
Jan 14, 2005, 2:46:58 PM1/14/05
to David Storrs, perl6-language >> p6l
David Storrs wrote:

But there's no clean way to make some of them temporary and some
persistent.

This seems like a legitimate place for "saying what you intend", viz:

for (my $n is longlasting = 0, $m = 1; ...) {...}

Albeit that's a lame example of how to do it.

=Austin

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.300 / Virus Database: 265.6.10 - Release Date: 1/10/2005

Matthew Walton

unread,
Jan 14, 2005, 2:57:11 PM1/14/05
to Austin_...@yahoo.com, perl6-language >> p6l

What's not clean about

{
loop my $n = 0; $n < 10; $n++ {
...
}
}

? Works fine for me, shows the scope boundaries very clearly indeed,
just the kind of thing a lot of languages are missing, IMO.

Of course, this example's really bad because it's much better written

for 0..9 {
...
}

In which case I assume that it only clobbers the topic inside the block,
not outside it, as it's somewhat like

for 0..9 -> $_ {
...
}

To write it explicitly. Or am I barking up the wrong tree completely?

Austin Hastings

unread,
Jan 14, 2005, 3:20:02 PM1/14/05
to Matthew Walton, perl6-language >> p6l
Matthew Walton wrote:

> Austin Hastings wrote:
>
>> But there's no clean way to make some of them temporary and some
>> persistent.
>>
>> This seems like a legitimate place for "saying what you intend", viz:
>>
>> for (my $n is longlasting = 0, $m = 1; ...) {...}
>>
>> Albeit that's a lame example of how to do it.
>
>
> What's not clean about
>
> {
> loop my $n = 0; $n < 10; $n++ {
> ...
> }
> }
>
> ? Works fine for me, shows the scope boundaries very clearly indeed,
> just the kind of thing a lot of languages are missing, IMO.
>
> Of course, this example's really bad because it's much better written
>
> for 0..9 {
> ...
> }
>
> In which case I assume that it only clobbers the topic inside the
> block, not outside it, as it's somewhat like
>
> for 0..9 -> $_ {
> ...
> }
>
> To write it explicitly. Or am I barking up the wrong tree completely?
>

Not sure. In my example, there were two variables, 'n' and 'm', one of
which was supposed to outlast the scope, the other not.

David Storrs

unread,
Jan 14, 2005, 7:16:26 PM1/14/05
to perl6-language >> p6l
On Fri, Jan 14, 2005 at 02:46:58PM -0500, Austin Hastings wrote:
> >rules, I can easily have it either way.
> >
> > {for (my $n=0; $n<10; ++$n) {...}} # Local to loop
> > for (my $n=0; $n<10; ++$n) {...} # Persistent
> >
> >--Dks
> >
> But there's no clean way to make some of them temporary and some
> persistent.
>
> This seems like a legitimate place for "saying what you intend", viz:
>
> for (my $n is longlasting = 0, $m = 1; ...) {...}


I see your point, but:

- at least in the kinds of programming I do, I rarely use more than
one loop variable (with the exception of nested loops, and even
there the second var is declared in the second loop line)

- even when I do, only rarely do I want some of them to persist and
some not

- if I do, I'm willing to suffer the minor ugliness of putting the
to-be-persistent ones outside the scope, rather than have to use a
property every time I want ANYTHING persistent.

- I would much prefer this:

my ($total, $last_seen, $had_errors) = (0)x3;
for ($my $i=0; $i < @elements; $i++) {...}

To this:

for (my $i=0,
$total=0 is longlasting,
$last_seen=0 is longlasting,
$had_errors=0 is longlasting;
$i < @elements;
$i++)
{
...
}


FWIW....

--Dks

0 new messages