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

S04

9 views
Skip to first unread message

Juerd

unread,
Jan 29, 2005, 11:59:40 AM1/29/05
to perl6-l...@perl.org
Some questions after reading S04:


Can last/redo be used outside loops? (i.e. with if or given)

Is a bare block still a loop?

Can loop be used as a statement modifier? (say 'y' loop;)

Can OUTER be stacked? ($OUTER::OUTER::_)


TIA.


Juerd

Larry Wall

unread,
Jan 29, 2005, 2:08:58 PM1/29/05
to perl6-l...@perl.org
On Sat, Jan 29, 2005 at 05:59:40PM +0100, Juerd wrote:
: Some questions after reading S04:

:
:
: Can last/redo be used outside loops? (i.e. with if or given)

No, though of course what "loop" means is negotiable. Effectively,
anything that captures the appropriate control exceptions is a loop.
But I think the design is best served if it's pretty well known what
an "official" loop is, much as we say what an official "sub" is so
that we know which entity is exited when you say "return". To that end,
the control exceptions for next/last/redo may well include information
on which outer lexical scope is intended, presuming there's a surrounding
lexical scope that is the obvious target. The p5-ish behavior of
scanning out the dynamic scopes for an appropriate label would perhaps
be a fallback if there is no appropriate lexical scope. In other words,
if you say "next METHOD", and there's a METHOD: label in your current
sub, we should probably assume the user means that METHOD label rather
than the METHOD label on the implicit method dispatcher.

: Is a bare block still a loop?

We need a do-once loop. Or if we don't exactly need it, it certainly
turned out to be handy in Perl 5, if only to provide a switch statement.
I think it would be surprising, though, to turn C<given> into a loop.
Plus, it has other difficulties as a do-once loop. It requires an
argument before the closure, and it clobbers $_. C<for 1> suffers
similarly.

So there's some argument for keeping bare {...} as a do-once loop.
It doesn't suffer the argument problems of C<given>, though it does
suffer from a bit surprising to newcomers. But this morning it occurs
to me that if we defined C<do {...}> to be a do-once loop, it kind of
naturally rules out putting an C<until> or C<while> modifier on it,
since you then have conflicting loop specifications. I realize that's
just a rationalization, since you could certainly define it such that
the do {...} nested inside the statement modifier. But I'm looking
at it more from a psychological-space viewpoint here, and since we're
outlawing do-while anyway, we might as well give people a semilogical
reason for it, which they can take as a semological reason if they like.

But speaking of semology, another psychological argument in favor of
that is that the longer construct should have more semantics than the
shorter one. That is, the marked form should do more than the unmarked
form. Plus the simple fact that introducing loop semantics into bare
blocks at the same time as making all blocks closures potentially
introduces halting-problem-ish non-optimizabilities--how can we know
that the bare block isn't going to execute a "next" someplace in it.

So for the moment, let's say that bare block is not a loop, but a C<do>
block is. It might provide some short-term confusion to Perl 5 programmers,
but I think the risk is worth it, unless someone can spot additional
difficulties.

: Can loop be used as a statement modifier? (say 'y' loop;)

Seems awfully obscure just to save two curlies, and I'm not sure the
fact that something is an infinite loop can ever be construed as
unimportant enough to be relegated to the right margin.

: Can OUTER be stacked? ($OUTER::OUTER::_)

Yep. You'll note it's not a subtle construct--this is quite intentional.

: TIA.

YWIR.

Larry

Juerd

unread,
Jan 29, 2005, 2:49:03 PM1/29/05
to Larry Wall, perl6-l...@perl.org
Thank you for your fast and detailed reply.

Larry Wall skribis 2005-01-29 11:08 (-0800):


> On Sat, Jan 29, 2005 at 05:59:40PM +0100, Juerd wrote:
> : Can last/redo be used outside loops? (i.e. with if or given)
> No, though of course what "loop" means is negotiable. Effectively,
> anything that captures the appropriate control exceptions is a loop.

redo could be useful in subs or even file scope.

CATCH { when Fatal { reset; redo; } }

And in given, for those who don't like fall-through:

GIVEN: given $foo {
when /^0x/ { $_.=hex; redo GIVEN; }
...
}

