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

Nested statement modifiers.

23 views
Skip to first unread message

Paul Seamons

unread,
Sep 1, 2006, 12:52:00 PM9/1/06
to p6l
I'm not sure if I have seen this requested or discussed.

Is there a parsing reason why Perl 6 would allow nested statement modifiers or
is it mainly a sanity-please-don't-hurt-my-eyes reason.

It is silly to do things such as:

say "Interesting" if $just_because if $because;

But it is sort of useful to be able to do things such as:

say "Hrm $_" for 1 .. 3 unless $why_not;

The grammar_rules.pg defines a statement as:

token statement {
| <statement_control>
| <block>
| <control_block>
| <class_block>
| <use_statement>
| <expression: ;> <statement_modifier>?
}

It seems like it should be possible to change that to:

token statement {
| <statement_control>
| <block>
| <control_block>
| <class_block>
| <use_statement>
| <expression: ;> <statement_modifier>*
}

pge2past.tg would need to be updated to loop on found statement modifiers
rather than only do the first one found. I'm afraid I'm not familiar enough
with PIR to write the looping portion but I can read the following section
enought to know that it shouldn't be too hard to change. The question is
would a patch to add the functionality be accepted if I went to the trouble
of figuring out how to do it?

Paul Seamons


Section of pge2past.tg that re-writes the expression to be enclosed by an if
block:

transform past (Perl6::Grammar::statement) :language('PIR') {
$P0 = node['statement_control']
if $P0 goto statement_control
$P0 = node['block']
if $P0 goto statement_block
$P0 = node['use_statement']
if $P0 goto statement_use

expression:
.local pmc stmt
$P0 = node['expression']
stmt = tree.'get'('past', $P0, 'Perl6::Grammar::expression')
$P0 = node['statement_modifier']
unless $P0 goto expression_1
stmt_modifier:
# handle if/unless modifier
.local pmc modifier, exprpast, thenpast, elsepast
modifier = $P0[0]
thenpast = stmt
null elsepast
$S0 = modifier['KEY']
if $S0 != 'unless' goto stmt_modifier_1
exchange thenpast, elsepast
stmt_modifier_1:
$P0 = modifier['expression']
exprpast = tree.'get'('past', $P0, 'Perl6::Grammar::expression')
stmt = new 'Perl6::PAST::Op'
stmt.'init'(exprpast, thenpast,
elsepast, 'name'=>'statement_control:if', 'node'=>modifier)

expression_1:

Trey Harris

unread,
Sep 1, 2006, 1:02:58 PM9/1/06
to Paul Seamons, p6l
In a message dated Fri, 1 Sep 2006, Paul Seamons writes:

> I'm not sure if I have seen this requested or discussed.

This was definitively rejected by Larry in 2002:

http://www.nntp.perl.org/group/perl.perl6.language/9343

He has not revisited the issue in the several times it has come up since.

Trey

Jerry Gay

unread,
Sep 1, 2006, 1:05:25 PM9/1/06
to Trey Harris, Paul Seamons, p6l
perhaps a sentence to that effect belongs in S04, which has no mention
of nested statement modifiers, for or against.
~jerry

Trey Harris

unread,
Sep 1, 2006, 1:08:00 PM9/1/06
to jerry gay, Paul Seamons, p6l

Well, that's because Synopses at least in theory only refer to changes
from Perl 5. Perl 5 doesn't allow more than one statement modifier, and
Perl 6 doesn't either.

Trey

Paul Seamons

unread,
Sep 1, 2006, 1:44:59 PM9/1/06
to perl6-l...@perl.org
> This was definitively rejected by Larry in 2002:

Yes. That is good to see and I do think I remember seeing that or some similar
postings come to think of it. Thank you for shaking my memory.

Now it is 2006. Object syntax has changed. Little bits and pieces (and
sometimes larger chunks) of the Perl 6 grammar have changed and reverted and
changed again.

I don't know what the reasoning was back then and it may be the same today.
I'm just wondering what that reason is. Maybe nested statement modifiers
promote bad language skills. Maybe its because statement modifiers have
always been frowned upon in the language and it wasn't a good idea to promote
their status. Maybe it was very difficult to allow for parsing of nested
statement modifiers. Maybe it was too difficult to rewrite the operation
tree. Maybe nested statement modifiers violate spoken language too much.

I can see some of these reasons still being valid. But others I don't see
being valid anymore. It is trivial to change the grammar. It is some
patches to the tg file to allow it to loop (which may take some more effort).
It is a feature that may not be used by many but is useful to others.

The following is one more interesting case.

say "Ok then" if $yes and $true unless $no or $false;

Without nested modifiers you'd have either:

say "Ok then" if $yes and $true and ! $no and ! $false;

or

say "OK then" unless ! $yes or ! $true or $no $or $false;

And everybody knows you shouldn't use double negatives.

I can't change the mind of Larry but the mind of Larry can be changed. I
can't speak for others, but I have found myself wanting to do similar things
in Perl 5 and I would wager other people have also.

I'll be quiet if you'd like me to be, unless you don't want me to be. :)

Paul

Dr.Ruud

unread,
Sep 1, 2006, 4:20:21 PM9/1/06
to perl6-l...@perl.org
Paul Seamons schreef:

> The following is one more interesting case.
>
> say "Ok then" if $yes and $true unless $no or $false;
>
> Without nested modifiers you'd have either:
>
> say "Ok then" if $yes and $true and ! $no and ! $false;
>
> or
>
> say "OK then" unless ! $yes or ! $true or $no $or $false;
>
> And everybody knows you shouldn't use double negatives.

$no or $false or $yes and $true and say "OK then" ;

$no or $false or say "OK then" if $yes and $true ;

--
Affijn, Ruud

"Gewoon is een tijger."


Paul Seamons

unread,
Sep 1, 2006, 5:10:10 PM9/1/06
to perl6-l...@perl.org
> $no or $false or $yes and $true and say "OK then" ;
>
> $no or $false or say "OK then" if $yes and $true ;

Thank you for your reply.

I know there are other ways to do it. I've had no choice but to do it other
ways in Perl5.

I don't think I have ever used that notation (outside of file open and
close) - not because I don't know it, but because it puts the emphasis on the
wrong values. It also doesn't read very smoothly.

