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

Comma Operator

7 views
Skip to first unread message

Joe Gottman

unread,
Jan 20, 2004, 9:17:32 PM1/20/04
to Perl6
About a month ago, a thread here suggested that we change the meaning of
the comma operator. Currently, in scalar context the expression
foo(), bar()
means "evaluate foo(), discard the result, then return the value of bar()".
It was suggested that this be changed to return the 2-element array (foo(),
bar()). Has Larry ruled on this yet?

By the way, even if we do make this change, I think that in void context
the expression
foo(), bar()
should still simply evaluate its parameters in order for their side-effects.
This would allow comma expressions to remain as-is in loop statements
(formerly for statements), which is where most of them are found anyway.
For instance
loop (my ($x = 0, $y = 10); $x < $y; ++$x, --$y) {...}

Joe Gottman


Jonathan Lang

unread,
Jan 20, 2004, 11:12:28 PM1/20/04
to Joe Gottman, Perl6
Joe Gottman wrote:
> About a month ago, a thread here suggested that we change the meaning
> of the comma operator. Currently, in scalar context the expression
> foo(), bar()
> means "evaluate foo(), discard the result, then return the value of
> bar()".
> It was suggested that this be changed to return the 2-element array
> (foo(), bar()). Has Larry ruled on this yet?

Not that I'm aware of. For the most part, the previous discussion was
focusing on what to replace the comma with in the case of "discard all but
the last result", and my impression was that any ruling on the change
would likely be contingent on the presence or absence of a suitable
replacement. That said,

> By the way, even if we do make this change, I think that in void
> context the expression
> foo(), bar()
> should still simply evaluate its parameters in order for their side-

> effects. This would allow comma expressions to remain as-is in loop

> statements (formerly for statements), which is where most of them are
> found anyway.

I do like this suggestion. In the majority of cases where I've used the
comma operator, I've either enclosed the whole thing in parentheses to
turn it into a list, or I've treated it as a sequence of operators where
even the last result got discarded. I've rarely been interested in just
the last result, and I wouldn't mind that functionality being provided by
means of a C<last> function which evaluates the list parameters for their
side effects and returns the value of the last list parameter.

=====
Jonathan "Dataweaver" Lang

__________________________________
Do you Yahoo!?
Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
http://hotjobs.sweepstakes.yahoo.com/signingbonus

Larry Wall

unread,
Jan 21, 2004, 2:51:28 PM1/21/04
to Perl6
On Tue, Jan 20, 2004 at 08:12:28PM -0800, Jonathan Lang wrote:
: Joe Gottman wrote:
: > About a month ago, a thread here suggested that we change the meaning
: > of the comma operator. Currently, in scalar context the expression
: > foo(), bar()
: > means "evaluate foo(), discard the result, then return the value of
: > bar()".
: > It was suggested that this be changed to return the 2-element array
: > (foo(), bar()). Has Larry ruled on this yet?
:
: Not that I'm aware of. For the most part, the previous discussion was
: focusing on what to replace the comma with in the case of "discard all but
: the last result", and my impression was that any ruling on the change
: would likely be contingent on the presence or absence of a suitable
: replacement.

I'm a little frustrated because I feel like I've ruled on it several
times, but it never seems to "stick". I guess that's because it was
never ruled in an Apocalypse, just in email. But I'm sure I'm on
the record somewhere saying that I think [-1] is sufficient to pick
out the last element of a list. If nothing else, just a couple of
days ago, but I'm sure I also said it more than once in ancient times.

: That said,

:
: > By the way, even if we do make this change, I think that in void
: > context the expression
: > foo(), bar()
: > should still simply evaluate its parameters in order for their side-
: > effects. This would allow comma expressions to remain as-is in loop
: > statements (formerly for statements), which is where most of them are
: > found anyway.
:
: I do like this suggestion. In the majority of cases where I've used the
: comma operator, I've either enclosed the whole thing in parentheses to
: turn it into a list, or I've treated it as a sequence of operators where
: even the last result got discarded. I've rarely been interested in just
: the last result, and I wouldn't mind that functionality being provided by
: means of a C<last> function which evaluates the list parameters for their
: side effects and returns the value of the last list parameter.

Well, a C<last> function (or method) would be redundant with [-1], though
I'm not totally opposed to redundancy. ["You can say that again."]

Larry

Joe Gottman

unread,
Jan 21, 2004, 8:51:33 PM1/21/04
to Perl6

Great, so
$x = foo(), bar();
means the same thing as
$x = ( foo(), bar() );

Is the optimizer going to be smart enough so that given the expression
$x = (foo(), bar(), glarch())[-1];

Perl6 won't have to construct a three-element array just to return the last
element?

Joe Gottman


Larry Wall

unread,
Jan 22, 2004, 1:30:16 PM1/22/04
to Perl6
On Wed, Jan 21, 2004 at 08:51:33PM -0500, Joe Gottman wrote:
: Great, so

: $x = foo(), bar();
: means the same thing as
: $x = ( foo(), bar() );

