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

if, loop, and lexical scope

20 views
Skip to first unread message

Alexey Trofimenko

unread,
Jun 27, 2004, 12:57:53 PM6/27/04
to perl6-l...@perl.org

AFAIR, I've seen in some Apocalypse that lexical scope boundaries will be
the same as boundaries of block, in which lexical variable was defined.

so, my question is, what the scope of variables, defined in C<if> and
C<loop> conditions?

in perl5:

my $a="first\n";
if (my $a="second\n") {print $a}
print $a;

prints

second
first

if I got it right, in perl6 same program will print

second
second

or will emit warning about redeclaring variable in the same scope..
sad. In C<if> case it isn't so significant, but what about C<loop>?

cite from Apocalypse4:
...
The continue block changes its name to NEXT and moves inside the block it
modifies, to work like POST blocks. Among other things, this allows NEXT
blocks to refer to lexical variables declared within the loop, provided
the
NEXT block is place after them. The generalized loop:
loop (EXPR1; EXPR2; EXPR3) { ... }
can now be defined as equivalent to:
EXPR1;
while EXPR2 {
NEXT { EXPR3 }
...
}
...


so,

loop (my $i=1;$i<10;$i++) { ... }

will declare $i for the rest of the block, in which loop is placed, won't
it?

I feel that I will write things like:

{loop (my $i=1;$i<10;$i++) {
...
}}

But I really hope that I missed something important, stating that theese
curlies are not necessary.

Luke Palmer

unread,
Jun 27, 2004, 5:16:11 PM6/27/04
to Alexey Trofimenko, perl6-l...@perl.org
Alexey Trofimenko writes:
> AFAIR, I've seen in some Apocalypse that lexical scope boundaries will be
> the same as boundaries of block, in which lexical variable was defined.

Yep. Except in the case of routine parameters, but that's nothing new.

>
> so, my question is, what the scope of variables, defined in C<if> and
> C<loop> conditions?
>
> in perl5:
>
> my $a="first\n";
> if (my $a="second\n") {print $a}
> print $a;
>
> prints
>
> second
> first
>
> if I got it right, in perl6 same program will print
>
> second
> second

Precisely.

> [...]

> so,
>
> loop (my $i=1;$i<10;$i++) { ... }
>
> will declare $i for the rest of the block, in which loop is placed, won't
> it?

Yep.

> I feel that I will write things like:
>
> {loop (my $i=1;$i<10;$i++) {
> ...
> }}

No you won't, for a couple reasons.

First, you'd instead be writing:

for 1..9 -> $i {
...
}

It's quite surprising how very many cases where you'd need loop can be
done with the new for. Since $i is a sub parameter, it's only scoped to
the block of the loop.

But anyway, if you still want to be old school about it, then you'll end
up not caring about the scope of your $i. Really you won't. And you'll
be happy that it was kept around for you once you decide you want to
know the value of $i for which the loop terminated.

Luke

David Storrs

unread,
Jun 28, 2004, 9:42:47 AM6/28/04
to perl6-l...@perl.org
On Sun, Jun 27, 2004 at 03:16:11PM -0600, Luke Palmer wrote:
>
> But anyway, if you still want to be old school about it, then you'll end
> up not caring about the scope of your $i. Really you won't. And you'll
> be happy that it was kept around for you once you decide you want to
> know the value of $i for which the loop terminated.
>
> Luke


Personally, I consider the new state of affairs to be a gift from
G--...er...Larry (ah, what's the difference?). It always annoyed me
to have to declared my vars outside the control structure when I
often needed them afterwards.

Thank you, Larry.

--Dks

John Williams

unread,
Jun 28, 2004, 1:10:03 PM6/28/04
to Luke Palmer, Alexey Trofimenko, perl6-l...@perl.org
On Sun, 27 Jun 2004, Luke Palmer wrote:

> Alexey Trofimenko writes:
> > AFAIR, I've seen in some Apocalypse that lexical scope boundaries will be
> > the same as boundaries of block, in which lexical variable was defined.
>
> Yep. Except in the case of routine parameters, but that's nothing new.

(This may be a bit tangential, but it still concerns scope...)

I am reminded of a strange case I came across in perl5, and I wondered how
perl6 would behave for the following:

$b = 'a';
my $b ='b' , print "$b\n";
print "$b\n";

In perl5, this prints:

a
b

Which seems to show that the "my $b" doesn't actually come into scope
until the end of the statement in which it is defined. Is that correct?
and what will perl6 do?

I know an obvious answer is "don't do that", which is what I had to (not)
do, but this is a greatly simplified version of some generated code.

~ John Williams


Jonathan Scott Duff

unread,
Jun 28, 2004, 1:17:40 PM6/28/04
to John Williams, Luke Palmer, Alexey Trofimenko, perl6-l...@perl.org
On Mon, Jun 28, 2004 at 11:10:03AM -0600, John Williams wrote:
> On Sun, 27 Jun 2004, Luke Palmer wrote:
>
> > Alexey Trofimenko writes:
> > > AFAIR, I've seen in some Apocalypse that lexical scope boundaries will be
> > > the same as boundaries of block, in which lexical variable was defined.
> >
> > Yep. Except in the case of routine parameters, but that's nothing new.
>
> (This may be a bit tangential, but it still concerns scope...)
>
> I am reminded of a strange case I came across in perl5, and I wondered how
> perl6 would behave for the following:
>
> $b = 'a';
> my $b ='b' , print "$b\n";
> print "$b\n";
>
> In perl5, this prints:
>
> a
> b
>
> Which seems to show that the "my $b" doesn't actually come into scope
> until the end of the statement in which it is defined. Is that correct?
> and what will perl6 do?

IIRC, perl6 will lexicalize $b as soon as it sees "my $b" so that it
should print

b
b

Assuming a left-to-right evaluation :)