In the samples you gave I had to read the entire line to see what the outcome
of the code is. In code you either give emphasis to the condition or to the
action that happens should the condition prove successful. Generally
speaking, if the condition is the most important thing I will put it in a
normal if/unless block.

if ($no or $false) {
die "Some horrible death" unless $i_should_not;
}

But if the action is more important then I tend use a modifier.

print_greeting("Hello") if $logged_in unless $asked_not_too;

Allowing for multiple nested modifiers allows the action to retain its
significance. After I sent the last email I came across a statement in the
code I was working on that would have phrased better if I could use both an
if and an unless. These things do come up - we Perl 5 coders have just
trained ourselves to do things another ways.

The biggest setback I see to nested modifiers is that the order of lexical
scopes visually read on the screen are reversed in execution. But that is
already a problem with a single level statement modifier. I don't think
multiple levels introduces any more problem than is already there.

Plus - if there are multiple modifiers then Perl poetry can get even better.
And everybody wins if Perl poetry is better. :)

say "I'm ok"
if $i_am_ok
if $you_are_ok
while $the_world_is_ok;

Paul

Randal L. Schwartz

unread,
Sep 2, 2006, 10:47:50 AM9/2/06
to perl6-l...@perl.org
>>>>> "Paul" == Paul Seamons <par...@seamons.com> writes:

Paul> I don't know what the reasoning was back then and it may be the same today.

From my early conversations with Larry, I recall that the reason is that
RSTS/E BASIC-PLUS had nested trailing modifiers, and both Larry and I saw many
abuses of these over the years. Therefore, he decided not to repeat that
abomination, limiting it to precisely one level deep. I'm happy for that.

Yeah, every once in a while, I've wanted the second layer, but I'm willing to
rewrite the statement as a true normal if/while instead of a backwards
if/while, and it *does* help the overall readability.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<mer...@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Dr.Ruud

unread,
Sep 2, 2006, 12:17:10 PM9/2/06
to perl6-l...@perl.org
Paul Seamons schreef:

> In the samples you gave I had to read the entire line to see
> what the outcome of the code is.

I was not addressing reading skills, but just your "you'd either have
... or ...". One always needs to read the full line, but one doesn't
have to do that linearly or just from left to right.

Read Perl's "or" as "skip if the previous was true", and speed-reading
such
constructs is in your bag.


There are plenty of cases where you too want the conditions up front.

A. $strong_objection1 or $strong_objection2 or
$half_a_reason1 and $half_a_reason2 and $weight *= 1.00001 ;

