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

Blocks and semicolons

35 views
Skip to first unread message

Piers Cawley

unread,
Sep 11, 2002, 3:47:46 AM9/11/02
to perl6-l...@perl.org
So, the new rule for blocks and when the need semicolons seems to be
"You don't need a semicolon if the block is the last argument of a
subroutine which expects a block as its last argument", which is all
very well and all, but where does that leave:

sub foo ( &block ) {...}
...
$wibble = foo { ... } + 10;

The problem here is that this change makes the meaning of every brace
dependent on everything that's gone before and we're back with a
language that's at least as hard as Perl 5 was to parse.

Now, my understanding was that the rule for 'statement terminating
braces' was


1. brace matches rx/^^ \s* \} \s* $$/

Or, less strictly:

2. brace matches rx/ } \s* $$/

Which I could have *sworn* was something Damian had told me was the
right thing, but I've mislaid the original mail. The idea behind this
approach, judging by the Apocalypse, is that it means that instead of
blocks needing or not needing a semicolon based on special cases, all
blocks have a simple rule.

Here's what Apocalypse 4 says on the subject:

If there is any space before the curly, we force it to start a
term, not an operator, which means that the curlies in question
must delimit either a hash composer or a block. And it's a hash
composer only if it contains a => pair constructor at the top level
(or an explicit hash keyword on the front.) Therefore it's possible
to unambiguously terminate an expression by following it with a
block

Which seems to imply that:

$wibble = foo {...} + 10;

would actually be parsed as:

$wibble = foo {...}; +10;

Ah... hang on, that's *expression* not statement, so that should parse
as C<< $wibble = foo( sub {...}) + 10; >> which is fine.

The rules for what the parser infers (semicolon, comma, nothing) after
a block are somewhat undefined though. How would

func $foo {...}
func $bar {...}
func $baz {...}

deparse? C<< func $foo {...}; func $bar {...}; func $baz {...}; >>?
C<< func $foo {...}, func $bar {...}, func $baz {...} >>?

Am I worrying unduly about nothing?

What was my question? Argh! I'm more confused now then when I started
this message...

--
Piers

"It is a truth universally acknowledged that a language in
possession of a rich syntax must be in need of a rewrite."
-- Jane Austen?

Smylers

unread,
Sep 11, 2002, 2:43:09 PM9/11/02
to perl6-l...@perl.org
Piers Cawley wrote:

> So, the new rule for blocks and when the need semicolons seems to be
> "You don't need a semicolon if the block is the last argument of a
> subroutine which expects a block as its last argument", which is all

> very well and all, but ... Ah... hang on, that's *expression* not
> statement, so that should parse ... fine.

>
> Am I worrying unduly about nothing?
>
> What was my question? Argh! I'm more confused now then when I started
> this message...

I'm wondering how implied semicolons will interact with statement
modifiers.[*0] This is Damian's example of calling a user-defined sub
without a trailing semicolon:

perhaps $x<$y, 0.25 { print "Happened to be less than\n"}

Presumably it's valid to put a statement modifier on such a line (with a
semicolon after it, obviously):

perhaps $x < $_, 0.4 { print "Smaller\n"} for @max;

Presumably it's also possible to have such a line (without a statement
modifier) with a for loop as the following statement, and for that loop
to use the new syntax for iterating through multiple lists in parallel:

perhaps $x < $_, 0.4 { print "Smaller\n"}
for @max; @min -> $top; $bottom
{
# etc
}

How are these two cases distinguished from each other?

Since whitespace is interchangeable, the second fragment could be
formatted like this to make it look even more like the first:

perhaps $x < $_, 0.4 { print "Smaller\n"} for @max;
@min -> $top; $bottom
{
# etc
}

I'm scared.

[*0] I actually tried to wonder this on this list last week. As I'm
not subscribed I thought that posting through the newsgroup interface
would be the best way of keep threading. I tried posting through Google
Groups. My article showed up there (see link below), but doesn't seem
to have filtered through to other places. Is it supposed to?

I'm posting this with a newsreader rather than a web-browser so
hopefully it'll get through. Apologies to anybody who got it twice.

http://groups.google.co.uk/groups?hl=en&ie=UTF-8&oe=UTF-8&threadm=d7c367d5.0209051022.9ba6bea%40posting.google.com&rnum=1

Smylers

Luke Palmer

unread,
Sep 11, 2002, 4:38:30 PM9/11/02
to Smylers, perl6-l...@perl.org
This is for everyone: <<EOA4

In Perl, this problem comes up most often when people say "Why do I
have to put a semicolon after do {} or eval {} when it looks like a
complete statement?"

Well, in Perl 6, you don't, if the final curly is on a line by itself.
That is, if you use an expression block as if it were a statement
block, it behaves as one. The win is that these rules are consistent
across all expression blocks, whether user-defined or built-in. Any
expression block construct can be treated as either a statement or a
component of an expression. Here's a block that is being treated as a
term in an expression:
$x = do {
...
} + 1;

However, if you write
$x = do {
...
}
+ 1;
then the + will be taken erroneously as the start of a new statement.
(So don't do that.)

Note that this special rule only applies to constructs that take a
block (that is, a closure) as their last (or only) argument. Operators
like sort and map are unaffected. However, certain constructs that
used to be in the statement class may become expression constructs in
Perl 6. For instance, if we change BEGIN to an expression construct we
can now use a BEGIN block inside an expression to force compile-time
evaluation of a non-static expression:
$value = BEGIN { call_me_once() } + call_me_again();

On the other hand, a one-line BEGIN would then have to have a
semicolon.

EOA4

To me, this looks like it has answers to all these questions.

Luke

Smylers

unread,
Sep 11, 2002, 4:53:23 PM9/11/02
to perl6-l...@perl.org
Luke Palmer wrote:

> This is for everyone: <<EOA4
>

> ... put a semicolon after do {} or eval {} when it looks like a


> complete statement?"
>
> Well, in Perl 6, you don't, if the final curly is on a line by
> itself.
>

> To me, this looks like it has answers to all these questions.

It would do, but 'A4' considerably predates that example I quoted from
Damian. It was only on August 28th this year that he said these are
fine without semicolons:

perhaps $x<$y, 0.25 { print "Happened to be less than\n"}

perhaps $x>$y, 0.50 { print "Happened to be greater than\n"}

Those braces definitely aren't on their own lines. This is the message
where he said it:

http://groups.google.co.uk/groups?&hl=en&ie=UTF-8&oe=UTF-8&threadm=3D6D4E7D.6070201%40conway.org&rnum=1&prev=/groups%3Fq%3Dg:thl477944572d%26dq%3D%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D3D6D4E7D.6070201%2540conway.org

He said something similar in the Perl 6 talk in London the following day
(and quite possibly other Perl 6 talks elsewhere at other times). So
the possibilities are:

1 Damian is wrong.

2 I've misunderstood what Damian said and wrote.

3 This bit of 'A4' has been superseded and the current thinking is
what Damian said above.

Option 1 strikes me as unlikely; Damian obviously has read 'A4'.

Option 3 is what scares me and is the reason why I'm after
clarification.

Given that, Option 2 would be a relief. (An embarrassment, but still a
relief.)

Smylers

Piers Cawley

unread,
Sep 11, 2002, 4:55:37 PM9/11/02
to Luke Palmer, Smylers, perl6-l...@perl.org
Luke Palmer <fibo...@babylonia.flatirons.org> writes:

Up to a point. Look at the discussion of given/when in the same
Apocalypse. Here's some example code from A4:


given $! {
when Error::Overflow { ... }
when Error::Type { ... }
when Error::ENOTTY { ... }
when /divide by 0/ { ... }
...
}

Look, closing braces, ending statements, not on a line by
themselves. There's code like this all through the apocalypse and its
associated Exegesis, so it looks to me like C<< rx/\} \s* \n/ >> is
the regex for 'end of statement'. Either that or we're back with a
pile of special cases, which I thought the Apocalypse was supposed to
be eliminating.

