> Paul Hodges took a crack at implementing for as a subroutine and came up with > something that didn't look too insane. Luke Palmer added a refinement allowing > for n at a time looping. However, for reasons that I can't quite put my finger > on, I'm not quite sure that either method has got the sub signature quite > right, and I'm not entirely sure how you would express for's signature as a > Perl 6 signature anyway. Answers on a mailing list please.
Did this ever get resolved to anyone's satisfaction? While reading EX6, I found myself wonder exactly what for() would look like in Perl 6 code...
> > Paul Hodges took a crack at implementing for as a subroutine and came > up with > > something that didn't look too insane. Luke Palmer added a refinement > allowing > > for n at a time looping. However, for reasons that I can't quite put > my finger > > on, I'm not quite sure that either method has got the sub signature > quite > > right, and I'm not entirely sure how you would express for's > signature as a > > Perl 6 signature anyway. Answers on a mailing list please.
> Did this ever get resolved to anyone's satisfaction? While reading > EX6, I found myself wonder exactly what for() would look like in Perl 6 > code...
Well, I don't think it's possible, actually. There's a flattening list context at the beginning (implying a sugary drink from 7 eleven), followed by a code block. But, as we know, slurpy arrays can only come at the end of positional parameters.
But, assuming that is possible, here's C<for> in its entirety:
sub for (*@list, &block) { while @list { block( *...@list.splice(0, &block.arity) ); } }
That's not handling NEXT blocks, et al. But I think that's just a matter of putting &block.NEXT(), &c. in the appropriate places.
On Thursday, July 31, 2003, at 12:05 PM, Luke Palmer wrote: > Well, I don't think it's possible, actually. There's a flattening > list context at the beginning (implying a sugary drink from 7 eleven), > followed by a code block. But, as we know, slurpy arrays can only > come at the end of positional parameters.
Right, which is why I couldn't get my head around it. But EX6 says:
"an important goal of Perl 6 is to make the language powerful enough to natively implement all its own built-ins"
Does "built-ins" just mean "subs" like split(), or does it also include control structures like if() and for()?
> But, assuming that is possible, here's C<for> in its entirety:
> sub for (*@list, &block) { > while @list { > block( *...@list.splice(0, &block.arity) ); > } > }
Maybe for() does some magic with "is parsed" and the various Perl 6 grammar rule regexes?
>Well, I don't think it's possible, actually. There's a flattening >list context at the beginning (implying a sugary drink from 7 eleven), >followed by a code block. But, as we know, slurpy arrays can only >come at the end of positional parameters.
Anyone but me feel the need for non-greedy slurpy arrays? similar to non-greedy RE matches? Then we could do:
sub for (*?@data, &block) {...}
Proposed behavior of *?@ : All Arguement to Parameter mapping left of it are processed Left to Right. Once seen, the mapping starts over right to left. Everything remaining is slurpable.
Yes, it's more expensive to use, just like the RE version, but shouldn't impact performance _too_ bad when it's not, since the behavior will be detectable at compile time.
> At 10:05 AM 7/31/2003 -0600, Luke Palmer wrote: > >Well, I don't think it's possible, actually. There's a flattening > >list context at the beginning (implying a sugary drink from 7 eleven), > >followed by a code block. But, as we know, slurpy arrays can only > >come at the end of positional parameters.
> Anyone but me feel the need for non-greedy slurpy arrays? similar to > non-greedy RE matches? > Then we could do:
> sub for (*?@data, &block) {...}
> Proposed behavior of *?@ : All Arguement to Parameter mapping left of it > are processed Left to Right. Once seen, the mapping starts over right to > left. Everything remaining is slurpable.
> Yes, it's more expensive to use, just like the RE version, but shouldn't > impact performance _too_ bad when it's not, since the behavior will be > detectable at compile time.
> Thoughts?
Doing something like that was what came to my mind right away when I read what Luke put too... It "feels right" to me, though I don't know that counts for much. :-)
> > Anyone but me feel the need for non-greedy > > slurpy arrays? similar to non-greedy RE matches?
>I definately like the idea of having something like that. It probably >wouldn't be used much, but it is nice to have the option.
>One thing though, can't you accomplish the same thing by slurping >everything, then poping the block off of the array?
One could do most of the stuff in P6 parameters with P5's @_. But as Damian showed at the end of E6, it can quickly grow to a nightmare, and making it nicer is what P6 is all about.
>-----Original Message----- >From: Rod Adams [mailto:r...@rodadams.net] >Sent: Thursday, July 31, 2003 12:56 PM >To: Perl 6 Language >Subject: Re: Perl 6's for() signature
>At 10:05 AM 7/31/2003 -0600, Luke Palmer wrote: > >Well, I don't think it's possible, actually. There's a flattening > >list context at the beginning (implying a sugary drink from 7 eleven), > >followed by a code block. But, as we know, slurpy arrays can only > >come at the end of positional parameters.
>Anyone but me feel the need for non-greedy slurpy arrays? similar to >non-greedy RE matches? >Then we could do:
>sub for (*?@data, &block) {...}
>Proposed behavior of *?@ : All Arguement to Parameter mapping left of it >are processed Left to Right. Once seen, the mapping starts over right to >left. Everything remaining is slurpable.
>Yes, it's more expensive to use, just like the RE version, but shouldn't >impact performance _too_ bad when it's not, since the behavior will be >detectable at compile time.
-----Original Message----- From: Rod Adams [mailto:r...@rodadams.net] Sent: Thursday, July 31, 2003 12:56 PM To: Perl 6 Language Subject: Re: Perl 6's for() signature
At 10:05 AM 7/31/2003 -0600, Luke Palmer wrote: >Well, I don't think it's possible, actually. There's a flattening >list context at the beginning (implying a sugary drink from 7 eleven), >followed by a code block. But, as we know, slurpy arrays can only >come at the end of positional parameters.
Anyone but me feel the need for non-greedy slurpy arrays? similar to non-greedy RE matches? Then we could do:
sub for (*?@data, &block) {...}
Proposed behavior of *?@ : All Arguement to Parameter mapping left of it are processed Left to Right. Once seen, the mapping starts over right to left. Everything remaining is slurpable.
Yes, it's more expensive to use, just like the RE version, but shouldn't impact performance _too_ bad when it's not, since the behavior will be detectable at compile time.
> Anyone but me feel the need for non-greedy slurpy arrays? similar to > non-greedy RE matches? > Then we could do:
> sub for (*?@data, &block) {...}
> Proposed behavior of *?@ : All Arguement to Parameter mapping left of it > are processed Left to Right. Once seen, the mapping starts over right to > left. Everything remaining is slurpable.
With obvious restrictions on "no other slurpy/semi-slurpy arrays" in the param list, b/c that would make things go insane, IMHO. Although, I guess with typing, you could do splits on the typed params between, and assuming there was no ambiguity ...
r...@rodadams.net (Rod Adams) wrote in message > Proposed behavior of *?@ : All Arguement to Parameter mapping left of it > are processed Left to Right. Once seen, the mapping starts over right to > left. Everything remaining is slurpable.
> Yes, it's more expensive to use, just like the RE version, but shouldn't > impact performance _too_ bad when it's not, since the behavior will be > detectable at compile time.
> Thoughts?
There is another problem beyond efficiency: the P6 list semantics is lazy.
The following is valid P6, AFAIK:
for 1 .. Inf { print $_; last when 10;
}
And then most of the proposed methods (including popping off *@_) would not work.
There is another problem that I see with a user defined my_for. We want to be able to write
my_for 1 .. 5 { something }
and not have to write:
my_for 1 .. 5 {something };
What is bothering me is the following: If we have a sub with the signature: sub very_complicated(Int $x, Code *@slurped)
how would the following get parsed:
very_complicated 7 { print "Hello," } { print " world!"} # Those were the 3 args I wanted to pass # and the next one is outside the call sub next_routine {...}
It seems to me, then, that calls to user defined subs will need to end with a semi-colon.
Abhi
Abhijit A. Mahabal Home: 520 N. Grant St, Apt #2 Graduate Student, Bloomington IN 47408 Dept of Cog Sci and Computer Science, 812 331 2286 Indiana University Off: LH301I; 812 855 8898
> > Proposed behavior of *?@ : All Arguement to Parameter mapping left of it > > are processed Left to Right. Once seen, the mapping starts over right to > > left. Everything remaining is slurpable.
> > Yes, it's more expensive to use, just like the RE version, but shouldn't > > impact performance _too_ bad when it's not, since the behavior will be > > detectable at compile time.
> > Thoughts?
> There is another problem beyond efficiency: the P6 list semantics is lazy.
> The following is valid P6, AFAIK:
> for 1 .. Inf { > print $_; > last when 10; > }
> And then most of the proposed methods (including popping off *@_) would > not work.
No, popping at least would work. I can assure you of that.
> There is another problem that I see with a user defined my_for. We want to > be able to write
> my_for 1 .. 5 { something }
> and not have to write:
> my_for 1 .. 5 {something };
> What is bothering me is the following: If we have a sub with the > signature: > sub very_complicated(Int $x, Code *@slurped)
> how would the following get parsed:
> very_complicated 7 { print "Hello," } { print " world!"} > # Those were the 3 args I wanted to pass > # and the next one is outside the call > sub next_routine {...}
> It seems to me, then, that calls to user defined subs will need to end > with a semi-colon.
Semicolon syntax shortcuts are still up in the air. People constantly get tripped up on whether or not to use a semicolon after whatever kind of block. So, there's going to be some rule which will allow you to omit them...
As of A4, "a } on a line by itself gets an implicit semicolon added, if syntactically valid". But the rules might need to be a bit more complex. We'll see.
I posed this very question to Larry a few months back, when I was writing E6. We're still mulling over the correct answer. The last thought on the problem that Larry's shared with me was that there may need to be a special case for allowing a single &block parameter after the slurpy (which would then be popped off the parsed arg list before slurpification).
I don't think either Larry or I thinks that's ideal, so we'll probably keep working towards a better (more general) solution to the problem.
dam...@conway.org (Damian Conway) writes: > The last thought on the problem that Larry's shared with me was that there > may need to be a special case for allowing a single &block parameter after > the slurpy
And the Rubyometer creeps up another few notches...
(Gosh, you'd almost think that Matz had already thought through some of these issues, wouldn't you? ;)
-- Will your long-winded speeches never end? What ails you that you keep on arguing? -- Job 16:3
On Fri, Aug 01, 2003 at 11:01:15PM +0100, Simon Cozens wrote:
: dam...@conway.org (Damian Conway) writes: : > The last thought on the problem that Larry's shared with me was that there : > may need to be a special case for allowing a single &block parameter after : > the slurpy : : And the Rubyometer creeps up another few notches...
It's long been planned to allow blocks anywhere in the signature, particularly at the end, because of endweight considerations. It's been on my Perl 5 wish list since long before I ever heard of Ruby. In fact, the first thing I thought when I saw how Ruby did it was, "Gee, why did he restrict it to only be the last thing?" In Ruby it's a special case syntax. We're making a general capability to put the block anywhere in the argument list. If that makes Perl more like Ruby, so be it. But Perl is not terribly worried about where it fits on the Rubyometer. Ruby will need to worry about where it fits on the Perlometer.
: (Gosh, you'd almost think that Matz had already thought through some of these : issues, wouldn't you? ;)
Certainly Matz thought about some of these issues. Whether he would claim to have thought them "through" is another matter. There are many throughways, and they don't all lead the same place. It's easy to tunnel into a false minimum and think you're "through".
"Abhijit A. Mahabal" <amaha...@cs.indiana.edu> writes:
> There is another problem beyond efficiency: the P6 list semantics is lazy.
> The following is valid P6, AFAIK:
> for 1 .. Inf { > print $_; > last when 10; > }
Yeah, but that's a foreach loop, despite the fact that "foreach" is spelled "for" in your example. foreach loops have a different signature from for loops. (P6 does make it possible to have two routines with the same name that differ by signature, right? ISTR seeing something about that in one of the Apocalypses[1].)
> And then most of the proposed methods (including popping off *@_) > would not work.
foreach loops take their only code block in the braces; you don't have the code block inside the parens to worry about in that case, like you would in a for loop. Thus, foreach loops are no harder to implement than while or if, signature-wise.
> my_for 1 .. 5 { something }
> and not have to write:
> my_for 1 .. 5 {something };
Ah, that's another matter, but you need that to implement while and if as well. Methinks that a signature should be able to call for a code block in braces, and when it's called the signature after that code block should be optional. (And it needs to be optional whether the code block is the last thing in the signature or not; else, how would one implement map and grep and sort?)
A question I haven't fully thought through: should a closing brace _ever_ need to be followed by a semicolon? Because, if not, then we could do this...
my $foo = sub { do_stuff() } # <-- Note no semicolon.. my $baz = { my @bar; more_stuff(@bar) yetmorestuff(@bar) \@bar } # <-- Here also.
Would that have any nasty consequences I haven't thought about?
---
[1] I _think_ that's the right plural.
*apocalupt + s + es => apocalupses, transliterated apocalypses. But my third declension is a little rusty and I'm not certain about that first s being added to the root to form the noun stem.
It's a sufficiently unusal word imported to English recently enough that the plural would be formed like in the original language, yes? But then why isn't the singular "apocalypsis"?
John Siracusa <sirac...@mindspring.com> writes: > Did this ever get resolved to anyone's satisfaction? While reading > EX6, I found myself wonder exactly what for() would look like in > Perl 6 code...
A for loop[1] is basically syntax sugar for a while loop. In general, where foo, bar, baz, and quux are expressions, the following are equivalent:
for (foo; bar; baz) { quux } foo; while (bar) { quux; baz }
If Perl6 has enough syntax-sugar ability to let you turn the former into the latter, then you don't need to worry about for's signature.
> "Abhijit A. Mahabal" <amaha...@cs.indiana.edu> writes:
> > There is another problem beyond efficiency: the P6 list semantics is lazy.
> > The following is valid P6, AFAIK:
> > for 1 .. Inf { > > print $_; > > last when 10; > > }
> Yeah, but that's a foreach loop, despite the fact that "foreach" is > spelled "for" in your example. foreach loops have a different > signature from for loops. (P6 does make it possible to have two > routines with the same name that differ by signature, right? ISTR > seeing something about that in one of the Apocalypses[1].)
Yes, it's possible to have two routines with the same name which differ by signature... however, in Perl 6, C<for> has only one signature, and it's the one above. The C<for> loop you are thinking of is spelled C<loop>, and that's an obvious candidate for C<is parsed>, because it's so funky.
> > And then most of the proposed methods (including popping off *@_) > > would not work.
> foreach loops take their only code block in the braces; you don't have > the code block inside the parens to worry about in that case, like you > would in a for loop. Thus, foreach loops are no harder to implement > than while or if, signature-wise.
To the contrary, C<while> and C<if> take only a single expression in scalar context, whereas C<for> takes a list in flattening list context. This is the trouble, because you need flattening list context followed by a different, C<Code> context. And that's not allowed by A6 rules.
> > my_for 1 .. 5 { something }
> > and not have to write:
> > my_for 1 .. 5 {something };
> Ah, that's another matter, but you need that to implement while and if > as well. Methinks that a signature should be able to call for a code > block in braces, and when it's called the signature after that code > block should be optional.
You mean s:2nd/signature/semicolon/ ?
> (And it needs to be optional whether the code block is the last > thing in the signature or not; else, how would one implement map and > grep and sort?)
Because commas are always optional around a code block, no matter where it appears. This may well be generalized to semicolons, but AFAIK, this is not the plan (yet).
> A question I haven't fully thought through: should a closing brace > _ever_ need to be followed by a semicolon? Because, if not, then we > could do this...
> my $foo = sub { do_stuff() } # <-- Note no semicolon.. > my $baz = { > my @bar; > more_stuff(@bar) > yetmorestuff(@bar) > \@bar } # <-- Here also.
> Would that have any nasty consequences I haven't thought about?
This has already been discussed at length. The answer is "um". :-)
So far documented, the semicolon is only optional when the closing brace is the only thing on the line. Don't worry, Larry's got a handle on this one, and I don't think it needs further discussion.
> > Did this ever get resolved to anyone's satisfaction? While reading > > EX6, I found myself wonder exactly what for() would look like in > > Perl 6 code...
> A for loop[1] is basically syntax sugar for a while loop. In general, > where foo, bar, baz, and quux are expressions, the following are equivalent:
> for (foo; bar; baz) { quux } > foo; while (bar) { quux; baz }
Well, except that in the second, any variables declared in foo will leak into the scope after the end of the for loop. Also, in the second, "baz" is inside the same scope as quux, whereas in the normal C-style for loop, it's not.
Thus, "for (foo; bar; baz) { quux }" is really more like:
> If Perl6 has enough syntax-sugar ability to let you turn the former > into the latter, then you don't need to worry about for's signature.
Well, yes. But the point of this discussion is, precisely what *kind* of syntactic sugar will be used.
> [1] Of course I mean a C-style for loop.
-- $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6 ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}
> > John Siracusa <sirac...@mindspring.com> writes:
> > > Did this ever get resolved to anyone's satisfaction? While reading > > > EX6, I found myself wonder exactly what for() would look like in > > > Perl 6 code...
> > A for loop[1] is basically syntax sugar for a while loop. In general, > > where foo, bar, baz, and quux are expressions, the following are equivalent:
> > for (foo; bar; baz) { quux } > > foo; while (bar) { quux; baz }
> Well, except that in the second, any variables declared in foo will leak > into the scope after the end of the for loop.
Actually, in Perl 6, they'll do that anyway. Scope in loops is strictly defined by the location of the braces WRT the location of "my". That is:
while (my $x = somefunc()) { ... } # $x still in scope
And the same for all other loops. C<for> loops are an "exception", sortof, because they're really declaring a parameterized block instead of a lexical variable.
> > If Perl6 has enough syntax-sugar ability to let you turn the former > > into the latter, then you don't need to worry about for's signature.
> Well, yes. But the point of this discussion is, precisely what *kind* > of syntactic sugar will be used.
> > [1] Of course I mean a C-style for loop.
> -- > $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca > );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6 > ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}
> -----Original Message----- > From: Luke Palmer [mailto:fibon...@babylonia.flatirons.org] > Actually, in Perl 6, they'll do that anyway. Scope in loops is > strictly defined by the location of the braces WRT the location of > "my". That is:
> while (my $x = somefunc()) { ... } > # $x still in scope
> And the same for all other loops. C<for> loops are an "exception", > sortof, because they're really declaring a parameterized block instead > of a lexical variable.
It seems like we could maybe generalize this "exception":
In cases where we say
my &block = -> $a, $b { do_stuff; }
for (my $a = 0, $b = 1; $a < $b; ++$a) block;
We're really just pulling the block vars out so we can tweak them.
Perhaps the right approach is that all lexically scoped vars declared "within" loop keywords that take blocks are parameters, and persist until the end of the loop-block.
while (my $line = <>) { # or loop, or for, or do/while, or whatever ... }
print $line; # error -- line out of scope
The obvious accompaniment is C<is scoped(BLOCK)> or maybe C<is persistent>.
FOR_LOOP: for (...) { while (my $line is scoped(FOR_LOOP) = <>) { ... } print $line; # Okay -- $line ends with the for. }
> -----Original Message----- > From: Luke Palmer [mailto:fibon...@babylonia.flatirons.org] > Austin Hastings writes: > > > From: Luke Palmer [mailto:fibon...@babylonia.flatirons.org]
> > > Actually, in Perl 6, they'll do that anyway. Scope in loops is > > > strictly defined by the location of the braces WRT the location of > > > "my". That is:
> > > while (my $x = somefunc()) { ... } > > > # $x still in scope
> > > And the same for all other loops. C<for> loops are an "exception", > > > sortof, because they're really declaring a parameterized block instead > > > of a lexical variable.
> > It seems like we could maybe generalize this "exception":
> C<for> is called C<loop>, and the & is required to avoid using the return > value of calling C<block>. The , is required because it's not a curly > block, and commas are only optional when it is.
> And you can't do that because the loop has no way of knowing that your > lexicals are referring to &block's parameters.
Which begs the question:
my &blk = -> $a, $b {...};
for (@list) &blk;
What happens?
(IOW, how do we map locals/parameters into block vars?)
(IOW, in a "target-rich" environment, how do we know what to bind?)
> Then again, C<for> > could be made to do that using named parameters, but I don't think it > will (there are some nasty traps with variables in outer scopes). It's > easy enough to say:
> > We're really just pulling the block vars out so we can tweak them.
> Yeah, sortof.
...
> It's a beginner trap, so Larry changed it to follow intuition. It can > be useful in a couple places, and it never really gets in your way. So, > poof, no more magic scopes.
Hooray for newbies. And that's a good point.
I'm still curious about the binding rules, though.
Luke Palmer <fibon...@babylonia.flatirons.org> writes: > Yes, it's possible to have two routines with the same name which > differ by signature... however, in Perl 6, C<for> has only one > signature, and it's the one above. The C<for> loop you are thinking > of is spelled C<loop>,
Oh, yes, forgot about that.
> To the contrary, C<while> and C<if> take only a single expression in > scalar context, whereas C<for> takes a list in flattening list > context.
*light dawns*
That's what I get for trying to start reading in the middle of a thread, I guess.
> > Methinks that a signature should be able to call for a code block > > in braces, and when it's called the signature after that code > > block should be optional.
> You mean s:2nd/signature/semicolon/ ?
Yes, that was a thinko. I thought I typed semicolon there.
> This has already been discussed at length. The answer is "um". :-)
I see.
> So far documented, the semicolon is only optional when the closing > brace is the only thing on the line. Don't worry, Larry's got a > handle on this one, and I don't think it needs further discussion.
Cool.
> > Fooey, English is weird, let's stick with Perl.
> Hmm, that last quote seems a little odd when placed next to your > signature... :-)
What, my little pathetic attempt at a JAPH? It's only even slightly hard to follow if you don't understand closures. Nothing like some of the clever monstrosities I've seen floating around on the net.