B. $no_way > 0.8 or $you_must_be_crazy > 0.9 or
$let_s_try > 0.6 and $you_never_know > 0.5 and $weight *= 1.00001 ;

C. $weight *= 1.00001 if $let_s_try > 0.6 and $you_never_know > 0.5
unless $no_way > 0.8 or $you_must_be_crazy > 0.9 ;

D. unless $no_way > 0.8 or $you_must_be_crazy > 0.9
{
if $let_s_try > 0.6 and $you_never_know > 0.5
{
$weight *= 1.00001
}
}

E. unless $no_way > 0.8 or $you_must_be_crazy > 0.9
{
$weight *= 1.00001 if $let_s_try > 0.6 and $you_never_know > 0.5
}


Assuming all variants are alternatives, I prefer E.

A-E aren't alternatives if the value of the (last) evaluated expression
counts:

F. $strong_objection1 or $strong_objection2 !!
$half_a_reason1 and $half_a_reason2 ?? ($weight *= 1.00001)
:: weight
:: weight ;

G. $strong_objection1 or $strong_objection2 ?? weight
::
$half_a_reason1 and $half_a_reason2 !! weight
:: ($weight *= 1.00001) ;

H. $strong_objection1 or $strong_objection2 ?? weight
::
$half_a_reason1 and $half_a_reason2 ?? ($weight *= 1.00001)
:: weight ;


> Allowing for multiple nested modifiers allows the action to retain its
> significance. After I sent the last email I came across a statement
> in the code I was working on that would have phrased better if I
> could use both an if and an unless. These things do come up - we
> Perl 5 coders have just trained ourselves to do things another ways.

Or use a block. I am all for multiple nested modifiers, but not because
I need the action up front, I just happen to like the lean look.

$weight *= 1.00001 if $half_a_reason1 and $half_a_reason2
unless $strong_objection1 or $ $strong_objection2 ;


unless $strong_objection1 or $ $strong_objection2
{
$weight *= 1.00001
if $half_a_reason1 and $half_a_reason2 ;
} ;


> The biggest setback I see to nested modifiers is that the order of
> lexical scopes visually read on the screen are reversed in execution.
> But that is already a problem with a single level statement modifier.
> I don't think multiple levels introduces any more problem than is
> already there.

It's just the same thing. Some people don't have problems using them,
many do.


> Plus - if there are multiple modifiers then Perl poetry can get even
> better. And everybody wins if Perl poetry is better. :)
>
> say "I'm ok"
> if $i_am_ok
> if $you_are_ok
> while $the_world_is_ok;

You can't even get near natural language. For example: in natural
language a double negation is often used to emphasize the negation.

Paul Seamons

unread,
Sep 3, 2006, 1:14:12 AM9/3/06
to perl6-l...@perl.org
> From my early conversations with Larry, I recall that the reason is that
> RSTS/E BASIC-PLUS had nested trailing modifiers, and both Larry and I saw
> many abuses of these over the years. Therefore, he decided not to repeat
> that abomination, limiting it to precisely one level deep. I'm happy for
> that.

Thank you. This is the sort of answer I was looking for.

> Yeah, every once in a while, I've wanted the second layer, but I'm willing
> to rewrite the statement as a true normal if/while instead of a backwards
> if/while, and it *does* help the overall readability.

I'd concede that the actual useful uses are rare enough to not warrant giving
a feature that could turn hopelessly ugly quickly - even if the current
generation of tools make it easy to add the feature.

Paul

Paul Seamons

unread,
Sep 3, 2006, 1:53:17 AM9/3/06
to perl6-l...@perl.org
> > Yeah, every once in a while, I've wanted the second layer, but I'm
> > willing to rewrite the statement as a true normal if/while instead of a
> > backwards if/while, and it *does* help the overall readability.
>
> I'd concede that the actual useful uses are rare enough to not warrant
> giving a feature that could turn hopelessly ugly quickly - even if the
> current generation of tools make it easy to add the feature.

Sorry to respond to my own post. As soon as I sent the reply I still felt an
itch for a second level.

I agree that such a thing could be abused as Randal mentioned. But how many
things are there in Perl 5 and Perl 6 that can't be abused (sorry - that is a
sort of subjective thing to ask so I am putting it out hypothetically)? It
still seems odd to take some things out of the language but leave others in
(ok - most things that have been left out have made perfect sense). I'm much
more a fan of the leaving in if the thing being left in doesn't have an
exponential cost and if there isn't a good reason to exclude it.