Smy...@stripey.com

unread,
Sep 11, 2002, 6:16:16 PM9/11/02
to Luke Palmer, Piers Cawley, perl6-l...@perl.org
Luke Palmer wrote:

[Piers wrote:]

> > Look, closing braces, ending statements, not on a line by
> > themselves. There's code like this all through the apocalypse and
> > its associated Exegesis, so it looks to me like C<< rx/\} \s* \n/ >>
> > is the regex for 'end of statement'. Either that or we're back with
> > a pile of special cases, which I thought the Apocalypse was supposed
> > to be eliminating.
>

> That's because C<when>s are statements. Statements don't need to be
> terminated. In C (or even Perl 5) you don't need to write:
>
> if (a < b) { foo(); };
>
> That's because the grammar says that conditionals (and loops) are
> statements all by themselves, because this doesn't make sense:
>
> 1 + if (a < b) { foo(); } / 2;
>
> But in Perl 6, things are moving around. Perl 6 needs the ability for
> users to program such interfaces with subs, which I<are> expressions.
> So, according to Damian, if a sub's last argument is a closure, it can
> (but not necessarily will) act like a statement rather than an
> expression.

The way I remember hearing Damian explain it was the other way round --
that many things that have been statements will now be built-in
functions that take closures as arguments, and that they won't have any
special powers that user-defined functions can't.

I'm reasonably sure it was that way round, cos Damian saying it (in
London) provoked me into asking "Does that mean that C<if> now needs a
semicolon after the block?" I'm reasonably sure the answer was that any
sub with a closure as a final argument can be invoked without a trailing
semicolon.

> From what I understand of his message, this has nothing to do with
> whitespace.

I think so too, which definitely disagrees with 'A4'.

> I don't know the exact semantics, if they are what I think they are,
then
> I disagree.
>
> sub cond_if ($condition, &code) {...} # returns something
>
> cond_if ($x < $y) { $y }
> for @a; @b; @c; # ...
>
> This requires infinite lookahead to parse.

Yup.

> Personally, I liked the A4 decision the best ('}' on a line by
> itself),

I'm not overly keen on that because it suddenly gives line-breaks a
special meaning. The rule in Perl at the moment that all whitespace is
interchangeable and you can arrange your code as you like is very
simple. Adding a special case (aka 'inconsistency') for a single
punctuation character sounds to be against the spirit of 'A5''s intro,
about making things simpler and more consistent.

I think I'd be happy enough with requiring semicolons at the end of all
statements, including C<if> blocks, C<sub> definitions -- everything.
It'd at least be consistent (and the problem with C<eval> and anonymous
C<sub> blocks in Perl 5 is not the semicolon _per se_, just the
semicolon there compared to the lack of one elsewhere).

> and I think otherwise there's too many ambiguities like this one.
> However, if an elegant solution has been (or is going to be) found,
> I'm all ears.

Smylers

Luke Palmer

unread,
Sep 11, 2002, 5:48:48 PM9/11/02
to Piers Cawley, Smylers, perl6-l...@perl.org
> Luke Palmer wrote:
> > [quote from A4]

> > To me, this looks like it has answers to all these questions.
>
> Up to a point. Look at the discussion of given/when in the same
> Apocalypse. Here's some example code from A4:
>
>
> given $! {
> when Error::Overflow { ... }
> when Error::Type { ... }
> when Error::ENOTTY { ... }
> when /divide by 0/ { ... }
> ...
> }
>
> Look, closing braces, ending statements, not on a line by
> themselves. There's code like this all through the apocalypse and its
> associated Exegesis, so it looks to me like C<< rx/\} \s* \n/ >> is
> the regex for 'end of statement'. Either that or we're back with a
> pile of special cases, which I thought the Apocalypse was supposed to
> be eliminating.

That's because C<when>s are statements. Statements don't need to be

terminated. In C (or even Perl 5) you don't need to write:

if (a < b) { foo(); };

That's because the grammar says that conditionals (and loops) are
statements all by themselves, because this doesn't make sense:

1 + if (a < b) { foo(); } / 2;

But in Perl 6, things are moving around. Perl 6 needs the ability for
users to program such interfaces with subs, which I<are> expressions. So,
according to Damian, if a sub's last argument is a closure, it can (but
not necessarily will) act like a statement rather than an expression.

From what I understand of his message, this has nothing to do with
whitespace.

I don't know the exact semantics, if they are what I think they are, then
I disagree.

sub cond_if ($condition, &code) {...} # returns something

cond_if ($x < $y) { $y }
for @a; @b; @c; # ...

This requires infinite lookahead to parse. Nobody likes infinite
lookahead grammars.

Personally, I liked the A4 decision the best ('}' on a line by itself),

and I think otherwise there's too many ambiguities like this one.
However, if an elegant solution has been (or is going to be) found, I'm
all ears.

Luke


Ken Fox

unread,
Sep 12, 2002, 9:25:06 AM9/12/02
to Luke Palmer, Piers Cawley, Smylers, perl6-l...@perl.org
Luke Palmer wrote:
> This requires infinite lookahead to parse. Nobody likes infinite
> lookahead grammars.

Perl already needs infinite lookahead. Anyways, most people
don't care whether a grammar is ambiguous or not -- if we did,
natural human languages would look very different.

People want expressive languages. (Some people even consider
ambiguity a feature. Poets? Comedians? Lawyers?)

I don't know how we should handle code blocks, but I do know
that the answer should solve human problems, not yacc's.

Perl 5 doesn't accept either of these loops:

if ($_) { print "$_\n" } for (qw(1 0));
print "$_\n" if ($_) for (qw(1 0));

The code must be written as:

for (qw(1 0)) {
print "$_\n" if ($_)
}

Why won't a similar solution work for user-defined syntax in
Perl 6? (It would be no worse than Perl 5...)

- Ken

Luke Palmer

unread,
Sep 12, 2002, 10:58:03 AM9/12/02
to Ken Fox, Piers Cawley, Smylers, perl6-l...@perl.org
On Thu, 12 Sep 2002, Ken Fox wrote:

> Luke Palmer wrote:
> > This requires infinite lookahead to parse. Nobody likes infinite
> > lookahead grammars.
>
> Perl already needs infinite lookahead. Anyways, most people
> don't care whether a grammar is ambiguous or not -- if we did,
> natural human languages would look very different.

Really? Where?

Computers don't like ambiguous grammars, because they don't know which to
execute. Ambiguity is a feature in natural language, but not computer.
Or you could make a language that selects a meaning randomly, but that
just feels too much like INTERCAL :).

> Perl 5 doesn't accept either of these loops:
>
> if ($_) { print "$_\n" } for (qw(1 0));
> print "$_\n" if ($_) for (qw(1 0));

Indeed. But in Perl 5, C<if> is not a sub. This is valid:

eval { print "foo\n" } for @ar;