No, we haven't changed the relative precedence of assignment and comma.
I've been tempted to, but I always come back to liking the parens
for visual psychological purposes. Plus changing the precedence
would break

loop $i = 0, $j = 0; $x[$i,$j]; $i++, $j++ { ... }

: Is the optimizer going to be smart enough so that given the expression


: $x = (foo(), bar(), glarch())[-1];
:
: Perl6 won't have to construct a three-element array just to return the last
: element?

It's interesting to me that you assume there would be a three element
array there. If the ()[] works like it does in Perl 5, the stuff inside
the parens is always evaluated in list context. Which means that foo(),
bar(), and glarch() can any of them return 0 or more elements. There's
no guarantee that the final value doesn't come from foo() or bar().

Now, in Perl 6, slices are distinguished from single subscripts only by
the form of the subscript, not by any sigil. So we can know for a fact
that [-1] is not a slice. But that doesn't mean we can necessarily
assume that the list in parens wants to evaluate its args in scalar
context. Maybe it does, and maybe it doesn't.

That doesn't mean that we have to put the C comma operator back
in though. It might just mean that the default is wrong on ()[].
Suppose we say that

(foo(), bar(), glarch())[-1]

by default evaluates its arguments in scalar context. To get the Perl 5
behavior, you'd merely have to use a splat to put the list into list
context:

(* foo(), bar(), glarch())[-1]

Then (...)[] would become the standard way of producing a list of
things evaluated in scalar context. Alternately, if you don't like
the splat list, you can always say

[foo(), bar(), glarch()][-1]

which does the same thing.

Given all that, I think we can say that, yes, the compiler can
optimize foo() and bar() to know they're running in void context.
I'd generalize that to say that any unselected element of a scalar
list can be evaluated in a void context, whether the subscript is -1
or 0 or any constant slice.

Larry

TSa Thomas Sandla?

unread,
Jan 26, 2004, 4:38:05 PM1/26/04
to
la...@wall.org (Larry Wall) wrote in message news:<20040122183...@wall.org>...

>
> No, we haven't changed the relative precedence of assignment and comma.
> I've been tempted to, but I always come back to liking the parens
> for visual psychological purposes.

Why does the psychology not apply to junctions?
We have:

$junc = 1 | 2 | 3;

but not:

@list = 1 , 2 , 3;


> Plus changing the precedence
> would break
>
> loop $i = 0, $j = 0; $x[$i,$j]; $i++, $j++ { ... }

How about letting the Comma Operator share the transformation
of the Ternary? Thus using ',' as the list constructor with
apropriate precedence and ',,' as C-comma:

loop $i = 0 ,, $j = 0; $x[$i,$j]; $i++ ,, $j++ { ... }

TSa.

Smylers

unread,
Feb 8, 2004, 12:45:59 PM2/8/04
to perl6-l...@perl.org
Larry Wall writes:

> On Wed, Jan 21, 2004 at 08:51:33PM -0500, Joe Gottman wrote:
>
> : Great, so
> : $x = foo(), bar();
> : means the same thing as
> : $x = ( foo(), bar() );
>
> No, we haven't changed the relative precedence of assignment and
> comma. I've been tempted to, but I always come back to liking the
> parens for visual psychological purposes.

But that does lead to propagating the myth that parens, rather than
commas, denote lists.

> Plus changing the precedence would break
>
> loop $i = 0, $j = 0; $x[$i,$j]; $i++, $j++ { ... }

I think that matters less -- assigning lists is a much more common
operation that using a C-style C<for> loop, and is also something that's
a common source of errors with beginning Perl 5 programmers. Most of
the C-style C<for> loops I see are unnecessary anyway:

* The majority of them are iterating through array indices (which are
then only used to look up elements in those arrays), something far
more easily achived with a C<foreach> loop and letting Perl take
care of the indices.

* Many of the remainder are still iterating through consecutive
integers, where C<for my $i (1 .. 10)> or whatever would much tidier
than checking the boundary and increasing the iterator manually.

* Even for situations which 'genuinely' need the C-style loop in Perl
5 (such as looping through items in an array but also having the
index number available) many of those in Perl 6 can use C<zip>.

So I think it's odd to optimize for convenience of a construct that has
so little use.

Especially when there are ways of writing that statement without any
commas in it:

loop $i = $j = 0; $x[$i,$j]; do { $i++; $j++ } { ... }

While on the topic of C<loop> and parens, it hadn't occurred to me that
the former could now be written without the latter; I knew that C<for>,
C<if>, and C<while> could be, and now I look at it I can see that
C<loop> can be so-written unambiguously -- but having 'internal',
unbracketed, unquoted, unprotected semicolons scares me a little.

I'd feel more at ease if on seeing something like:

loop $i = $j = 0;

I could be certain that that semicolon denoted the end of that
statement, without my having to know what C<loop> does.

Again, given how infrequently C<loop> is likely to be used, would
imposing such a rule be much of a hardship? So a loop could look
something like:

loop($i = $j = 0; $x[$i,$j]; do { $i++; $j++ }) { ... }

and it's blindingly obvious that the first semicolon couldn't possibly
be the end of the statement.

Smylers

0 new messages