We still have goto statements. We have map and grep that now go forwards -
but can still go backwards.

Taking it out doesn't necessarily prevent abuses since we now have repeat.

repeat {
repeat {
say "Oh no. Not again";
} while $x++ < 10;
} while $y++ < 2;

As opposed to

say "Yes. Yes again"
while $x++ < 10
while $y++ < 2;

Additionally reading the documentation about repeat it seems that the
following should already be allowed since the conditional statement on a
repeat is not optional and if it doesn't come first then it MUST come later
and if it MUST come later then it isn't a modifier.

my $x = 1; repeat { say "hello"; $x = 0 } while $x if $x;

Though I would expect the following to break because it wouldn't know to parse
for the modifier after the closing brace:

my $x = 1; repeat while $x { say "hello"; $x = 0 } if $x;

This is what pugs does - though I'm not sure what it means.

pugs> my $x = 1; repeat { say "hello"; $x = 0 } while $x;
hello
0
pugs> my $x = 1; repeat { say "hello"; $x = 0 } while $x if $x;
....>

I think it means that I will probably need to have the correct behavior be
clarified to me, obtain a commit bit and add a test to pugs.

Anyway. Once again if the alleged crime or the predicted crime is too great
then I concede. I can see that it could be abused by some. But that doesn't
mean I will abuse it.

Paul

PS. And not that it matters, but TT3 is planned to support nested statement
modifiers and my engine which does much of TT3 already supports them - and I
do use them on occasion - but that's a different mailing list.

Aaron Sherman

unread,
Oct 3, 2006, 1:46:51 PM10/3/06
to Trey Harris, p6l
Trey Harris wrote:
> In a message dated Fri, 1 Sep 2006, jerry gay writes:
>
>> On 9/1/06, Trey Harris <tr...@eecs.harvard.edu> wrote:
>>> In a message dated Fri, 1 Sep 2006, Paul Seamons writes:
>>>
>>> > I'm not sure if I have seen this requested or discussed.
>>>
>>> This was definitively rejected by Larry in 2002:

>> perhaps a sentence to that effect belongs in S04, which has no mention


>> of nested statement modifiers, for or against.
>
> Well, that's because Synopses at least in theory only refer to changes
> from Perl 5. Perl 5 doesn't allow more than one statement modifier, and
> Perl 6 doesn't either.

In Perl 5, it's:

sub {sub {print 1 if 1}->() if 1}->() if 1;

In Perl 6, that's simplified to:

{{say 1 if 1}.() if 1}.() if 1;

Since expressions can always be a closure wrapped around a statement,
any statement can always be an expression.

Of course, that wasn't exactly what you were asking, but it does present
a practical solution when you want to:

{say $_ for =<>}.() if $do_read_input;

Which I just verified works fine under current pugs.

Paul Seamons

unread,
Oct 3, 2006, 2:06:01 PM10/3/06
to perl6-l...@perl.org
> Of course, that wasn't exactly what you were asking, but it does present
> a practical solution when you want to:
>
> {say $_ for =<>}.() if $do_read_input;
>
> Which I just verified works fine under current pugs.

Thank you.

Hadn't thought of that. I think that is workable.

But it also brings the question: If you can do it ugly [1] easily, why not
allow for it do be done prettily [2] ?

say $_ for =<> if $do_read_input

Paul

[1] It isn't really that ugly - just not as pretty.
[2] Arguably the "pretty" version is also more ambiguous whereas the "ugly"
version leaves little room for doubt.

Aaron Sherman

unread,
Oct 3, 2006, 3:01:19 PM10/3/06
to Paul Seamons, perl6-l...@perl.org
Paul Seamons wrote:
>> Of course, that wasn't exactly what you were asking, but it does present
>> a practical solution when you want to:
>>
>> {say $_ for =<>}.() if $do_read_input;
>>
>> Which I just verified works fine under current pugs.
>
> Thank you.
>
> Hadn't thought of that. I think that is workable.
>
> But it also brings the question: If you can do it ugly [1] easily, why not
> allow for it do be done prettily [2] ?
>
> say $_ for =<> if $do_read_input

It relates to some old problems in the early part of the RFC/Apocalypse
process, and the fact that:

say $_ for 1..10 for 1..10

