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

[], (), and potential design issues

16 views
Skip to first unread message

Dan Sugalski

unread,
Sep 24, 2002, 4:18:18 PM9/24/02
to perl6-l...@perl.org
Folks,

Larry is mostly out of touch this week, so working ourselves into a
fury over a potential design issue is probably a bit
counterproductive.

Perhaps someone can put together a statement of the problem and post
it, and we can leave the discussion for a bit, both to give larry
time to get his mail (probably not for a week) and to give everyone a
chance to mull over the issues?
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Luke Palmer

unread,
Sep 24, 2002, 6:09:41 PM9/24/02
to la...@wall.org, perl6-l...@perl.org
=head1 TITLE

Square brackets are the only list constructor

=head1 VERSION

Maintainer: Luke Palmer <fibo...@babylonia.flatirons.org>
Date: 24 Sep 2002
Number: 362 (?)
Version: 1

=head1 ABSTRACT

This RFC responds to the fury on perl6-language about the redundancy of
parentheses and brackets with respect to list construction. It proposes
that only brackets may be used to create lists (or arrays), and
parentheses be left for grouping.

=head1 DESCRIPTION

Because of the addition of the flattening operator, parentheses in Perl 6,
when used as list constructors, are entirely redundant with brackets.
Additionally, parentheses have one inconsistency which brackets do not:
This is the following case, already shown on perl6-language:

$a = (); # $a is a list reference with 0 elements
$a = (10); # $a is the scalar 10
$a = (10, 20); # $a is a list reference with 2 elements
# ...

If the ability to construct lists with parentheses is removed, so is this
inconsistency. This has the added benefit that there is a significant
visual clue about when a list is being tossed around. This doesn't break
any convenience, just changes the look of it:

# Perl 6 # Perl 5
[$a, $b] ^= [$b, $a]; # ($a, $b) = ($b, $a)
print *[$a=$b],"\n"; # print(($a=$b), "\n");
push @a: *[1,2,3]; # push @a, (1,2,3);
push @a: [1,2,3]; # push @a, [1,2,3];

=head2 Subroutines

One place of quarrel is subroutine calls. Would this change the argument
list delimiters to brackets? I argue no, because they were never a
parenthesis-delimited list in the first place:

print("Hello, World", "\n");
print "Hello, World", "\n";

Thus, in this case, parentheses are used for grouping around the argument
list, not constructing it. The following transformation has been
mentioned:

print($a, $b);

is equivilent to

(print $a, $b);

so no change is necessary on account of subroutine calls.

=head2 Semantics

The semantics of brackets need to be changed slightly to support this.
Specifically, instead of creating a list I<reference>, they create a list
I<object>. This object may be stored in an @array interface, or a $scalar
interface. The $scalar interface works the same way as array references
did. But the way @arrays are assigned changes in this manner:

@array = [1, 2, 3]; # @array has 3 elements, not 1
@array = [[1, 2, 3]]; # @array has 1 element: an array object
@array[0] = [1, 2, 3]; # same thing

Slices work as they always have.

=head2 Hashes

For consistency, parentheses must be disallowed for hash construction as
well. The same semantic changes apply to braces. This fixes the common
mistake:

%hash = { a => 1, b => 2 };

will now DWIM.

=head1 IMPLEMENTATION

Very simple: Just a few changes in the grammar. Array references were
always references to objects in one sense, it's now just defined that way
on the surface.

Janek Schleicher

unread,
Sep 25, 2002, 3:27:59 AM9/25/02
to perl6-l...@perl.org
Luke Palmer wrote at Wed, 25 Sep 2002 00:09:41 +0200:

Very good written text.

