Re: Statement modifier scope

2005-04-15 Thread Juerd
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

2005-04-15 Thread Paul Seamons
> 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

2005-04-15 Thread Larry Wall
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

2005-04-15 Thread Juerd
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

2005-04-15 Thread Paul Seamons
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

2005-04-15 Thread Paul Seamons
>
> 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

2005-04-15 Thread Juerd
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

2005-04-15 Thread Paul Seamons
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

2005-04-15 Thread Juerd
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

2005-04-15 Thread Paul Seamons
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