Was ambiguous. The bottom line was that you needed to define your
parameter name for that to work, and defining a parameter name on a
modifier means that you have to parse the expression without knowing
what the parameters are, which is ugly in a very non-stylistic sense.

To resolve that, the modifiers are limited to one per statement. There's
nothing that can be done about:

{say $_ for 1..10}.() for 1..10

but at least then you are going out of your way to shoot yourself in the
foot, so presumably you knew the risks. Others who are not so bold will
write:

for 1..10 -> ($a) {
for 1..10 -> ($b) {
say $b;
}
}

And ambiguity is gone.

Paul Seamons

unread,
Oct 3, 2006, 4:04:34 PM10/3/06
to perl6-l...@perl.org
> It relates to some old problems in the early part of the RFC/Apocalypse
> process, and the fact that:
>
> say $_ for 1..10 for 1..10
>
> Was ambiguous. The bottom line was that you needed to define your
> parameter name for that to work, and defining a parameter name on a
> modifier means that you have to parse the expression without knowing
> what the parameters are, which is ugly in a very non-stylistic sense.

Again, thank you for your reply.

I don't think that is ambiguous though. If you view statement modifiers in
their unwrapped state, that example isn't any more ambiguous than

for 1..10 {
for 1..10 {
say $_
}
}

The question is sort of related to asking if these two examples are equivalent
not just in operation, but also in how they scope.

Is the following a syntax error in Perl6:

use strict;
my $a = 1;
my $x for $a;
$x;

It isn't under Perl5 - but will it be under Perl6.

Either way the nested statement modifiers would work even if scopes aren't
introduced at each level.

.say for 1..$_ for 2..5;

I think it reads sort of nicely left to right.

Paul

Aaron Sherman

unread,
Oct 3, 2006, 4:34:11 PM10/3/06
to Paul Seamons, perl6-l...@perl.org
Paul Seamons wrote:
>> It relates to some old problems in the early part of the RFC/Apocalypse
>> process, and the fact that:
>>
>> say $_ for 1..10 for 1..10
>>
>> Was ambiguous. The bottom line was that you needed to define your
>> parameter name for that to work, and defining a parameter name on a
>> modifier means that you have to parse the expression without knowing
>> what the parameters are, which is ugly in a very non-stylistic sense.

> I don't think that is ambiguous though.

It really is, and the very first question that everyone asks is: how do
I get access to the outer loop variable, which of course, you cannot for
the reasons stated above.

Let's get P6 out the door, and then discuss what tiny details like this
do or don't make sense.

Juerd

unread,
Oct 3, 2006, 6:39:00 PM10/3/06
to perl6-l...@perl.org
Aaron Sherman skribis 2006-10-03 13:46 (-0400):

> In Perl 6, that's simplified to:
> {{say 1 if 1}.() if 1}.() if 1;

Which can also be written as:

do { do { say 1 if 1 } if 1 } if 1;

Which if crammed together the way you wrote it, turns into:

do {do {say 1 if 1} if 1} if 1;

Or perhaps you like this even better:

do{do{say 1 if 1}if 1}if 1;

I find that hard to guess. I personally think the statement is confusing
anyhow, with or without whitespace. Besides, stacked "if"-statements
really don't make any sense. We've already got "and" for that! :)

say 1 if 1 and 1 and 1;

Oh, and 1 is always true. So you could just write:

say 1;

Which seems like a great improvement.

It may be more useful to discuss this issue using less contrived
examples. :)
--
korajn salutojn,

juerd waalboer: perl hacker <ju...@juerd.nl> <http://juerd.nl/sig>
convolution: ict solutions and consultancy <sa...@convolution.nl>

Damian Conway

unread,
Oct 3, 2006, 7:40:29 PM10/3/06
to perl6-l...@perl.org
Juerd wrote:

> Which can also be written as:
>
> do { do { say 1 if 1 } if 1 } if 1;