> =head1 DESCRIPTION
>
> Because of the addition of the flattening operator, parentheses in Perl 6,
> when used as list constructors, are entirely redundant with brackets.
> Additionally, parentheses have one inconsistency which brackets do not:
> This is the following case, already shown on perl6-language:
>
> $a = (); # $a is a list reference with 0 elements
> $a = (10); # $a is the scalar 10
> $a = (10, 20); # $a is a list reference with 2 elements
> # ...
>
> If the ability to construct lists with parentheses is removed, so is this
> inconsistency. This has the added benefit that there is a significant
> visual clue about when a list is being tossed around. This doesn't break
> any convenience, just changes the look of it:
>
> # Perl 6 # Perl 5
> [$a, $b] ^= [$b, $a]; # ($a, $b) = ($b, $a)
> print *[$a=$b],"\n"; # print(($a=$b), "\n");
> push @a: *[1,2,3]; # push @a, (1,2,3);
> push @a: [1,2,3]; # push @a, [1,2,3];

I didn't follow the Perl6 discussion very well,
so I have perhaps the advantage seeing all this with Perl5 eyes only.

Perhaps it's a good idea to add an explanation what is the most significant
benefit of this new notion. It's only said, that there is a significant

visual clue about when a list is being tossed around.

As I don't feel much that I don't know whether a variable is in list or scalar
context in Perl5, I'm asking whether there are some more (important) advantages.
Especially as there is an obviously disadvantage of the Perl6 syntax:
It's in all lines but the last one character longer :-))

As I'm sure that there is the chance of 1,2 or 3 short sentences explaining the
real advantages, I only wanted to ask for a completion of this nice text.


Greetings,
Janek

mosul...@crtinc.com

unread,
Sep 25, 2002, 8:41:41 AM9/25/02
to perl6-l...@perl.org
From: Luke Palmer fibo...@babylonia.flatirons.org
> [snip]

Luke, thanks and congratulations on a well written case. You put into
words exactly what I was trying to put into words myself. Now I don't have
to finish this ugly draft I have lying around.

-Miko

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


Larry Wall

unread,
Oct 5, 2002, 9:33:32 PM10/5/02
to Luke Palmer, perl6-l...@perl.org
On Tue, 24 Sep 2002, Luke Palmer wrote:
: =head1 TITLE

:
: Square brackets are the only list constructor
:
: =head1 VERSION
:
: Maintainer: Luke Palmer <fibo...@babylonia.flatirons.org>
: Date: 24 Sep 2002
: Number: 362 (?)
: Version: 1
:
: =head1 ABSTRACT
:
: This RFC responds to the fury on perl6-language about the redundancy of
: parentheses and brackets with respect to list construction. It proposes
: that only brackets may be used to create lists (or arrays), and
: parentheses be left for grouping.
:
: =head1 DESCRIPTION
:
: Because of the addition of the flattening operator, parentheses in Perl 6,
: when used as list constructors, are entirely redundant with brackets.

I cringe every time someone says "Parens construct lists in Perl 6."
Parens don't construct lists in Perl 6. They merely group. The only
difference from Perl 5 is that if they happen to group a comma in
scalar context, the comma acts differently, not the parens. But the
comma acts differently whether or not there are parens. It depends
only on the context. I admit that it's difficult to get a comma into
scalar context without parens, at least with the current precedence
table. But if we swapped the precedence of comma and assignment,
it would still be the case that

$a = 1,2,3;

generates a list because of the comma. The grouping would be implicit.
(But there are other problems with doing that.)

You can actually do the grouping without parens:

$foo = do { 1,2,3 };

Gee, maybe we should get rid of parens, since they're redundant. :-)

So the parens have little to do with the list construction. It's all
the comma's fault.

And in general, parentheses should not be used to construct lists in
scalar context. It's better to use [] explicitly. In list context,
the [] is not at all the same as (), because () is essentially a
no-op in list context, while [] creates an array ref.

I suppose we could make comma merely puke in scalar context rather
than DWIM, at least optionally.

: Additionally, parentheses have one inconsistency which brackets do not:


: This is the following case, already shown on perl6-language:
:
: $a = (); # $a is a list reference with 0 elements
: $a = (10); # $a is the scalar 10
: $a = (10, 20); # $a is a list reference with 2 elements
: # ...
:
: If the ability to construct lists with parentheses is removed, so is this
: inconsistency.