And I've been hearing that you can do this in Perl 6:

eval { print "foo\n" }

(of course with C<try> instead, but this is more illustrative)
And _that_ is a terminated statement. But it's also an expression. This
is problematic, because of the ambiguity presented earlier.

> The code must be written as:
>
> for (qw(1 0)) {
> print "$_\n" if ($_)
> }
>
> Why won't a similar solution work for user-defined syntax in
> Perl 6? (It would be no worse than Perl 5...)

Because subs have to work as expressions. It would all be well and good if
you had to give an C<if>-like sub a special property:

sub perhaps ($cond, $prob, &code) is statement {...}

But somehow that doesn't seem very elegant.

Luke

Ken Fox

unread,
Sep 12, 2002, 11:46:35 AM9/12/02
to Luke Palmer, Ken Fox, Piers Cawley, Smylers, perl6-l...@perl.org
Luke Palmer wrote:
> On Thu, 12 Sep 2002, Ken Fox wrote:
> > Perl already needs infinite lookahead.
>
> Really? Where?

Indirect objects need infinite lookahead and they are
in the core language. Hyper operators may need lookahead.
Place holders may need lookahead. User defined rules
will definitely need infinite lookahead. (Remember we
are switching from LR to LL parsing. LL(1) parsing is
not as powerful as LR(1), so Perl 6 will need lookahead
even in places where Perl 5 doesn't.)

> Computers don't like ambiguous grammars ...

The "dangling else" problem is ambiguous. Every time you
get a shift-reduce conflict in yacc, you have an ambiguous
grammar. Computers don't care about ambiguous grammars,
but some of the common tools (yacc) disambiguate whether
we like it not. ;)

BTW, there are some parser generators that handle
ambiguous grammars -- they either support backtracking,
infinite lookahead, or simultaneously parse all possible
derivations. In the case of the simultaneous parse, they
can actually return multiple parse trees and let the
code generator decide how to interpret things.

> But in Perl 5, C<if> is not a sub.

> ...


> Because subs have to work as expressions.

In Perl 6 the difference between "sub" and "syntax" is
almost non-existant. Some subs will behave like built-in
syntax, some subs will behave like "normal" function
calls. (AFAIK, the only difference is that subs can not
provide lazy argument evaluation. Maybe the "is rx"
property eliminates even that? BTW, does anybody else
find "is rx" funny? "This is your argument. This is your
argument on drugs." (Rx is an abbreviation for drug
prescription in the U.S.))

I think Perl 5's solution for handling "if" can be
applied to Perl 6 subs that look like syntax. It might
not be an improvement over Perl 5, but at least it's
no worse.

A better solution may be to continue the parse until
we see if "for" is followed by a block. (That's really
hard to do with yacc, which might be why Perl 5 does
what it does.)

- Ken

Luke Palmer

unread,
Sep 12, 2002, 12:29:37 PM9/12/02
to Ken Fox, Piers Cawley, Smylers, perl6-l...@perl.org
> BTW, there are some parser generators that handle
> ambiguous grammars -- they either support backtracking,
> infinite lookahead, or simultaneously parse all possible
> derivations. In the case of the simultaneous parse, they
> can actually return multiple parse trees and let the
> code generator decide how to interpret things.

A la my very own Parse::Earley. But don't try to use the parse "graph"
yet, as it is near impossible to traverse.

> > But in Perl 5, C<if> is not a sub.
> > ...
> > Because subs have to work as expressions.
>
> In Perl 6 the difference between "sub" and "syntax" is
> almost non-existant. Some subs will behave like built-in
> syntax, some subs will behave like "normal" function
> calls. (AFAIK, the only difference is that subs can not
> provide lazy argument evaluation. Maybe the "is rx"
> property eliminates even that? BTW, does anybody else
> find "is rx" funny? "This is your argument. This is your
> argument on drugs." (Rx is an abbreviation for drug
> prescription in the U.S.))

Yeah, that's exactly why I said that.

This discussion is getting rather stagnant, so I'll just back off and let
the design team work all this out.

> I think Perl 5's solution for handling "if" can be
> applied to Perl 6 subs that look like syntax. It might
> not be an improvement over Perl 5, but at least it's
> no worse.
>
> A better solution may be to continue the parse until
> we see if "for" is followed by a block. (That's really
> hard to do with yacc, which might be why Perl 5 does
> what it does.)
>
> - Ken

Luke

Brent Dax

unread,
Sep 12, 2002, 12:47:06 PM9/12/02
to kf...@vulpes.com, Luke Palmer, Piers Cawley, Smylers, perl6-l...@perl.org
Ken Fox:
# derivations. In the case of the simultaneous parse, they can
# actually return multiple parse trees and let the code
# generator decide how to interpret things.

Of course, in Perl 6, they'd return a superposition of all possible
parses, and trying to use the superposition would cause it to collapse
to one of the possibilities. :^)

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

"In other words, it's the 'Blow up this Entire Planet and Possibly One
or Two Others We Noticed on our Way Out Here' operator."
--Damian Conway

mosul...@crtinc.com

unread,
Sep 12, 2002, 1:12:42 PM9/12/02
to perl6-l...@perl.org
From: Ken Fox f...@mail.msen.com

> BTW, does anybody else find "is rx" funny?

Only because they're not called regular expressions anymore. How about
"px" for "pattern expression"?

-Miko

--------------------------------------------------------------------
mail2web - Check your email from the web at
http://mail2web.com/ .


Nicholas Clark

unread,
Sep 13, 2002, 4:25:25 PM9/13/02
to Brent Dax, kf...@vulpes.com, Luke Palmer, Piers Cawley, Smylers, perl6-l...@perl.org
On Thu, Sep 12, 2002 at 09:47:06AM -0700, Brent Dax wrote:
> Of course, in Perl 6, they'd return a superposition of all possible
> parses, and trying to use the superposition would cause it to collapse
> to one of the possibilities. :^)

Aargh, he's using a hyper-smiley. I can't be sure what sort of "joking"
is going on.

And please don't give Damian any more evil ideas. He's got quite enough of
his own, and doesn't need encouraging. :-)

> "In other words, it's the 'Blow up this Entire Planet and Possibly One
> or Two Others We Noticed on our Way Out Here' operator."
> --Damian Conway

Also heard at his talk to london.pm was, as best I remember it:

"I'm still subscribed to the london.pm list, but I don't reply to any
messages as it only encourages them"

Nicholas Clark
--
Even better than the real thing: http://nms-cgi.sourceforge.net/

Aaron Sherman

unread,
Sep 13, 2002, 4:49:31 PM9/13/02
to kf...@vulpes.com, Perl6 Language List
On Thu, 2002-09-12 at 11:46, Ken Fox wrote:

> In Perl 6 the difference between "sub" and "syntax" is
> almost non-existant. Some subs will behave like built-in
> syntax, some subs will behave like "normal" function
> calls. (AFAIK, the only difference is that subs can not
> provide lazy argument evaluation.

There was a thread a couple of weeks ago about how to write subroutines
that would evaluate arguments lazily, so yes, even that is gone.

However, I wanted to bring up what I see as the far-too-many ways to
pass parameters, and see if anyone already has a unifying concept:

1. Simple parameters:

sub foo($a)

2. Defaulted parameters:

sub foo($a //= 1)

3. Defaulted parameters based on topic:

sub foo($a //= $_)

4. Topic-passing:

sub grep(&code,*@list) { my @r; for @list->$_ { push @r, $_ if code($_); @r } }

5. Funky-assed regsub:

$x =~ s:i/\bperl\s*5\b/Perl 6/;

This last one eats my brains. It has a grand total of 5 different types
of parameter passing! It has:

quote-like regex
quote-like lazy string
modifiers
topic-passing
closure

C<=~> is sort of a sixth, but it's more of a macro operator that calls
C<s> with a topic set.

This one is sticky to write in Perl 6, as far as I can tell. You could
have something like this:

sub s(rx $pattern, $replacement is lazy, $string is rw //= $_)
is quotelike, rx($modifiers) {
# Handle s-specific modifiers, and remove them....
if m:$modifiers/<$pattern>/ {
$string = $0.before _ $replacement.eval($0.match) _ $0.after;
}
# Possibly repeat, assuming :each
}

Questions:

1. Can you say C<$string is rw //= $_>?
2. How would C<s> pass C<$modifiers> on to a sub-expression?
I used m:$modifiers, above, but that's a guess
3. Is C<quotelike> a doable property?
4. Would "is lazy" be right for the replacement?
It needs to act as a special case closure

Here's another ugly scenario: let's say you have a flattened list in
your parameters and you also want to operate on the topic. How would you
specify that? Here's an example:

sub x($a,*@b) { ... }

How do I pass a topic to that?


--
Aaron Sherman <a...@ajs.com>
http://www.ajs.com/~ajs

Luke Palmer

unread,
Sep 13, 2002, 6:03:07 PM9/13/02
to Aaron Sherman, kf...@vulpes.com, Perl6 Language List
On 13 Sep 2002, Aaron Sherman wrote:

> 4. Topic-passing:
>
> sub grep(&code,*@list) { my @r; for @list->$_ { push @r, $_ if code($_); @r } }

Huh? What's special about this case? This looks pretty regular to me.
Are you referring to the for? That's basically just a synonym, for
convenience.

> Questions:
>
> 1. Can you say C<$string is rw //= $_>?

Why wouldn't you be able to?

> 3. Is C<quotelike> a doable property?

Hopefully :), or something with similar functionality. Possibly parsed with
C<is rx//> rules. C<is rx//> is something that needs a lot of thought too.
It doesn't seem feasable just to ask for a regular expression, given all the
things that can come from an expression.

On the other hand, there I<are> grammars. I hope C<eval> can take a perl parse
tree as an argument.

> 4. Would "is lazy" be right for the replacement?
> It needs to act as a special case closure

The Perl 5 way would be to take a literal string, and eval it inside a qq//.
Of course, in the caller's scope, however you do that. I hope there's a more
elegant way than that. But this is standard library code, which is seldom
elegant.

> Here's another ugly scenario: let's say you have a flattened list in
> your parameters and you also want to operate on the topic. How would you
> specify that? Here's an example:
>
> sub x($a,*@b) { ... }
>
> How do I pass a topic to that?

Declare it thus:

sub x($topic //= $_, $a, *@b);

No function should only operate on the topic. Er.. except m//, except when
there's an =~, oh crap. You could use a special C<but> property, that defaults
to $_, so you could also do a m// on something other than $_ with:

m:w/foo bar/ but target($str);

Which is how =~ would do it. I'm sure this will be possible once we figure out
how to define C<but> properties.

Luke


Brent Dax

unread,
Sep 13, 2002, 6:23:59 PM9/13/02
to Aaron Sherman, kf...@vulpes.com, Perl6 Language List
Aaron Sherman:
# 4. Topic-passing:
#
# sub grep(&code,*@list) { my @r; for @list->$_ { push
# @r, $_ if code($_); @r } }

I fail to see the weirdness in this one.

# 5. Funky-assed regsub:
#
# $x =~ s:i/\bperl\s*5\b/Perl 6/;
#
# This last one eats my brains. It has a grand total of 5
# different types of parameter passing! It has:
#
# quote-like regex
# quote-like lazy string
# modifiers
# topic-passing
# closure
#
# C<=~> is sort of a sixth, but it's more of a macro operator
# that calls C<s> with a topic set.
#
# This one is sticky to write in Perl 6, as far as I can tell.
# You could have something like this:
#
# sub s(rx $pattern, $replacement is lazy, $string is rw //= $_)
# is quotelike, rx($modifiers) {
# # Handle s-specific modifiers, and remove them....

Are there any left? No /e equivalent, at least...

# if m:$modifiers/<$pattern>/ {
# $string = $0.before _
# $replacement.eval($0.match) _ $0.after;
# }
# # Possibly repeat, assuming :each
# }

How about:

sub s(
string $targ is rw target:
RULE $pattern, string $replacement is lazy:
*@modi is modifier
) is quotelike {
# Assumes that you can call quotelikes
# as functions.
while m($targ: $pattern: @modi) {
$0.text = $replacement;
}
}

# Questions:
#
# 1. Can you say C<$string is rw //= $_>?

Sure. Why not?

# 2. How would C<s> pass C<$modifiers> on to a sub-expression?
# I used m:$modifiers, above, but that's a guess

See what I did.

# 3. Is C<quotelike> a doable property?

I would assume that it would be, though perhaps you would need to pass a
2 to it for s///. (Or perhaps not--maybe it can tell that there are two
arguments in the "middle" area.)

# 4. Would "is lazy" be right for the replacement?
# It needs to act as a special case closure

I suppose so...

# Here's another ugly scenario: let's say you have a flattened
# list in your parameters and you also want to operate on the
# topic. How would you specify that? Here's an example:
#
# sub x($a,*@b) { ... }
#
# How do I pass a topic to that?

Depending on what you mean by the question, one of:

sub x($a //= $_, *@b) { ... }
sub x($a, *@b //= $_) { ... }

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

"In other words, it's the 'Blow up this Entire Planet and Possibly One

Aaron Sherman

unread,
Sep 14, 2002, 1:29:08 AM9/14/02
to Luke Palmer, Perl6 Language List
On Fri, 2002-09-13 at 18:03, Luke Palmer wrote:
> On 13 Sep 2002, Aaron Sherman wrote:
>
> > 4. Topic-passing:
> >
> > sub grep(&code,*@list) { my @r; for @list->$_ { push @r, $_ if code($_); @r } }
>
> Huh? What's special about this case? This looks pretty regular to me.
> Are you referring to the for? That's basically just a synonym, for
> convenience.

code($_) is passing a topic, not really expecting code() to take a
parameter.

> > Questions:
> >
> > 1. Can you say C<$string is rw //= $_>?
>
> Why wouldn't you be able to?

Because this indicates defaulting to a binding, which was not something
I'd heard mentioned as valid.


> > 4. Would "is lazy" be right for the replacement?
> > It needs to act as a special case closure
>
> The Perl 5 way would be to take a literal string, and eval it inside a qq//.
> Of course, in the caller's scope, however you do that. I hope there's a more
> elegant way than that. But this is standard library code, which is seldom
> elegant.

Yeah, this is a hard one, since

s/x/y/

is really sort of like:

s(rx/x/, sub{"y"})

But it's even a bit scarier, since hypotheticals and bound
subexpressions created inside the first parameter are available inside
the second... It's actually more like:

m(rx/x/) && replace(sub{"y"});

Gah!

> > Here's another ugly scenario: let's say you have a flattened list in
> > your parameters and you also want to operate on the topic. How would you
> > specify that? Here's an example:
> >
> > sub x($a,*@b) { ... }
> >
> > How do I pass a topic to that?
>
> Declare it thus:
>
> sub x($topic //= $_, $a, *@b);

What happens if I call that like so:

x(1,2,3,4,5);

It looks to me like $topic is 1 (it doesn't default because the argument
was provided).

> No function should only operate on the topic. Er.. except m//, except when
> there's an =~, oh crap.

I assumed C<=~> was just a fancy operator for setting the topic.

There are a lot of functions that default to just operating on the
topic. From the Perl 5 perlfunc:

abs Returns the absolute value of its argument. If VALUE is
omitted, uses $_.

There are a lot of those....

Aaron Sherman

unread,
Sep 14, 2002, 1:35:12 AM9/14/02
to Brent Dax, Perl6 Language List
On Fri, 2002-09-13 at 18:23, Brent Dax wrote:
> Aaron Sherman:

> # sub x($a,*@b) { ... }
> #
> # How do I pass a topic to that?
>
> Depending on what you mean by the question, one of:
>
> sub x($a //= $_, *@b) { ... }
> sub x($a, *@b //= $_) { ... }

No, I'm thinking of a case (I think it was sprintf or pack or something
like that) where the parameters were all passed normally, but in some
special cases it needed access to $_ for something. So, you don't want
to default $a or @b, you just want to access the caller's topic.

Piers Cawley

unread,
Sep 14, 2002, 2:40:34 AM9/14/02
to Aaron Sherman, Brent Dax, Perl6 Language List
Aaron Sherman <a...@ajs.com> writes:

Doesn't

caller.MY{'$_'}

do what you want, within the body of the function.

Aaron Sherman

unread,
Sep 14, 2002, 2:48:36 AM9/14/02
to Piers Cawley, Perl6 Language List
On Sat, 2002-09-14 at 02:40, Piers Cawley wrote:
> Aaron Sherman <a...@ajs.com> writes:

> > No, I'm thinking of a case (I think it was sprintf or pack or something
> > like that) where the parameters were all passed normally, but in some
> > special cases it needed access to $_ for something. So, you don't want
> > to default $a or @b, you just want to access the caller's topic.
>
> Doesn't
>
> caller.MY{'$_'}
>
> do what you want, within the body of the function.

It depends on what you mean by what I want. Shouldn't the compiler be
able to optimize that topic away if no one is using it? There should be
some way for well mannered functions with odd signatures to say "I need
that", no?

Luke Palmer

unread,
Sep 14, 2002, 4:06:45 AM9/14/02
to Aaron Sherman, Perl6 Language List
On 14 Sep 2002, Aaron Sherman wrote:

> On Fri, 2002-09-13 at 18:03, Luke Palmer wrote:
> > On 13 Sep 2002, Aaron Sherman wrote:
> >
> > > 4. Topic-passing:
> > >
> > > sub grep(&code,*@list) { my @r; for @list->$_ { push @r, $_ if code($_); @r } }
> >
> > Huh? What's special about this case? This looks pretty regular to me.
> > Are you referring to the for? That's basically just a synonym, for
> > convenience.
>
> code($_) is passing a topic, not really expecting code() to take a
> parameter.

Oh, then that's a syntax error. Too many arguments to sub code.

> > > Here's another ugly scenario: let's say you have a flattened list in
> > > your parameters and you also want to operate on the topic. How would you
> > > specify that? Here's an example:
> > >
> > > sub x($a,*@b) { ... }
> > >
> > > How do I pass a topic to that?
> >
> > Declare it thus:
> >
> > sub x($topic //= $_, $a, *@b);
>
> What happens if I call that like so:
>
> x(1,2,3,4,5);
>
> It looks to me like $topic is 1 (it doesn't default because the argument
> was provided).

I was saying that you shouldn't *have* to use the topic. You can, if the
argument is omitted, thus, a default.

> > No function should only operate on the topic. Er.. except m//, except when
> > there's an =~, oh crap.
>
> I assumed C<=~> was just a fancy operator for setting the topic.

Apparently you forgot about that gigantic section in A4 about it. But in
the case of s/// and m//, I suppose that's true. Well, except for this:

$_ = rx/ foo /;
$str =~ /$_/;

Does that match $str against 'foo', or $str against itself? Can't remember
what the decision was, if there was one.

> There are a lot of functions that default to just operating on the
> topic. From the Perl 5 perlfunc:
>
> abs Returns the absolute value of its argument. If VALUE is
> omitted, uses $_.
>
> There are a lot of those....

Yep. When the argument's omitted. I don't believe there are any functions
along the lines of:

abs Returns the absolute value of $_. It takes no arguments.

In other words, C<//= $_> is all you should need.

Once again, with the exception of the matching operators, for which I
showed a solution that I quite liked. By the end of the design process,
possibly due to laziness, I swear we're going to have 500 properties.

Luke

Luke Palmer

unread,
Sep 14, 2002, 4:16:13 AM9/14/02
to Aaron Sherman, Perl6 Language List
On Sat, 14 Sep 2002, Luke Palmer wrote:

> On 14 Sep 2002, Aaron Sherman wrote:
>
> > On Fri, 2002-09-13 at 18:03, Luke Palmer wrote:
> > > On 13 Sep 2002, Aaron Sherman wrote:
> > >
> > > > 4. Topic-passing:
> > > >
> > > > sub grep(&code,*@list) { my @r; for @list->$_ { push @r, $_ if code($_); @r } }
> > >
> > > Huh? What's special about this case? This looks pretty regular to me.
> > > Are you referring to the for? That's basically just a synonym, for
> > > convenience.
> >
> > code($_) is passing a topic, not really expecting code() to take a
> > parameter.
>
> Oh, then that's a syntax error. Too many arguments to sub code.

Ohh right. Here's what you're missing:

When a bare closure is defined, it behaves the same as a signatureless
sub. That is, it topicalizes the first argument, and hands them all over
in @_. So your "topic passing" is just, well, passing the topic, like
any ol' argument.

Luke

Brent Dax

unread,
Sep 19, 2002, 4:51:57 PM9/19/02
to Aaron Sherman, Luke Palmer, Perl6 Language List
Aaron Sherman:
# topicalize: To default to C<$_> in a prototype (thus
# acquiring the caller's current topic).

Well, to topicalize a region of code is actually to specify a different
topic, that is, a different value for $_. For example:

$foo = new X;
$bar = new Y;

given $foo {
print $_.type, "\n"; #prints "X"

given $bar {
#XXX we're using 'given' for this too, right?
print $_.type, "\n"; #prints "Y"
}
}

(An aside: it strikes me that you could use C<given> as a scoped lexical
alias, i.e.

my $foo="foo";
my $bar="bar";

print $foo;

given $bar -> $foo {
print $foo;
}

print $foo;

#prints "foobarfoo"

Hmm...)

# signatureless sub: A sub that does not specify a prototype,
# and thus has a default prototype of:
#
# sub($_//=$_){};
#
# ne?

More like:

a sub that was created with the arrow (->) or a bare block and
does not specify a prototype, and thus has a default prototype
of:

-> ($_ //= $OUTER::_) { };

Or some such. (Maybe C<$_ //= $_> will work, but I have reservations
about that--especially about the possibility of that picking up $_
dynamically instead of lexically. In some cases you want $_
dynamically, in others lexically. Perhaps C<$_ is topic('lexical')> and
C<$_ is topic('dynamic')>?)

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

Wire telegraph is a kind of a very, very long cat. You pull his tail in
New York and his head is meowing in Los Angeles. And radio operates
exactly the same way. The only difference is that there is no cat.
--Albert Einstein (explaining radio)


Aaron Sherman

unread,
Sep 19, 2002, 4:21:53 PM9/19/02
to Luke Palmer, Perl6 Language List
On Sat, 2002-09-14 at 04:16, Luke Palmer wrote:

> When a bare closure is defined, it behaves the same as a signatureless
> sub. That is, it topicalizes the first argument, and hands them all over
> in @_. So your "topic passing" is just, well, passing the topic, like
> any ol' argument.

Ok, thanks. I was getting lost in the noise there, but this finally
makes sense.

Just to make 100% sure though, let me get these definitions clear:

topicalize: To default to C<$_> in a prototype (thus acquiring the
caller's current topic).

signatureless sub: A sub that does not specify a prototype, and thus has
a default prototype of:

sub($_//=$_){};

ne?

Larry Wall

unread,
Sep 20, 2002, 10:36:15 AM9/20/02
to Brent Dax, Aaron Sherman, Luke Palmer, Perl6 Language List
On Thu, 19 Sep 2002, Brent Dax wrote:
: Aaron Sherman:

: # topicalize: To default to C<$_> in a prototype (thus
: # acquiring the caller's current topic).
:
: Well, to topicalize a region of code is actually to specify a different
: topic, that is, a different value for $_. For example:
:
: $foo = new X;
: $bar = new Y;
:
: given $foo {
: print $_.type, "\n"; #prints "X"
:
: given $bar {
: #XXX we're using 'given' for this too, right?
: print $_.type, "\n"; #prints "Y"
: }
: }

Yes.

: (An aside: it strikes me that you could use C<given> as a scoped lexical


: alias, i.e.
:
: my $foo="foo";
: my $bar="bar";
:
: print $foo;
:
: given $bar -> $foo {
: print $foo;
: }
:
: print $foo;
:
: #prints "foobarfoo"
:
: Hmm...)

Sure, though it also aliases to $_.

: # signatureless sub: A sub that does not specify a prototype,

: # and thus has a default prototype of:
: #
: # sub($_//=$_){};
: #
: # ne?
:
: More like:
:
: a sub that was created with the arrow (->) or a bare block and
: does not specify a prototype, and thus has a default prototype
: of:
:
: -> ($_ //= $OUTER::_) { };

OUTER only works for lexical scopes. What you want is out-of-band access
to the $_ in the surrounding dynamic context

: Or some such. (Maybe C<$_ //= $_> will work, but I have reservations


: about that--especially about the possibility of that picking up $_
: dynamically instead of lexically. In some cases you want $_
: dynamically, in others lexically. Perhaps C<$_ is topic('lexical')> and
: C<$_ is topic('dynamic')>?)

The current thinking as of Zurich is that the "given" passes in
separate from the ordinary parameters:

sub ($a,$b,$c) is given($x) {...}

That binds the dynamically surrounding $_ to $x as an out-of-band
parameter. Can also bind to $_ to make it the current topic.

Not sure of the syntax for pointy subs yet. Maybe

-> ($a,$b,$c) is given($x) {...}

Larry

Aaron Sherman

unread,
Sep 20, 2002, 11:46:06 AM9/20/02
to Larry Wall, Perl6 Language List
On Fri, 2002-09-20 at 10:36, Larry Wall wrote:
> On Thu, 19 Sep 2002, Brent Dax wrote:

> : (An aside: it strikes me that you could use C<given> as a scoped lexical
> : alias, i.e.

> : given $bar -> $foo {
> : print $foo;
> : }

> Sure, though it also aliases to $_.
>

Does that mean that I can't

for $x -> $_ {
for $y -> $z {
print "$_, $z\n";
}
}

And expect to get different values?

> : # signatureless sub: A sub that does not specify a prototype,
> : # and thus has a default prototype of:
> : #
> : # sub($_//=$_){};
> : #
> : # ne?
> :
> : More like:
> :
> : a sub that was created with the arrow (->) or a bare block and
> : does not specify a prototype, and thus has a default prototype
> : of:
> :
> : -> ($_ //= $OUTER::_) { };
>
> OUTER only works for lexical scopes. What you want is out-of-band access
> to the $_ in the surrounding dynamic context
>

I assumed that's what C<//=$_> was. It does have the disadvantage of
looking like variable assignment, though.


> The current thinking as of Zurich is that the "given" passes in
> separate from the ordinary parameters:
>
> sub ($a,$b,$c) is given($x) {...}
>

Ok, that seems saner.

> That binds the dynamically surrounding $_ to $x as an out-of-band
> parameter. Can also bind to $_ to make it the current topic.
>
> Not sure of the syntax for pointy subs yet. Maybe
>
> -> ($a,$b,$c) is given($x) {...}

I was with you up until this last example. Can you give a surrounding
context so I can see how that would be used?

--
Aaron Sherman <a...@ajs.com>

Brent Dax

unread,
Sep 20, 2002, 10:58:44 AM9/20/02
to Larry Wall, Aaron Sherman, Luke Palmer, Perl6 Language List
Larry Wall:
# That binds the dynamically surrounding $_ to $x as an
# out-of-band parameter. Can also bind to $_ to make it the
# current topic.

The problem I have with that is this:

sub for_trace(*@array, &block) {
loop($_=0; $_ < @array; $_++) {
print "$_:\n";

{
my $coreprint=&CORE::print;
my $lastnl=1;

temp &CORE::print := sub ($fh: *@args) {
$fh.$coreprint("\t") if $lastnl;

$fh.$coreprint(@args);

$lastnl = @args[@args.last] =~
/\n $/;
}

block(@array[$_]);
}

print "\n"
}
}

$_="x";
@list=qw(y z);

for_trace @list -> $x {
print $_;
}

Which of these does this print?

0:
0
1:
1

0:
y
1:
z

0:
x
1:
x

The "correct" behavior (IMHO) is the third, though I could see the
second. But the first is unacceptable.

Larry Wall

unread,
Sep 20, 2002, 11:57:40 AM9/20/02
to Aaron Sherman, Perl6 Language List
On 20 Sep 2002, Aaron Sherman wrote:

: On Fri, 2002-09-20 at 10:36, Larry Wall wrote:
: > On Thu, 19 Sep 2002, Brent Dax wrote:
:
: > : (An aside: it strikes me that you could use C<given> as a scoped lexical
: > : alias, i.e.
: > : given $bar -> $foo {
: > : print $foo;
: > : }
:
: > Sure, though it also aliases to $_.
: >
:
: Does that mean that I can't
:
: for $x -> $_ {
: for $y -> $z {
: print "$_, $z\n";
: }
: }
:
: And expect to get different values?

That's correct. Name the outer topic explicitly, not the inner one.

: > : # signatureless sub: A sub that does not specify a prototype,

: > : # and thus has a default prototype of:
: > : #
: > : # sub($_//=$_){};
: > : #
: > : # ne?
: > :
: > : More like:
: > :
: > : a sub that was created with the arrow (->) or a bare block and
: > : does not specify a prototype, and thus has a default prototype
: > : of:
: > :
: > : -> ($_ //= $OUTER::_) { };
: >
: > OUTER only works for lexical scopes. What you want is out-of-band access
: > to the $_ in the surrounding dynamic context
: >
:
: I assumed that's what C<//=$_> was. It does have the disadvantage of
: looking like variable assignment, though.

I don't think we want to allow binding of defaults to variables of
the outer lexical scope. $_ is kind of special that way.

: > The current thinking as of Zurich is that the "given" passes in


: > separate from the ordinary parameters:
: >
: > sub ($a,$b,$c) is given($x) {...}
: >
:
: Ok, that seems saner.
:
: > That binds the dynamically surrounding $_ to $x as an out-of-band
: > parameter. Can also bind to $_ to make it the current topic.
: >
: > Not sure of the syntax for pointy subs yet. Maybe
: >
: > -> ($a,$b,$c) is given($x) {...}
:
: I was with you up until this last example. Can you give a surrounding
: context so I can see how that would be used?

Exactly the same as the previous example.

Larry

Larry Wall

unread,
Sep 20, 2002, 11:48:12 AM9/20/02
to Brent Dax, Aaron Sherman, Luke Palmer, Perl6 Language List
On Fri, 20 Sep 2002, Brent Dax wrote:
: Larry Wall:

The rule says the innermost topicalizer wins, and pointy sub always
topicalizes its first argument, so the second behavior is what happens.

The third behavior can always be forced with $OUTER::_. But it would
be better stylistically to name it something other than $_--which is
part of the reason we decided to make the topicalizers always alias
$_ in addition to whatever else they might alias. It's much better
to keep the pronouns referring to small-scale topics rather than
large scale.

Larry

Larry Wall

unread,
Sep 20, 2002, 12:01:55 PM9/20/02
to Aaron Sherman, Perl6 Language List
On 20 Sep 2002, Aaron Sherman wrote:
: I assumed that's what C<//=$_> was. It does have the disadvantage of

: looking like variable assignment, though.

BTW, latest leaning is toward = rather than //= for parameter defaults,
since it can, in fact, be undef if the parameter is supplied, while //=
seems to imply otherwise. And //= is too visually disruptive to the
signature.

Larry

Angel Faus

unread,
Sep 20, 2002, 4:15:10 PM9/20/02
to Larry Wall, Aaron Sherman, Perl6 Language List
Larry said:
> BTW, latest leaning is toward = rather than //= for parameter
> defaults, ...

Horray!

Sorry. Couldn't resist. :-)

-angel
"Simple men are happy with simple presents"

Sean O'Rourke

unread,
Sep 20, 2002, 12:17:48 PM9/20/02
to Larry Wall, Brent Dax, Aaron Sherman, Luke Palmer, Perl6 Language List
On Fri, 20 Sep 2002, Larry Wall wrote:
> The current thinking as of Zurich is that the "given" passes in
> separate from the ordinary parameters:
>
> sub ($a,$b,$c) is given($x) {...}
>
> That binds the dynamically surrounding $_ to $x as an out-of-band
> parameter. Can also bind to $_ to make it the current topic.

Does this mean that we allow/encourage uses of $_ other than as a default
for an optional argument? I think it would be less confusing and
error-prone to associate the underscore-aliasing with the parameter $_
will be replacing, i.e. this

sub foo($a, $b = given) { ... }

vs this

sub foo($a; $b) is given($b) { ... }

or this

sub foo($a; $b) is given($c) {
$b //= $c;
...
}

Furthermore, if the caller can pass undef for the second parameter, I
don't see a way to distinguish in the third variant between a legitimately
passed undef, for which we don't want $_, and a missing optional argument,
for which we do.

/s


Larry Wall

unread,
Sep 20, 2002, 12:33:09 PM9/20/02
to Sean O'Rourke, Brent Dax, Aaron Sherman, Luke Palmer, Perl6 Language List
On Fri, 20 Sep 2002, Sean O'Rourke wrote:

: On Fri, 20 Sep 2002, Larry Wall wrote:
: > The current thinking as of Zurich is that the "given" passes in
: > separate from the ordinary parameters:
: >
: > sub ($a,$b,$c) is given($x) {...}
: >
: > That binds the dynamically surrounding $_ to $x as an out-of-band
: > parameter. Can also bind to $_ to make it the current topic.
:
: Does this mean that we allow/encourage uses of $_ other than as a default
: for an optional argument? I think it would be less confusing and
: error-prone to associate the underscore-aliasing with the parameter $_
: will be replacing, i.e. this
:
: sub foo($a, $b = given) { ... }
:
: vs this
:
: sub foo($a; $b) is given($b) { ... }
:
: or this
:
: sub foo($a; $b) is given($c) {
: $b //= $c;
: ...
: }

We want to be able to write CORE::print, among other things.

: Furthermore, if the caller can pass undef for the second parameter, I


: don't see a way to distinguish in the third variant between a legitimately
: passed undef, for which we don't want $_, and a missing optional argument,
: for which we do.

You can check for that with exists.

We felt you could use exists to check a parameter for having been passed.

BTW, I may be out of touch for a week. Don't know if I'll have
Internet access where I'll be. YAPC::Europe is just going through
the final announcements as I type, so my current connection will go
away soon.

Larry

Adam D. Lopresto

unread,
Sep 20, 2002, 12:24:05 PM9/20/02
to Perl6 Language List
Personally, I like the looks of

sub foo($a, $b is given) { ... }

> Does this mean that we allow/encourage uses of $_ other than as a default
> for an optional argument? I think it would be less confusing and
> error-prone to associate the underscore-aliasing with the parameter $_
> will be replacing, i.e. this
>
> sub foo($a, $b = given) { ... }
>
> vs this
>
> sub foo($a; $b) is given($b) { ... }
>
> or this
>
> sub foo($a; $b) is given($c) {
> $b //= $c;
> ...
> }
>
> Furthermore, if the caller can pass undef for the second parameter, I
> don't see a way to distinguish in the third variant between a legitimately
> passed undef, for which we don't want $_, and a missing optional argument,
> for which we do.
>
> /s
>
>

--
Adam Lopresto (ad...@cec.wustl.edu)
http://cec.wustl.edu/~adam/

"It's times like these that I wish I was a leper" --Bob.

Smylers

unread,
Sep 21, 2002, 6:05:50 AM9/21/02
to perl6-l...@perl.org
Larry Wall wrote:

> On 20 Sep 2002, Aaron Sherman wrote:
>
> : Does that mean that I can't
> :
> : for $x -> $_ {
> : for $y -> $z {
> : print "$_, $z\n";
> : }
> : }
> :
> : And expect to get different values?
>
> That's correct. Name the outer topic explicitly, not the inner one.

That makes sense for nested C<for> loops: avoid confusion by always
having the 'unlabelled' entity being the thing being dealt with right
now.

Is it as helpful for file input? Many Perl programs use C<$_> to mean
'the current line'. 'A2' gives the Perl 6 syntax for this as:

while $STDIN {

That C<while> loop may be quite long. Maybe somewhere in the middle of
it, it's necessary to have a C<for> loop iterating over something else.
Or we want to switch on some state:

given $who
{
when $us { push %line{us}, $_ }
when $them { $num_them++ }
default { warn "$_\n" if $DEBUG }
}

I think it could surprise people if the variable holding 'the current
line' no longer holds that inside the C<for> or C<given>.

Having to alias C<$current_line> to C<$_> around inner loops and
switches is messy, and potentially confusing -- the same value now has
different names in different places.

Presumably something like this will be valid to use a different name for
the current line:

while defined my $line = $STDIN {

By C<$line> is just an ordinary variable in there, not a topic. So we
lose the benefits of being able to perform matches and substitutions
directly on the current line without having to name it or type the C<=~>
operator explicitly.

So I'm unconvinced that having an explicitly named topic always also
clobbering C<$_> is a good idea. But if it is, then we need a simple
syntax for reading file input lines into an explicitly named topic.

Smylers

Paul Johnson

unread,
Sep 21, 2002, 1:49:09 PM9/21/02
to Smylers, perl6-l...@perl.org
On Sat, Sep 21, 2002 at 10:05:50AM -0000, Smylers wrote:
> Larry Wall wrote:
>
> > On 20 Sep 2002, Aaron Sherman wrote:
> >
> > : Does that mean that I can't
> > :
> > : for $x -> $_ {
> > : for $y -> $z {
> > : print "$_, $z\n";
> > : }
> > : }
> > :
> > : And expect to get different values?
> >
> > That's correct. Name the outer topic explicitly, not the inner one.
>
> That makes sense for nested C<for> loops: avoid confusion by always
> having the 'unlabelled' entity being the thing being dealt with right
> now.
>
> Is it as helpful for file input? Many Perl programs use C<$_> to mean
> 'the current line'. 'A2' gives the Perl 6 syntax for this as:
>
> while $STDIN {
>
> That C<while> loop may be quite long. Maybe somewhere in the middle of
> it, it's necessary to have a C<for> loop iterating over something else.
> Or we want to switch on some state:
>
> given $who
> {
> when $us { push %line{us}, $_ }
> when $them { $num_them++ }
> default { warn "$_\n" if $DEBUG }
> }
>
> I think it could surprise people if the variable holding 'the current
> line' no longer holds that inside the C<for> or C<given>.

I don't see what is different from perl 5.

> Having to alias C<$current_line> to C<$_> around inner loops and
> switches is messy, and potentially confusing -- the same value now has
> different names in different places.
>
> Presumably something like this will be valid to use a different name for
> the current line:
>
> while defined my $line = $STDIN {

while $STDIN -> $line {

or

for $STDIN -> $line {

as the input should be read lazily.

> By C<$line> is just an ordinary variable in there, not a topic. So we
> lose the benefits of being able to perform matches and substitutions
> directly on the current line without having to name it or type the C<=~>
> operator explicitly.

As I wrote it $_ is the same as $line until some other construct claims
the $_.

I think that if your loop is so long that you are having trouble keeping
track of what $_ refers to then you probably need to explicitly name it
anyway, and maybe put some of the loop in a sub too.

> So I'm unconvinced that having an explicitly named topic always also
> clobbering C<$_> is a good idea. But if it is, then we need a simple
> syntax for reading file input lines into an explicitly named topic.

Allison Randall gave a really good talk on this at YAPC::Europe. I
think she gave it at YAPC::NA too.

--
Paul Johnson - pa...@pjcj.net
http://www.pjcj.net

Luke Palmer

unread,
Sep 21, 2002, 5:00:43 PM9/21/02
to Smylers, perl6-l...@perl.org
On 21 Sep 2002, Smylers wrote:

> Larry Wall wrote:
>
> > On 20 Sep 2002, Aaron Sherman wrote:
> >
> > : Does that mean that I can't
> > :
> > : for $x -> $_ {
> > : for $y -> $z {
> > : print "$_, $z\n";
> > : }
> > : }
> > :
> > : And expect to get different values?
> >
> > That's correct. Name the outer topic explicitly, not the inner one.
>

> Is it as helpful for file input? Many Perl programs use C<$_> to mean
> 'the current line'. 'A2' gives the Perl 6 syntax for this as:
>
> while $STDIN {
>
> That C<while> loop may be quite long. Maybe somewhere in the middle of
> it, it's necessary to have a C<for> loop iterating over something else.
> Or we want to switch on some state:
>
> given $who
> {
> when $us { push %line{us}, $_ }
> when $them { $num_them++ }
> default { warn "$_\n" if $DEBUG }
> }
>
> I think it could surprise people if the variable holding 'the current
> line' no longer holds that inside the C<for> or C<given>.
>
> Having to alias C<$current_line> to C<$_> around inner loops and
> switches is messy, and potentially confusing -- the same value now has
> different names in different places.

Well, no.

sub process;
for <> -> $line {
# both $line and $_ are the current line here
given process $line {
# $_ is process $line; $line is, well, $line
}
}

I don't think this is confusing. $_ is I<always> the current topic. If
you have a C<given>, you have a different topic. Like the Apocalypse
says, you alias the outer ones, not the inner ones.

I used C<for>, because C<while> doesn't topicalize.

> Presumably something like this will be valid to use a different name for
> the current line:
>
> while defined my $line = $STDIN {
>
> By C<$line> is just an ordinary variable in there, not a topic. So we
> lose the benefits of being able to perform matches and substitutions
> directly on the current line without having to name it or type the C<=~>
> operator explicitly.
>
> So I'm unconvinced that having an explicitly named topic always also
> clobbering C<$_> is a good idea. But if it is, then we need a simple
> syntax for reading file input lines into an explicitly named topic.
>
> Smylers
>

Luke

Smylers

unread,
Sep 29, 2002, 5:31:46 PM9/29/02
to perl6-l...@perl.org
Paul Johnson wrote:

> On Sat, Sep 21, 2002 at 10:05:50AM -0000, Smylers wrote:
>
> > Many Perl programs use C<$_> to mean
> > 'the current line'. 'A2' gives the Perl 6 syntax for this as:
> >
> > while $STDIN {
> >

> > Maybe somewhere in the middle of
> > it, it's necessary to have a C<for> loop iterating over something else.

> > ... I think it could surprise people if the variable holding 'the current


> > line' no longer holds that inside the C<for> or C<given>.
>
> I don't see what is different from perl 5.

Consider this Perl 5:

while (<>)
{
# ...
foreach my $fruit (qw<apple banana cherry>)
{
# ...
}
}

Inside the inner loop C<$_> still holds the current line. In the
equivalent Perl 6 syntax, insider the inner loop C<$_> will be an alias
of C<$fruit> and there wouldn't be any way of getting the current line.

> while $STDIN -> $line {
>
> or
>
> for $STDIN -> $line {
>
> as the input should be read lazily.
>

> As I wrote it $_ is the same as $line until some other construct claims
> the $_.

That solves the problem, since it answers the "But if it is" part of
this:

> > So I'm unconvinced that having an explicitly named topic always also
> > clobbering C<$_> is a good idea. But if it is, then we need a
> > simple syntax for reading file input lines into an explicitly named
> > topic.

Smylers

Paul Johnson

unread,
Sep 30, 2002, 2:22:40 PM9/30/02
to Smylers, perl6-l...@perl.org
On Sun, Sep 29, 2002 at 09:31:46PM -0000, Smylers wrote:

> Consider this Perl 5:
>
> while (<>)
> {
> # ...
> foreach my $fruit (qw<apple banana cherry>)
> {
> # ...
> }
> }
>
> Inside the inner loop C<$_> still holds the current line. In the
> equivalent Perl 6 syntax, insider the inner loop C<$_> will be an alias
> of C<$fruit> and there wouldn't be any way of getting the current line.

Well, there's always $OUTER::_ and $OUTER::OUTER::_ etc if you _really_
need them.

0 new messages