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

NEXT and the general loop statement

4 views
Skip to first unread message

Joe Gottman

unread,
Aug 16, 2006, 8:21:29 PM8/16/06
to Perl6 Language List
Is a NEXT clause called before or after the update portion of a general loop
statement? For instance, consider the following code:

loop $n = 0; $n < 5; ++$n {

NEXT {print $n;}

}

Is the output 01234 or 12345?

Joe Gottman

Larry Wall

unread,
Aug 16, 2006, 9:24:47 PM8/16/06
to Perl6 Language List
On Wed, Aug 16, 2006 at 08:21:29PM -0400, Joe Gottman wrote:
: Is a NEXT clause called before or after the update portion of a general loop

I'd say 01234 on the theory that the 3-arg loop is really saying:

$n = 0;
while $n < 5 {
NEXT { ++$n }
NEXT { print $n }
}

and also on the theory that block exiting blocks always run in reverse order.

Larry

Luke Palmer

unread,
Aug 17, 2006, 8:44:13 PM8/17/06
to Perl6 Language List
On 8/16/06, Larry Wall <la...@wall.org> wrote:
> : Is the output 01234 or 12345?
>
> I'd say 01234 on the theory that the 3-arg loop is really saying:
>
> $n = 0;
> while $n < 5 {
> NEXT { ++$n }
> NEXT { print $n }
> }
>
> and also on the theory that block exiting blocks always run in reverse order.

Wasn't NEXT supposed to do something tricky, such as being mutually
exclusive with LAST? I remember a debate some time ago where some
complained "but that would be hard to implement", and the solution
being mostly correct but failing in this case.

I seem to recall NEXT being created in order to do things like this:

for @objs {
.print;
NEXT { print ", " }
LAST { print "\n" }
}

We also might consider using perl6's hypothetical features to
implement NEXT correctly in all cases (except for those cases where
the loop update condition cannot be hypotheticalized).

Luke

Joe Gottman

unread,
Aug 17, 2006, 11:39:06 PM8/17/06
to Perl6 Language List

> -----Original Message-----
> From: Luke Palmer [mailto:lrpa...@gmail.com]
> Sent: Thursday, August 17, 2006 8:44 PM
> To: Perl6 Language List
> Subject: Re: NEXT and the general loop statement
> Wasn't NEXT supposed to do something tricky, such as being mutually
> exclusive with LAST? I remember a debate some time ago where some
> complained "but that would be hard to implement", and the solution
> being mostly correct but failing in this case.
>
> I seem to recall NEXT being created in order to do things like this:
>
> for @objs {
> .print;
> NEXT { print ", " }
> LAST { print "\n" }
> }
>

Is this even possible? This would require Perl to know which iteration is
going to be the last one. In many cases there is no way to know this:

repeat {

Joe Gottman

unread,
Aug 17, 2006, 11:45:06 PM8/17/06
to Perl6 Language List

> -----Original Message-----
> From: Luke Palmer [mailto:lrpa...@gmail.com]
> Sent: Thursday, August 17, 2006 8:44 PM
> To: Perl6 Language List
>

> Wasn't NEXT supposed to do something tricky, such as being mutually
> exclusive with LAST? I remember a debate some time ago where some
> complained "but that would be hard to implement", and the solution
> being mostly correct but failing in this case.
>
> I seem to recall NEXT being created in order to do things like this:
>
> for @objs {
> .print;
> NEXT { print ", " }
> LAST { print "\n" }
> }
>
> We also might consider using perl6's hypothetical features to
> implement NEXT correctly in all cases (except for those cases where
> the loop update condition cannot be hypotheticalized).

Is this even possible? This would require Perl to know which iteration is


going to be the last one. In many cases there is no way to know this:

repeat {
$num = rand;
print $num;
NEXT {print ',';}
LAST {print "\n";}
} while $num < 0.9;

If rand is a true random-number generator it would take a time machine to
determine whether to call NEXT or LAST.
(Sorry for the double post.)

Joe Gottman

Jonathan Scott Duff

unread,
Aug 18, 2006, 12:16:17 AM8/18/06
to Joe Gottman, Perl6 Language List

Depends on when it fires I guess. Your example might be equivalent to
this perl5ish:

while (1) {


$num = rand;
print $num;

last if $num < 0.9;
print ","; # NEXT
}
print "\n"; # LAST

-Scott
--
Jonathan Scott Duff
du...@pobox.com

Luke Palmer

unread,
Aug 18, 2006, 3:44:35 AM8/18/06
to du...@pobox.com, Joe Gottman, Perl6 Language List
On 8/17/06, Jonathan Scott Duff <du...@pobox.com> wrote:
> Depends on when it fires I guess. Your example might be equivalent to
> this perl5ish:
>
> while (1) {
> $num = rand;
> print $num;
> last if $num < 0.9;
> print ","; # NEXT
> }
> print "\n"; # LAST

Which, incidentally, relates back to the discussion at hand. If this
were the case, though, the state of the variables (in three-arg for
loops and side-effecty while loops) would seem to reflect the state of
the next iteration from the rest of the code. It would also
(obviously) fire after user input for eg. a for =<> loop.

So, unless the next paragraph is feasible, I think NEXT ought to be
equivalent to LEAVE, perhaps with the exception of exceptional
circumstances.

But I was talking about hypotheticalization. That is, unless I am
mistaken we have temp {} and let {} using UNDO blocks (which are given
default definitions where possible). So perhaps we could use that
feature to provide a NEXT trait which actually executes only if there
is a next iteration, while giving the block the impression that it is
executing in the previous iteration. This, of course, would not work
for loops whose conditions have irreversible side-effects.

Overall, it might be feasible in some circumstances, but it may not be
worth it. Its implementation (and usage caveats) are quite complex
for a relatively minor convenience feature. For a user to implement
its effect by himself, using the extended knowledge he has of the loop
semantics, would probably not take more than four extra lines in the
worst case.

Luke

Larry Wall

unread,
Aug 18, 2006, 11:46:48 AM8/18/06
to Perl6 Language List
On Fri, Aug 18, 2006 at 01:44:35AM -0600, Luke Palmer wrote:
: On 8/17/06, Jonathan Scott Duff <du...@pobox.com> wrote:
: >Depends on when it fires I guess. Your example might be equivalent to
: >this perl5ish:
: >
: > while (1) {
: > $num = rand;
: > print $num;
: > last if $num < 0.9;
: > print ","; # NEXT
: > }
: > print "\n"; # LAST
:
: Which, incidentally, relates back to the discussion at hand. If this
: were the case, though, the state of the variables (in three-arg for
: loops and side-effecty while loops) would seem to reflect the state of
: the next iteration from the rest of the code. It would also
: (obviously) fire after user input for eg. a for =<> loop.
:
: So, unless the next paragraph is feasible, I think NEXT ought to be
: equivalent to LEAVE, perhaps with the exception of exceptional
: circumstances.

I think it is equivalent to LEAVE, unless you've explicitly opted out
with "last" or an exception.

: But I was talking about hypotheticalization. That is, unless I am


: mistaken we have temp {} and let {} using UNDO blocks (which are given
: default definitions where possible). So perhaps we could use that
: feature to provide a NEXT trait which actually executes only if there
: is a next iteration, while giving the block the impression that it is
: executing in the previous iteration. This, of course, would not work
: for loops whose conditions have irreversible side-effects.
:
: Overall, it might be feasible in some circumstances, but it may not be
: worth it. Its implementation (and usage caveats) are quite complex
: for a relatively minor convenience feature. For a user to implement
: its effect by himself, using the extended knowledge he has of the loop
: semantics, would probably not take more than four extra lines in the
: worst case.

It would mean that we can't use NEXT to replace Perl 5's "continue"
blocks, for instance, since those are required to run before the
while loop's condition is tested. Which also basically means we
couldn't rewrite loop (;;) using NEXT. So I think NEXT should just
be equivalent to LEAVE from the viewpoint of conditionals outside
the loop body. You have to use "last" to do better.

Larry

Joe Gottman

unread,
Aug 18, 2006, 9:49:21 PM8/18/06
to Perl6 Language List

> -----Original Message-----
> From: Larry Wall [mailto:la...@wall.org]
> Sent: Friday, August 18, 2006 11:47 AM
> To: Perl6 Language List
> Subject: Re: NEXT and the general loop statement
>

One alternative that would work well in many cases would be to define a
REENTER block, which would be called at the beginning of any loop iteration
after the first one. This would be much easier to implement that the idea of
NEXT blocks being mutually exclusive to LAST blocks, because it depends only
on what happened in the past, not the future. Luke's example could then be
implemented as

for @objs {
.print;
REENTER { print ", " }
LAST { print "\n" }
}

In a language that has both if and unless, it makes sense to have a block
that means not FIRST. I'm not sure about the name; besides REENTER, other
possible names would be SUBSEQUENT or NOTFIRST.

Joe Gottman

Agent Zhang

unread,
Sep 7, 2006, 9:59:45 AM9/7/06
to Perl6 Language List
On 8/17/06, Larry Wall <la...@wall.org> wrote:
>
> I'd say 01234 on the theory that the 3-arg loop is really saying:
>
> $n = 0;
> while $n < 5 {
> NEXT { ++$n }
> NEXT { print $n }
> }
>
> and also on the theory that block exiting blocks always run in reverse order.
>

Dear Larry, I think it's important enough to explicitly express this
rule in S04 after the following IRC conversation with Audrey:

<agentzh> audreyt: do multiple NEXT {} run in the reversed order?
<audreyt> I don't know, actually.
<audreyt> I don't have a clear intuision of what makes sense.
<agentzh> larry once said on p6l that quitting blocks should run in
reversed order.
<audreyt> I read that too. thing is, is NEXT quitting or entering...
<audreyt> I can argue either way eloquently, which means it's best deferred to
TimToady, sorry :)

Cheers,
Agent

0 new messages