I don't think that's an important inconsistency.

: This has the added benefit that there is a significant
: visual clue about when a list is being tossed around. This doesn't break
: any convenience, just changes the look of it:
:
: # Perl 6 # Perl 5
: [$a, $b] ^= [$b, $a]; # ($a, $b) = ($b, $a)
: print *[$a=$b],"\n"; # print(($a=$b), "\n");
: push @a: *[1,2,3]; # push @a, (1,2,3);
: push @a: [1,2,3]; # push @a, [1,2,3];

I'd rather they just work the way people expect from Perl 5. Requiring
people to say *[1,2,3] when they could say 1,2,3 is needless obfuscation.

: =head2 Subroutines


:
: One place of quarrel is subroutine calls. Would this change the argument
: list delimiters to brackets? I argue no, because they were never a
: parenthesis-delimited list in the first place:
:
: print("Hello, World", "\n");
: print "Hello, World", "\n";
:
: Thus, in this case, parentheses are used for grouping around the argument
: list, not constructing it.

Indeed. :-)

: The following transformation has been

: mentioned:
:
: print($a, $b);
:
: is equivilent to
:
: (print $a, $b);
:
: so no change is necessary on account of subroutine calls.
:
: =head2 Semantics
:
: The semantics of brackets need to be changed slightly to support this.
: Specifically, instead of creating a list I<reference>, they create a list
: I<object>. This object may be stored in an @array interface, or a $scalar
: interface. The $scalar interface works the same way as array references
: did. But the way @arrays are assigned changes in this manner:
:
: @array = [1, 2, 3]; # @array has 3 elements, not 1
: @array = [[1, 2, 3]]; # @array has 1 element: an array object
: @array[0] = [1, 2, 3]; # same thing
:
: Slices work as they always have.

I think if you're going to replace the whole array using a reference, it's
better to use the explicit binding:

@array := [1,2,3]

It's awfully handy that the right side of a normal list assignment
automatically flattens. And it's what Perl 5 programmers expect.
They certainly won't expect [] to flatten.

: =head2 Hashes


:
: For consistency, parentheses must be disallowed for hash construction as
: well. The same semantic changes apply to braces. This fixes the common
: mistake:
:
: %hash = { a => 1, b => 2 };
:
: will now DWIM.

Well, that one can be caught, if not the other one. Again, the right
approach to dealing with references is probably to bind:

%hash := { a => 1, b => 2 };

Larry

Chip Salzenberg

unread,
Oct 5, 2002, 11:26:53 PM10/5/02
to Larry Wall, Luke Palmer, perl6-l...@perl.org
According to Larry Wall:

> I suppose we could make comma merely puke in scalar context rather
> than DWIM, at least optionally.

I rather like Perl 5's scalar comma operator.

> : $a = (); # $a is a list reference with 0 elements
> : $a = (10); # $a is the scalar 10
> : $a = (10, 20); # $a is a list reference with 2 elements
>

> I don't think that's an important inconsistency.

What if $a and $b are both array refs, and maintenance programmer
changes:
for $a, $b { print }
to:
for $a { print }
Will that end up iterating across @$a? The equivalent of that gotcha
was forever bugging me in Python (gack).
--
Chip Salzenberg - a.k.a. - <ch...@pobox.com>
"It furthers one to have somewhere to go."

Noah White

unread,
Oct 6, 2002, 1:08:32 AM10/6/02
to Larry Wall, Luke Palmer, perl6-l...@perl.org

On Saturday, October 5, 2002, at 09:33 PM, Larry Wall wrote:
>
>
> : Additionally, parentheses have one inconsistency which brackets do
> not:
> : This is the following case, already shown on perl6-language:
> :
> : $a = (); # $a is a list reference with 0 elements
> : $a = (10); # $a is the scalar 10
> : $a = (10, 20); # $a is a list reference with 2 elements
> : # ...
> :
> : If the ability to construct lists with parentheses is removed, so is
> this
> : inconsistency.
>
> I don't think that's an important inconsistency.