-Scott
--
Jonathan Scott Duff Division of Nearshore Research
du...@lighthouse.tamucc.edu Senior Systems Analyst II

Alexey Trofimenko

unread,
Jun 28, 2004, 6:15:33 PM6/28/04
to perl6-l...@perl.org
On Mon, 28 Jun 2004 06:42:47 -0700, David Storrs <dst...@dstorrs.com>
wrote:

strange enough, i think that current perl5 behavior is kinda good.. I
often use the same $i or $j (10-years-old-Basic-habit) as counters in
every loop in my program (if using $_ is not what I want), and of course
it shouldn't be the SAME $i, and warnings about redeclaring variable isn't
what I want to get.. if I'll need to store counter after exiting loop, I
can do it in Perl6 anyway thanks to LAST {$stored=$i} (right?)...

many people - many habits...

of course, I just mutter.. new C<for> is very good, and in special cases,
when simple incrementing-decrementing isn't what I want, I can write my
own iterator (btw, in which apocalypse I can find how to write iterators
in perl6?) with my own custom very special increment and end condition.

Luke Palmer

unread,
Jun 28, 2004, 7:36:16 PM6/28/04
to Alexey Trofimenko, perl6-l...@perl.org
Alexey Trofimenko writes:
> of course, I just mutter.. new C<for> is very good, and in special
> cases, when simple incrementing-decrementing isn't what I want, I can
> write my own iterator (btw, in which apocalypse I can find how to
> write iterators in perl6?) with my own custom very special increment
> and end condition.

You want a C<next> method, and you want the <> operator to do the right
thing in its various contexts. I presume there will be a
close-to-builtin role C<iterator> that does just that:

class MyIterator {
does iterator;
has $.count = 0;
sub next () {
$.count++;
}
}

my $iter = MyIterator.new;
say for <$iter>; # 0 1 2 3 4 5 6 ...

Luke

Luke Palmer

unread,
Jun 28, 2004, 7:46:08 PM6/28/04
to Alexey Trofimenko, perl6-l...@perl.org
Luke Palmer writes:
> Alexey Trofimenko writes:
> > of course, I just mutter.. new C<for> is very good, and in special
> > cases, when simple incrementing-decrementing isn't what I want, I can
> > write my own iterator (btw, in which apocalypse I can find how to
> > write iterators in perl6?) with my own custom very special increment
> > and end condition.
>
> You want a C<next> method, and you want the <> operator to do the right
> thing in its various contexts. I presume there will be a
> close-to-builtin role C<iterator> that does just that:
>
> class MyIterator {
> does iterator;
> has $.count = 0;
> sub next () {

What am I thinking!?

method next () {

Jonadab The Unsightly One

unread,
Jun 29, 2004, 10:52:31 AM6/29/04
to John Williams, Luke Palmer, Alexey Trofimenko, perl6-l...@perl.org
John Williams <will...@tni.com> writes:

> $b = 'a';
> my $b ='b' , print "$b\n";
> print "$b\n";
>

> Which seems to show that the "my $b" doesn't actually come into
> scope until the end of the statement in which it is defined.

The comma operator doesn't guarantee order of operation because it's
building (or not bothering to build, in this case) a list. I wouldn't
have been terribly surprised if the expression before the comma were
optimized out entirely, since the comma operator is in void context,
which is theoretically a form of scalar context in Perl5 IIRC.

People who think in terms of "statements" often get mixed up when they
put complex expressions in void context, expecting them to be treated
as statements. print(2+3)*7; is another example. Perl doesn't have
"statements" in the same sense that Pascal does. It has expressions.

--
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}}
split//,"ten.thgirb\@badanoj$/ --";$\=$ ;-> ();print$/

Alexey Trofimenko

unread,
Jun 29, 2004, 4:19:56 PM6/29/04
to perl6-l...@perl.org
On Tue, 29 Jun 2004 10:52:31 -0400, Jonadab The Unsightly One
<jon...@bright.net> wrote:

> People who think in terms of "statements" often get mixed up when they
> put complex expressions in void context, expecting them to be treated
> as statements. print(2+3)*7; is another example. Perl doesn't have
> "statements" in the same sense that Pascal does. It has expressions.
>

hm.. still it have modifers like postfix C<for>, C<while>, C<if> etc.,
which are statement ones, not expression..

hm.. just consider all the mess(and fun!) if all the control structures
and modfiers would become ordinary expressions.. but it's a perl, not lisp
or haskel or whatever..

0 new messages