Sorry, no it can't. From S4
(http://dev.perl.org/perl6/doc/design/syn/S04.html#The_repeat_statement):

"Unlike in Perl 5, applying a statement modifier to a do block is
specifically disallowed

Damian Conway

unread,
Oct 3, 2006, 7:46:41 PM10/3/06
to perl6-l...@perl.org
[Apologies for the last post. Gmail got a little eager.
Here's what I meant to send...]

Juerd wrote:

> Which can also be written as:
>
> do { do { say 1 if 1 } if 1 } if 1;

"Unlike in Perl 5, applying a statement modifier to a do block is

specifically disallowed..."


FWIW, I completely agree with Larry that multiple postfix modifiers are a bad
idea and would only serve impair the comprehensibility of code (even in the
cases where they're not ambiguous).

Damian

Audrey Tang

unread,
Oct 3, 2006, 9:31:07 PM10/3/06
to dam...@conway.org, perl6-l...@perl.org

在 Oct 4, 2006 7:46 AM 時,Damian Conway 寫到:

> [Apologies for the last post. Gmail got a little eager.
> Here's what I meant to send...]
>
> Juerd wrote:
>
>> Which can also be written as:
>>
>> do { do { say 1 if 1 } if 1 } if 1;
>
> Sorry, no it can't. From S4
> (http://dev.perl.org/perl6/doc/design/syn/
> S04.html#The_repeat_statement):
>
> "Unlike in Perl 5, applying a statement modifier to a do block is
> specifically disallowed..."

However, I wonder if this is too strict. Disallowing "while" and
"until" after a do block
is fine (and can be coded directly in those two statement modifier
macros), but is there a
reason to disallow other modifiers?

Thanks,
Audrey

Damian Conway

unread,
Oct 3, 2006, 10:17:40 PM10/3/06
to perl6-l...@perl.org
Audrey asked:

> However, I wonder if this is too strict. Disallowing "while" and
> "until" after a do block is fine (and can be coded directly in those
> two statement modifier macros), but is there a reason to disallow
> other modifiers?

Well, for a start, there's this syntactic problem:

do { say "vale, munde asper"; mori(); }
if $lang eq 'Latinus';

As well as the fact that do..if has no discernable advantage in either
writability
or readability over:

if $lang eq 'Latinus' {
say "vale, munde asper"; mori();
}

Damian

Audrey Tang

unread,
Oct 3, 2006, 10:39:10 PM10/3/06
to dam...@conway.org, perl6-l...@perl.org

在 Oct 4, 2006 10:17 AM 時,Damian Conway 寫到:

> Audrey asked:
>
>> However, I wonder if this is too strict. Disallowing "while" and
>> "until" after a do block is fine (and can be coded directly in those
>> two statement modifier macros), but is there a reason to disallow
>> other modifiers?
>
> Well, for a start, there's this syntactic problem:
>
> do { say "vale, munde asper"; mori(); }
> if $lang eq 'Latinus';

*nod* The use case here is

do { .foo for @bar } if $baz;

But I guess you can always "protect" it with a parens:

(do { .foo for @bar }) if $baz;

Which also makes the syntactic problem go away. So indeed,
disallowing statement modifiers after do{} altogether seems sane.

Thanks!
Audrey

Damian Conway

unread,
Oct 3, 2006, 11:20:09 PM10/3/06
to perl6-l...@perl.org
> The use case here is
>
> do { .foo for @bar } if $baz;
>
> But I guess you can always "protect" it with a parens:
>
> (do { .foo for @bar }) if $baz;

Or just:

if $baz { .foo for @bar }

or even:

@bar».foo if $baz;

;-)

Damian

Markus Laire

unread,
Oct 4, 2006, 3:55:26 AM10/4/06
to perl6-l...@perl.org
On 10/3/06, Aaron Sherman <a...@ajs.com> wrote:
> Paul Seamons wrote:
> >> It relates to some old problems in the early part of the RFC/Apocalypse
> >> process, and the fact that:
> >>
> >> say $_ for 1..10 for 1..10
> >>
> >> Was ambiguous. The bottom line was that you needed to define your
> >> parameter name for that to work, and defining a parameter name on a
> >> modifier means that you have to parse the expression without knowing
> >> what the parameters are, which is ugly in a very non-stylistic sense.
>
> > I don't think that is ambiguous though.
>
> It really is, and the very first question that everyone asks is: how do
> I get access to the outer loop variable, which of course, you cannot for
> the reasons stated above.

What about $OUTER::_ ? Shouldn't that access the outer $_ ?

> Let's get P6 out the door, and then discuss what tiny details like this
> do or don't make sense.

--
Markus Laire

Juerd

unread,
Oct 4, 2006, 4:16:26 AM10/4/06
to perl6-l...@perl.org
Damian Conway skribis 2006-10-03 16:40 (-0700):

> >Which can also be written as:
> > do { do { say 1 if 1 } if 1 } if 1;
> Sorry, no it can't. From S4
> (http://dev.perl.org/perl6/doc/design/syn/S04.html#The_repeat_statement):
> "Unlike in Perl 5, applying a statement modifier to a do block is
> specifically disallowed

Oh. For some reason, I thought this exception was for loops only.

Markus Laire

unread,
Oct 4, 2006, 6:48:19 AM10/4/06
to perl6-l...@perl.org
On 10/4/06, Juerd <ju...@convolution.nl> wrote:
> Damian Conway skribis 2006-10-03 16:40 (-0700):
> > >Which can also be written as:
> > > do { do { say 1 if 1 } if 1 } if 1;
> > Sorry, no it can't. From S4
> > (http://dev.perl.org/perl6/doc/design/syn/S04.html#The_repeat_statement):
> > "Unlike in Perl 5, applying a statement modifier to a do block is
> > specifically disallowed
>
> Oh. For some reason, I thought this exception was for loops only.

According to S04 C<do { ... }> is a loop, "The do-once loop".

--
Markus Laire

Paul Seamons

unread,
Oct 4, 2006, 10:22:11 AM10/4/06
to perl6-l...@perl.org
> It may be more useful to discuss this issue using less contrived
> examples. :)

I would agree. I haven't had any use for a double "if" or a double "for".

The double "if" case is handled by "&&". The double "for" case is handled
by "for" and "map".

The interesting cases are combinations of "if" and "for" and "while"
and "unless".

.say if cond($_) for =<>;

That one is sort of not necessary now that grep can be lazy.

.say for =<> if $read_the_rest;

Which can obviously be written in other ways using other constructs, but not
without changing how the statement reads or changing what it emphasizes.

And as for Perl6 - well yes I'd love to see it get here more quickly also.
But I don't think that discussing little nitpicks like this are delaying the
release of Perl6. Maybe they are - but I would guess there are more pressing
issues that are occupying development time.

Paul

Aaron Sherman

unread,
Oct 4, 2006, 10:35:05 AM10/4/06
to dam...@conway.org, perl6-l...@perl.org
Damian Conway wrote:

> @bar».foo if $baz;

That brought to mind the question that I've had for some time: how are
exceptions going to work on hyper-operators?

Will they kill the hyperoperation in-progress? e.g. what will $i be:

my $i = 0;
class A { method inci() { die if $i++ > 5 } }
my Array of A @aoa;
try { @aoa>>.inci; }
say $i;

Is it even possible to know, or is it entirely dependent on the
implementation? And what do multiple, successive dies within the same
try block do?

Aaron Sherman

unread,
Oct 4, 2006, 10:40:05 AM10/4/06
to perl6-l...@perl.org
Aaron Sherman wrote:
> Damian Conway wrote:
>
>> @bar».foo if $baz;
>
> That brought to mind the question that I've had for some time: how are
> exceptions going to work on hyper-operators?
>
> Will they kill the hyperoperation in-progress? e.g. what will $i be:

Corrected example follows (there were supposed to be 10 elements):

> my $i = 0;
> class A { method inci() { die if $i++ > 5 } }

> my @aoa = map {A.new} 1..10;


> try { @aoa>>.inci; }
> say $i;

We now return you to your regularly scheduled question, already in progress:

Larry Wall

unread,
Oct 4, 2006, 12:35:28 PM10/4/06
to perl6-l...@perl.org

An uncaught exception is going to blow you out of the hyperoperator
when it's partway done, just like any other operator. Since a
hyperoperator is a promise that you don't care about ordering of side
effects, any code that relies on a particular implementation's ordering
of side effects is erroneous.

Which is all an excellent argument for unthrown exceptions being
the norm. Then the hyper can proceed to completion and you just
have to be careful how you use the resulting undefined values.
For hypers that must produce unboxed native types, you don't have
the undef option, but at least IEEE floaters give you NaN and Inf.

This also tells me that we'll occasionally want to turn normally fatal
exceptions into unthrown exceptions. Fortunately, Perl 6 specifies
that CATCH blocks run before the stack is unwound, so this should be
possible in theory. Of course, this is not guaranteed to work unless
the undef value is returned immediately to the hyperoperator manager,
since the called code may not have anticipated that it might have to
continue with an undefined value.

All the more reason to encourage use of "fail" rather than "die".

Larry

0 new messages