# Heh, I guess here $_.=hex, $_=hex and $_=.hex all do the same
# thing :)

> So there's some argument for keeping bare {...} as a do-once loop.

> (..) But this morning it occurs


> to me that if we defined C<do {...}> to be a do-once loop, it kind of
> naturally rules out putting an C<until> or C<while> modifier on it,
> since you then have conflicting loop specifications.

It also kind of naturally rules out that do { } is for grouping
statements in an expression, because it'd behave *very* differently in
void context. And wasn't Perl 6 supposed to weed out weird exceptions? :)

$foo = %*ENV<FOO>;

$foo = do { print "Foo: "; readline } until $foo.validate; # valid
do { print "Foo: "; $foo = readline } until $foo.validate; # invalid?

Maybe it doesn't hurt to tell people who need a once-loop to just use
loop with last:

loop {
...
last;
}

Those who find comfort in knowing beforehand that it'll only run once,
can use NEXT { last } :)

Juerd

David Storrs

unread,
Feb 10, 2005, 10:39:54 AM2/10/05
to perl6-l...@perl.org
Given that Perl 6 won't support an actual do-while loop a la C++ (and
yes, I know that Perl5 didn't either), how would you accomplish that?
That is, I'd like to have a loop that runs once, then checks its
condition to see if it should repeat and continues to repeat as long
as the condition is true.

I don't think this works, but here's what I'm look for:

{
$foo = readline;
...do stuff with $foo...
} while ( $foo );

--Dks



Luke Palmer

unread,
Feb 10, 2005, 11:59:23 AM2/10/05
to perl6-l...@perl.org

There's been some discussion about bringing a syntax back for that
recently, but I haven't really been paying attention. Anyway, this is
pretty clear:

loop {
$foo = readline;
do { stuff :with($foo) };
last unless $foo;
}

Luke

Larry Wall

unread,
Feb 10, 2005, 12:45:59 PM2/10/05
to perl6-l...@perl.org
On Thu, Feb 10, 2005 at 07:39:54AM -0800, David Storrs wrote:
: Given that Perl 6 won't support an actual do-while loop a la C++ (and

That's spelled

loop {


$foo = readline;
...do stuff with $foo...
} while ( $foo );

these days.

Larry

Aaron Sherman

unread,
Feb 10, 2005, 4:58:10 PM2/10/05
to Luke Palmer, Perl6 Language List
On Thu, 2005-02-10 at 11:59, Luke Palmer wrote:

> There's been some discussion about bringing a syntax back for that
> recently, but I haven't really been paying attention. Anyway, this is
> pretty clear:
>
> loop {
> $foo = readline;
> do { stuff :with($foo) };
> last unless $foo;
> }

Well, yes it's clear, but then you run into the problem where your code
looks like:

while stuff() {
more_stuff();
}
loop {
other_more_stuff();
last unless other_stuff();
}

and then you want to add something like:

next if things();

to both... you have to do it in two ways. The Perl 6ish way of dealing
with this is:

while stuff() {
next if things();
more_stuff();
}
loop {
next if other_things();
other_more_stuff();
NEXT { last unless other_stuff(); }
}

I think Larry's contention has been that loop is all you really need,
and everything else is a macro. If you really want dowhile, then it's
something like (making up macro example on the fly, and probably wrong
here...):

macro infix:dowhile (Code $block, Bool $cond) {
loop { $block.(); NEXT { last unless $cond.() } }
}

{
next if other_things();
other_more_stuff();
} dowhile other_stuff();

Of course, that assumes that an expanded macro will, by default, handle
the case when you pass it code that invokes a loop control, expecting to
control the loop inside the macro first.


--
781-324-3772
a...@ajs.com
http://www.ajs.com/~ajs

David Storrs

unread,
Feb 10, 2005, 2:51:11 PM2/10/05
to perl6-l...@perl.org
On Thu, Feb 10, 2005 at 09:45:59AM -0800, Larry Wall wrote:

> That's spelled
>
> loop {
> $foo = readline;
> ...do stuff with $foo...
> } while ( $foo );
>
> these days.
>
> Larry

Cool, perfect. Thanks.

--Dks

--
dst...@dstorrs.com

0 new messages