Re: Statement modifier scope
Paul Seamons skribis 2005-04-15 13:42 (-0600): > Each of the declarations my, our and local currently set the value to > undefined (unless set = to something). That's not true. use strict; $::foo = 5; our $foo; print $foo; # 5 Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Statement modifier scope
> I'm imagining it will be different, as I expect temp to not hide the old > thing. I'm not sure it will. That is another good question. I just searched through the S and A's and couldn't find if temp will blank it out. I am thinking it will act like local. Each of the declarations my, our and local currently set the value to undefined (unless set = to something). I imagine that temp and let will behave the same. In which case "local %h;" and "let %h" would allocate a new, empty variable in a addition to the original variable (which is hidden but still retains its contents). Paul
Re: Statement modifier scope
I would like to get rid of all those implicit scopes. The only exception would be that any topicalizing modifier allocates a private lexical $_ scoped to just that statement. But dynamic scoping may happen only at explicit block boundaries. I can see the argument for the other side, where any "deferred" code is treated as a kind of closure regardless of whether there are explicit curlies around it. That would solve certain problems like defining the scopes of the lexicals in $a = $x ?? my $y :: my $z; or the infamous my $x = 1 if $y; to extend only to the subexpressions in which they find themselves. But it's not what naive users expect, and it's hard to explain, so I think we should stick with explicit curlies for most of our scoping needs, even if it means letting certain variables hang around undefined because their initialization was never executed. Larry
Re: Statement modifier scope
Paul Seamons skribis 2005-04-15 12:41 (-0600): > In Perl5 > perl -MData::Dumper -e '%h=qw(a 1 b 2); {local %h; $h{a}="one"; print Dumper > \%h} print Dumper \%h; > $VAR1 = { > 'a' => 'one' > }; > $VAR1 = { > 'a' => '1', > 'b' => '2' > }; > I'm imaging the behavior would be the same with Perl6. Notice that 'b' is I'm imagining it will be different, as I expect temp to not hide the old thing. I'm not sure it will. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Statement modifier scope
On Friday 15 April 2005 12:28 pm, Juerd wrote: > temp %h{ %other.keys } = %other.values; Oops missed that - I like that for solving this particular problem. It does even work in Perl5: perl -MData::Dumper -e '%h=qw(a 1 b 2); {local @h{qw(a b)}=("one","two"); print Dumper \%h} print Dumper \%h' $VAR1 = { 'a' => 'one', 'b' => 'two' }; $VAR1 = { 'a' => '1', 'b' => '2' }; I had never thought to do a hash slice in a local. That is great!!! Thank you very much! Wish I'd know about that three years ago. But, it still doesn't answer the original question about scoping in the looping statement modifiers. Paul
Re: Statement modifier scope
> > temp %h; > %h{ %other.keys } = %other.values; > > or even > > temp %h{ %other.keys } = %other.values; > > should work well already? Almost - but not quite. In Perl5 perl -MData::Dumper -e '%h=qw(a 1 b 2); {local %h; $h{a}="one"; print Dumper \%h} print Dumper \%h; $VAR1 = { 'a' => 'one' }; $VAR1 = { 'a' => '1', 'b' => '2' }; I'm imaging the behavior would be the same with Perl6. Notice that 'b' is gone in the first print. I only want to temporarily modify "some" values (the ones from the %other hash). I don't want the contents of the %h to be identical to %other - I already have %other. So in Perl5 this does work: perl -MData::Dumper -e '%h=qw(a 1 b 2); {local %h=%h; $h{a}="one"; print Dumper \%h} print Dumper \%h; $VAR1 = { 'a' => 'one' 'b' => '2', }; $VAR1 = { 'a' => '1', 'b' => '2' }; But this won't work in Perl6 (temp $var = $var doesn't work in Perl6) and again it may be fine for small hashes with only a little data - but for a huge hash (1000+ keys) it is very inefficient. This is good discussion - but it isn't the real focus of the original message in the thread - the question is about the local (temp) scoping of looping statement modifiers in Perl6. Though, I do appreciate your trying to get my example working as is. Paul
Re: Statement modifier scope
Paul Seamons skribis 2005-04-15 12:16 (-0600): > For the given example, your code fits perfectly. A more common case I have > had to deal with is more like this: > my %h = > my %other = ; > { > temp %h{$_} = %other{$_} for %other.keys; Either temp %h; %h{$_} = %other{$_} for %other.keys; or temp %h; %h{ %other.keys } = %other.values; or even temp %h{ %other.keys } = %other.values; should work well already? > %h.say; > } I think it's hard to find an example that can't easily be rewritten as something that already works. Gather/take solves most. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Statement modifier scope
On Friday 15 April 2005 11:57 am, Juerd wrote: > Paul Seamons skribis 2005-04-15 11:50 (-0600): > > my %h = ; > > { > > temp %h{$_} ++ for %h.keys; > > Just make that two lines. Is that so bad? > > temp %h; > %h.values »++; > For the given example, your code fits perfectly. A more common case I have had to deal with is more like this: my %h = my %other = ; { temp %h{$_} = %other{$_} for %other.keys; %h.say; } Ideally that example would print aone btwo c3 It isn't possible any more to do something like { temp %h = (%h, %other); } because that second %h is now hidden from scope (I forget which Apocalypse or mail thread I saw it in). Plus for huge hashes it just isn't very efficient. I'd like to temporarily put the values of one hash into another (without wiping out all of the modfied hashes values like "temp %h" would do), run some code, leave scope and have the modified hash go back to normal. In perl5 I've had to implement that programatically by saving existing values into yet another hash - running the code - putting them back. It works but there is all sorts of issues with defined vs exists. So yes - your code fits the limited example I gave. But I'd still like the other item to work. Paul
Re: Statement modifier scope
Paul Seamons skribis 2005-04-15 11:50 (-0600): > my %h = ; > { > temp %h{$_} ++ for %h.keys; Just make that two lines. Is that so bad? temp %h; %h.values »++; > %h.say; # values are incremented still > } > %h.say; # values are back to original values Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Statement modifier scope
The following chunks behave the same in Perl 5.6 as in Perl 5.8. Notice the output of "branching" statement modifiers vs. "looping" statement modifiers. perl -e '$f=1; {local $f=2; print "$f"} print " - $f\n"' # prints 2 - 1 perl -e '$f=1; {local $f=2 if 1; print "$f"} print " - $f\n" # prints 2 - 1 perl -e '$f=1; {local $f=2 unless 0; print "$f"} print " - $f\n"'' # prints 2 - 1 perl -e '$f=1; {local $f=2 for 1; print "$f"} print " - $f\n"' # prints 1 - 1 perl -e '$f=1; {local $f=2 until 1; print "$f"} print " - $f\n"' # prints 1 - 1 perl -e '$f=1; {local $f=2 while !$n++; print "$f"} print " - $f\n"' # prints 1 - 1 It appears that there is an implicit block around statements with looping statement modifiers. perlsyn does state that the control variables of the "for" statement modifier are locally scoped, but doesn't really mention that the entire statement is as well. I'm not sure if this was in the original design spec or if it flowed out of the implementation details, but either way it seems to represent an inconsistency in the treatment of locality with regards to braces (ok I guess there are several in Perl5). So the question is, what will it be like for Perl6. It would seem that all of the following should hold true because of scoping being tied to the blocks. pugs -e 'our $f=1; {temp $f=2; print $f}; say " - $f"' # should print 2 - 1 (currently prints 2 - 2 - but that is a compiler issue) pugs -e 'our $f=1; {temp $f=2 if 1; print $f}; say " - $f"' # should print 2 - 1 (currently dies with parse error) pugs -e 'our $f=1; {temp $f=2 for 1; print $f}; say " - $f"' # hopefully prints 2 - 1 (currently dies with parse error) As a side note - pugs does work with: pugs -e 'our $f=1; {$f=2 for 1; print $f}; say " - $f"' # prints 2 - 2 (as it should. It seems that statement modifiers don't currently work with declarations - but that is a compiler issue - not a language issue.) I have wanted to do this in Perl5 but couldn't but would love to be able to do in Perl6: my %h = ; { temp %h{$_} ++ for %h.keys; %h.say; # values are incremented still } %h.say; # values are back to original values Paul