[SNIP]

>
> : This has the added benefit that there is a significant
> : visual clue about when a list is being tossed around. This doesn't
> break
> : any convenience, just changes the look of it:
> :
> : # Perl 6 # Perl 5
> : [$a, $b] ^= [$b, $a]; # ($a, $b) = ($b, $a)
> : print *[$a=$b],"\n"; # print(($a=$b), "\n");
> : push @a: *[1,2,3]; # push @a, (1,2,3);
> : push @a: [1,2,3]; # push @a, [1,2,3];
>
> I'd rather they just work the way people expect from Perl 5. Requiring
> people to say *[1,2,3] when they could say 1,2,3 is needless
> obfuscation.

I think needless obfuscation is treating $a = (10); as a scalar instead
of a list reference containing one item when the rest of the the $a =
() are list references.

-Noah

Brent Dax

unread,
Oct 6, 2002, 1:50:34 AM10/6/02
to Noah White, Larry Wall, Luke Palmer, perl6-l...@perl.org
Noah White:
# I think needless obfuscation is treating $a = (10); as a
# scalar instead
# of a list reference containing one item when the rest of the the $a =
# () are list references.

I think needless obfuscation is treating $a = (10) differently than $a =
10. The latter is the behavior we've come to expect from other
languages.

This may not look consistent:

$a = (10);
$a = (10, 20);
$a = (10, 20, 30);
#...

But it is consistent with this:

$a = do { 10 };
$a = do { 10, 20 };
$a = do { 10, 20, 30 };
#...

(Thanks for pointing that out, Larry.)

Parens don't construct lists EVER! They only group elements
syntactically. One common use of parens is to surround a
comma-separated list, but the *commas* are creating the list, *not* the
parens!

--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)

Luke Palmer

unread,
Oct 6, 2002, 1:14:50 AM10/6/02
to Larry Wall, perl6-l...@perl.org
Larry Wall wrote:
>
> [ Stuff about how commas construct lists, not parens ]
>

Wow, somehow you've convinced me that all the problems I saw before aren't
really there. Well, switch on the light, there's no monsters under the
bed afterall.

> : This has the added benefit that there is a significant
> : visual clue about when a list is being tossed around. This doesn't break
> : any convenience, just changes the look of it:
> :
> : # Perl 6 # Perl 5
> : [$a, $b] ^= [$b, $a]; # ($a, $b) = ($b, $a)
> : print *[$a=$b],"\n"; # print(($a=$b), "\n");
> : push @a: *[1,2,3]; # push @a, (1,2,3);
> : push @a: [1,2,3]; # push @a, [1,2,3];
>
> I'd rather they just work the way people expect from Perl 5. Requiring
> people to say *[1,2,3] when they could say 1,2,3 is needless obfuscation.

According to the RFC, they could say it either way. I suppose I should
have clarified that.

Well, fine, there goes my argument. I ended up happy, though.

Luke

Noah White

unread,
Oct 6, 2002, 1:56:22 AM10/6/02
to Brent Dax, Larry Wall, Luke Palmer, perl6-l...@perl.org

On Sunday, October 6, 2002, at 01:50 AM, Brent Dax wrote:

> Parens don't construct lists EVER! They only group elements
> syntactically. One common use of parens is to surround a
> comma-separated list, but the *commas* are creating the list, *not* the
> parens!
>

Following this rule would mean that

$a = (); # $a is a list reference with 0 elements

should not be a list reference at all and would appear inconsistent.

-Noah

Trey Harris

unread,
Oct 6, 2002, 3:28:47 AM10/6/02
to Noah White, Brent Dax, Larry Wall, Luke Palmer, perl6-l...@perl.org

No, because there are zero commas. Squint and you can see them. :-)

Trey

Smylers

unread,
Oct 6, 2002, 4:29:43 AM10/6/02
to perl6-l...@perl.org
Larry Wall wrote:

> Parens don't construct lists in Perl 6. They merely group.
> The only difference from Perl 5 is that if they happen to group a
> comma in scalar context, the comma acts differently, not the parens.

Do parens still provide list context on the left side of an assignment?
What do these two do:

my $x = @ARGS;
my ($y) = @ARGS;

Parens just grouping suggests that C<$x> and C<$y> should be the same
(which may well be good, as it's a subtle distinction which trips up
many beginners in Perl 5). If so, what's the preferred way of getting
the 'other' behaviour?

Smylers

Luke Palmer

unread,
Oct 6, 2002, 4:36:17 AM10/6/02
to Smylers, perl6-l...@perl.org
> Do parens still provide list context on the left side of an assignment?
> What do these two do:
>
> my $x = @ARGS;
> my ($y) = @ARGS;
>
> Parens just grouping suggests that C<$x> and C<$y> should be the same
> (which may well be good, as it's a subtle distinction which trips up
> many beginners in Perl 5). If so, what's the preferred way of getting
> the 'other' behaviour?

Maybe:?

my ($y) ^= @ARGS;

Luke

Smylers

unread,
Oct 6, 2002, 6:42:06 AM10/6/02
to perl6-l...@perl.org
Luke Palmer wrote:

> > my $x = @ARGS;
> > my ($y) = @ARGS;
>

> Maybe:?
>
> my ($y) ^= @ARGS;

Or (presumably equivalently):

my $y ^= @ARGS;

But that's horrible. Presumably with two or more variables the comma
would denote list context, so the caret is only needed for exactly one
variable. That's an awkward special-case to have to introduce.

Though thinking about this more, it may not be too much of a problem. A
main use of this in Perl 5 is with C<@_>. Since Perl 6 will have named
sub params this will be much less common and may not be something to
worry about.

Smylers

Glenn Linderman

unread,
Oct 6, 2002, 1:15:51 AM10/6/02
to Larry Wall, Luke Palmer, perl6-l...@perl.org
Larry Wall wrote:

>I cringe every time someone says "Parens construct lists in Perl 6."
>Parens don't construct lists in Perl 6.
>

>: Additionally, parentheses have one inconsistency which brackets do not:
>: This is the following case, already shown on perl6-language:
>:
>: $a = (); # $a is a list reference with 0 elements
>: $a = (10); # $a is the scalar 10
>: $a = (10, 20); # $a is a list reference with 2 elements
>: # ...
>:
>: If the ability to construct lists with parentheses is removed, so is this
>: inconsistency.
>
>I don't think that's an important inconsistency.
>
>

So is it even true that

$a = (); # is this really a list reference with 0 elements? Or is
this just undef? There is no comma...

--
Glenn
=====
Not everything that is counted counts,
and not everything that counts can be counted.
-- A. Einstein


John Williams

unread,
Oct 6, 2002, 1:21:10 PM10/6/02
to Luke Palmer, Smylers, perl6-l...@perl.org

That's like saying
$y = @ARGS[$_] for 0..+@ARGS;
so $y will probably end up with the _last_ element of @ARGS.

I suggest:

my $y = shift; # if this still works in perl6
my $y = @ARGS[0];

~ John Williams


Larry Wall

unread,
Oct 8, 2002, 8:10:05 PM10/8/02
to Smylers, perl6-l...@perl.org
On 6 Oct 2002, Smylers wrote:
: Do parens still provide list context on the left side of an assignment?

Er, kind of. More precisely, use of parens on the left provides a
flattening list context on the right side, just as in Perl 5. I guess
I did not make clear that a basic Perl 6 design decision was that = will
appear to work exactly as it does in Perl 5, while all the new semantics
get put into := instead. In fact, = doesn't work exactly the same, because
it lazily evaluates things like ranges and other potentially infinite lists.
But that should be more or less transparent.

Larry

Larry Wall

unread,
Oct 8, 2002, 8:30:41 PM10/8/02
to Chip Salzenberg, Luke Palmer, perl6-l...@perl.org
On Sat, 5 Oct 2002, Chip Salzenberg wrote:
: According to Larry Wall:

: > I suppose we could make comma merely puke in scalar context rather
: > than DWIM, at least optionally.
:
: I rather like Perl 5's scalar comma operator.

Most of the uses of which are actually in void context, where it
doesn't matter if we technically build a list and throw it away,
or throw away all but the last value, then throw that one away too.
Which is why it got decided the way it was. If you really want the
last value, you can always use

(LIST)[-1]

which could be construed as better documentation. Admittedly it's
not quite the same, since LIST is evaluated in list context.

Anyway, if we did outlaw comma in scalar context, it would not apply
to void context, or we couldn't write:

loop ($a=0, $b=1; $c; $a++, $b++) { ... }

: > : $a = (); # $a is a list reference with 0 elements


: > : $a = (10); # $a is the scalar 10
: > : $a = (10, 20); # $a is a list reference with 2 elements
: >
: > I don't think that's an important inconsistency.
:
: What if $a and $b are both array refs, and maintenance programmer
: changes:
: for $a, $b { print }
: to:
: for $a { print }
: Will that end up iterating across @$a? The equivalent of that gotcha
: was forever bugging me in Python (gack).

No, in list context reference scalars must still be explicitly
dereferenced. The $ on the front still means something occasionally.
It's only in scalar contexts that $ can be autodereffed as an array
now, so that someone can say

push $a, @list;

But if you say

push $a, $a;

you get the ref in $a pushed onto @$a, as it currently stands.

Larry

Larry Wall

unread,
Oct 8, 2002, 8:15:06 PM10/8/02
to Trey Harris, Noah White, Brent Dax, Luke Palmer, perl6-l...@perl.org

Actually, () has -1 commas, which is why it's not ambiguous. Rather,
it's ($x) that has zero commas, so it's naturally ambiguous, and thus
must depend on context to determine whether to produce a scalar or
a list value.

Seriously, () is just a special token. We could easily have used a
special token like NULLLIST instead. What does INTERCAL use?

Larry

Chip Salzenberg

unread,
Oct 8, 2002, 10:28:26 PM10/8/02
to Larry Wall, Luke Palmer, perl6-l...@perl.org
According to Larry Wall:

> On Sat, 5 Oct 2002, Chip Salzenberg wrote:
> : I rather like Perl 5's scalar comma operator.
>
> Most of the uses of which are actually in void context [...]

I didn't realize you were distinguishing scalar from void in this, uh,
context. I agree that scalar comma is expendable if void comma can be
rescued. However:

> ... where it doesn't matter if we technically build a list and throw


> it away, or throw away all but the last value, then throw that one
> away too.

Except that it would impose list context on the values; and if the
values to be thrown away are no longer in void context, unnecessary
work may be done to evaluate them fully. This is a bad thing.

(Or are you rescinding the rule that void context is a special kind of
scalar context?)

> If you really want the last value, you can always use
> (LIST)[-1]

If scalar comma goes away, I'd be inclined to replace it with

do { E1; E2; E3 }

which evaluates E1 and E2 in void context.

Mark J. Reed

unread,
Oct 9, 2002, 12:09:55 PM10/9/02
to Larry Wall, perl6-l...@perl.org
On 2002-10-08 at 17:15:06, Larry Wall wrote:
> Seriously, () is just a special token. We could easily have used a
> special token like NULLLIST instead. What does INTERCAL use?
Well, INTERCAL doesn't have lists per se, but it does have arrays, whose
size is set by assignment: the lvalue is the name of the entire array,
and the rvalue is the size. So if you wanted an empty array you'd set it
up with something like this:

PLEASE DO ;1 <- #0

(Hey, you asked.)

--
Mark REED | CNN Internet Technology
1 CNN Center Rm SW0831G | mark...@cnn.com
Atlanta, GA 30348 USA | +1 404 827 4754
--
It is not enough to have great qualities, we should also have the
management of them.
-- La Rochefoucauld

0 new messages