# (1)[0] ok but not 1[0]

Discussion in 'Perl Misc' started by Florian Kaufmann, Dec 12, 2007.

1. ### Florian KaufmannGuest

Hello

I am still after the answer to the old question whats the difference
between an array and a list. Yes, I read the faq, and I am reading
Programming Perl.

In my current understanding, the array subscript operator [] forces
its left operand to be an array. Thus, if that left operand is a list,
that list is converted to an array. Thus things like
\$x = (1,2,3)[0];
\$x = (3)[0];

work. But then again, why shoudn't that work?
\$x = 3[0];

I thought it's the operator , which composes/constructs a list, not
parantheses. Parantheses are in this discussion only used for
overwriting precedence. Eg this works to create an array with just one
element
@a = 3;

I don't have to write
@a = (3);

Thus a literal scalar like 3 in 'array context' (imposed by the array
subscript operator []) is just a list with one element, just as (3)
[0]. Thats why I expect 3[0] to work.

Greetings

Flo

Florian Kaufmann, Dec 12, 2007

2. ### Michele DondiGuest

On Wed, 12 Dec 2007 01:55:23 -0800 (PST), Florian Kaufmann
<> wrote:

>I am still after the answer to the old question whats the difference
>between an array and a list. Yes, I read the faq, and I am reading
>Programming Perl.

Basically, an array is a thing that has a name (yes, even when it's
anonymous!) into which a list can be stored, and out of which a list
can be extracted.

>In my current understanding, the array subscript operator [] forces
>its left operand to be an array. Thus, if that left operand is a list,

Your current understanding is wrong.

>that list is converted to an array. Thus things like

False. Since an array and a list are much similar, you can have array
and list subscripting (and slicing) which work in a quite similar way.

>\$x = (1,2,3)[0];
>\$x = (3)[0];
>
>work. But then again, why shoudn't that work?
>\$x = 3[0];

Because 3 is not a list.

>I thought it's the operator , which composes/constructs a list, not
>parantheses. Parantheses are in this discussion only used for
>overwriting precedence. Eg this works to create an array with just one
>element
>@a = 3;

But assignment to an array creates list context.

>I don't have to write
>@a = (3);

That's a special case. You'll find that

C:\temp>perl -le "@a=3,5;@b=(3,5);print qq(@a|@b)"
3|3 5

Michele
--
{\$_=pack'B8'x25,unpack'A8'x32,\$a^=sub{pop^pop}->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

Michele Dondi, Dec 12, 2007

3. ### Dr.RuudGuest

Florian Kaufmann schreef:

> I am still after the answer to the old question whats the difference
> between an array and a list.

An array is a variable.

--
Affijn, Ruud

"Gewoon is een tijger."

Dr.Ruud, Dec 12, 2007
4. ### Florian KaufmannGuest

> False. Since an array and a list are much similar, you can have array
> and list subscripting (and slicing) which work in a quite similar way.
> ....
> >But then again, why shoudn't that work?
> >\$x = 3[0];

>
> Because 3 is not a list.

So then, why does the following work?
\$x = (3)[0].

Where is a rule that states that parentheses make the difference?
Here, parentheses are only for grouping I thought. To create lists,
one has to use the operator ',' , not parentheses.

Flo

Florian Kaufmann, Dec 12, 2007
5. ### Florian KaufmannGuest

Perldoc says that "List values are denoted by separating individual
values by commas (and enclosing the list in parentheses where
precedence requires it):". To repeat the point, parentheses are not
required to create/specify lists.

The following two are equivalent
print 1,2,3;
print (1,2,3);

Thus the following two should be equivalent too in my view
\$x = 3[0];
\$x = (3)[0];

Flo

Florian Kaufmann, Dec 12, 2007
6. ### John W. KrahnGuest

Florian Kaufmann wrote:
>
> > False. Since an array and a list are much similar, you can have array
> > and list subscripting (and slicing) which work in a quite similar way.
> > ....
> > >But then again, why shoudn't that work?
> > >\$x = 3[0];

> >
> > Because 3 is not a list.

>
> So then, why does the following work?
> \$x = (3)[0].
>
> Where is a rule that states that parentheses make the difference?
> Here, parentheses are only for grouping I thought. To create lists,
> one has to use the operator ',' , not parentheses.

Who said that you needed ',' or parentheses?

\$ perl -le'print qw/a b c d e f/[3]'
d

John
--
use Perl;
program
fulfillment

John W. Krahn, Dec 12, 2007
7. ### Ben MorrowGuest

Quoth Florian Kaufmann <>:
>
> I am still after the answer to the old question whats the difference
> between an array and a list. Yes, I read the faq, and I am reading
> Programming Perl.

An array is a variable, a list is a value. That is, the contents of an
array can be modified (by assigning to a subscript, or with push, pop,
splice &c.) whereas the contents of a list cannot. All you can do is
build a *new* list based on the old one, say with map or grep. A list
also has no 'life' beyond the end of the expression it is part of: it
must be assigned into an array or it will be garbage-collected.
(Exception: the list passed to 'return' exists past the sub return and
into the expression that made the call.)

> In my current understanding, the array subscript operator [] forces
> its left operand to be an array.

No, this is incorrect. There are three different operators in Perl
spelled []: array subscript, array slice, and list slice.

\$ary[0] array subscript
\$aref->[0] also array subscript
@ary[0] array slice
(LIST)[0] list slice

For the 'list slice' form, the parens are part of the syntax, so @ary[0]
and (@ary)[0] are quite different expressions.

> Thus, if that left operand is a list,
> that list is converted to an array. Thus things like
> \$x = (1,2,3)[0];
> \$x = (3)[0];
>
> work.

No. Otherwise exists( (1,2)[0] ) would work, which it doesn't.

> But then again, why shoudn't that work?
> \$x = 3[0];

This is none of the forms above, so it is a syntax error.

> I thought it's the operator , which composes/constructs a list, not
> parantheses.

The comma only composes a list in list context. The inside of the parens
in the ()[] list slice operator are in list context, so you will get a
list to slice.

> Thus a literal scalar like 3 in 'array context' (imposed by the array
> subscript operator []) is just a list with one element, just as (3)
> [0]. Thats why I expect 3[0] to work.

There is no 'array context', at least, not in Perl 5. 3[0] is a syntax
error, so there are no contexts at all ; in (3)[0] the ()[] operator
does indeed provide list context to the 3.

I hope this helps you understand it: it *is* rather confusing .

Ben

Ben Morrow, Dec 12, 2007
8. ### Ben MorrowGuest

Quoth Michele Dondi <>:
> On Wed, 12 Dec 2007 01:55:23 -0800 (PST), Florian Kaufmann
> <> wrote:
>
> >I am still after the answer to the old question whats the difference
> >between an array and a list. Yes, I read the faq, and I am reading
> >Programming Perl.

>
> Basically, an array is a thing that has a name (yes, even when it's
> anonymous!) into which a list can be stored, and out of which a list
> can be extracted.

You can do much more to an array than just store and extract lists.
splice, for instance, doesn't work on lists.

> >\$x = (3)[0];
> >
> >work. But then again, why shoudn't that work?
> >\$x = 3[0];

>
> Because 3 is not a list.

Well... it can be. In (3)[0], the 3 is in list context, so it *is* (part
of) a list. The important point is that the parens are an integral part
of the list slice operator.

> >I don't have to write
> >@a = (3);

>
> That's a special case. You'll find that
>
> C:\temp>perl -le "@a=3,5;@b=(3,5);print qq(@a|@b)"
> 3|3 5

It's not a special case. Here the parens *are* just for precedence: =
binds more tightly than comma, so @a=3,5 evaluates as (@a=3),5 . If you
had @a = foo, then foo would be called in list context despite the lack
of parens.

Ben

Ben Morrow, Dec 12, 2007
9. ### Ben MorrowGuest

Quoth "John W. Krahn" <>:
> Florian Kaufmann wrote:
> >
> > Where is a rule that states that parentheses make the difference?
> > Here, parentheses are only for grouping I thought. To create lists,
> > one has to use the operator ',' , not parentheses.

>
> Who said that you needed ',' or parentheses?
>
> \$ perl -le'print qw/a b c d e f/[3]'
> d

Now that *is* a special case . qw// pretends it has parens around it
(look for KEY_qw in toke.c: it actually inserts paren tokens into the
token stream) so that @a = qw/a b/ doesn't need extra parens. Of course,
it doesn't pretend hard enough to invoke the 'looks like a function'
rule...

Ben

Ben Morrow, Dec 12, 2007
10. ### Michele DondiGuest

On Wed, 12 Dec 2007 05:05:26 -0800 (PST), Florian Kaufmann
<> wrote:

>> Because 3 is not a list.

>
>So then, why does the following work?
>\$x = (3)[0].

Because (3) is a list.
>
>Where is a rule that states that parentheses make the difference?
>Here, parentheses are only for grouping I thought. To create lists,
>one has to use the operator ',' , not parentheses.

Yep, the comma *does* create lists, in list context. In scalar
context, it does something entirely different.

Michele
--
{\$_=pack'B8'x25,unpack'A8'x32,\$a^=sub{pop^pop}->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

Michele Dondi, Dec 12, 2007
11. ### Michele DondiGuest

On Wed, 12 Dec 2007 05:28:47 -0800 (PST), Florian Kaufmann
<> wrote:

>Perldoc says that "List values are denoted by separating individual
>values by commas (and enclosing the list in parentheses where
>precedence requires it):". To repeat the point, parentheses are not
>required to create/specify lists.

In fact, \$x= ... binds stricter. Thus parens *are* required.

>The following two are equivalent
>print 1,2,3;
>print (1,2,3);

This is an entirely different matter: the parens around the arguments
for print are the optional ones of the print() function. Thus

argon:~ [16:45:30]\$ perl -le 'print 1,(2,3)'
123
argon:~ [16:45:49]\$ perl -le 'print (2,3),4'
23
argon:~ [16:45:56]\$ perl -le 'print((2,3),4)'
234
argon:~ [16:46:03]\$ perl -le 'print +(2,3),4'
234

Michele
--
{\$_=pack'B8'x25,unpack'A8'x32,\$a^=sub{pop^pop}->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

Michele Dondi, Dec 12, 2007
12. ### Michele DondiGuest

On Wed, 12 Dec 2007 14:39:53 +0000, Ben Morrow <>
wrote:

>> C:\temp>perl -le "@a=3,5;@b=(3,5);print qq(@a|@b)"
>> 3|3 5

>
>It's not a special case. Here the parens *are* just for precedence: =
>binds more tightly than comma, so @a=3,5 evaluates as (@a=3),5 . If you
>had @a = foo, then foo would be called in list context despite the lack
>of parens.

Sorry for the misinformation. A braino on my part.

Michele
--
{\$_=pack'B8'x25,unpack'A8'x32,\$a^=sub{pop^pop}->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

Michele Dondi, Dec 12, 2007
13. ### Ben MorrowGuest

Quoth Ben Morrow <>:
>
> No, this is incorrect. There are three different operators in Perl
> spelled []: array subscript, array slice, and list slice.

There is a fourth, of course: the anon array constructor. Duh.

Ben

Ben Morrow, Dec 12, 2007
14. ### Florian KaufmannGuest

> I hope this helps you understand it: it *is* rather confusing .

Yes, wonderful. Thats what I wrote down for myself to summarize, after
I read all your answers and made some tests:

1) \$arraypseudoref[scalarcontext] array subscript
2) @arraypseudoref[listcontext] array slice
3) (listcontext)[listcontext] list slice

arraypseudoref = Something that refers to an array. E.g.
-) an array identifier: my_array
-) a reference to an array (possibly anonymous): \$ref_to_array and
{[1,2]} respectively
The braces are needed. [1,2] or ([1,2]) don't work.

I think I have now have described for me any array/list slices/
subscripts whatsoever that are possible in Perl.

What I know obviously have to read about more is what the correct
names/terms are, and how to better describe/specify them. I wonder how
"Programming Perl" calls what I have called arraypseudoref, and how it
is specified exactly.

Thank you

Flo

Just if anybody also wants to play with subscript/slice operators -
with the following script I tried to clarify things.

#! /bin/perl -w

sub foo { wantarray ? (print ("y"),(0,1)) : (print ("n"),2) }
sub bar { @a }

@a = (1..100);

foo();
print "\n";

print "-- 1 --------------\n";
\${[1..100]}[foo()];
print "\n";
\${[1..100]}[foo(),foo()];
print "\n";
@{[1..100]}[foo()];
print "\n";
@{[1..100]}[foo(),foo()];
print "\n";

print "-- 2 --------------\n";
(bar())[foo()];
print "\n";
(bar())[foo(),foo()];
print "\n";

print "-- 3 --------------\n";
\$s = \$a[foo()];
print "\n";
\$s = \$a[foo(),foo()];
print "\n";
\$s = @a[foo()];
print "\n";
\$s = @a[foo(),foo()];
print "\n";
\$s = (1..100)[foo()];
print "\n";
\$s = (1..100)[foo(),foo()];
print "\n";

print "-- 4 --------------\n";
@a2 = \$a[foo()];
print "\n";
@a2 = \$a[foo(),foo()];
print "\n";
@a2 = @a[foo()];
print "\n";
@a2 = @a[foo(),foo()];
print "\n";
@a2 = (1..100)[foo()];
print "\n";
@a2 = (1..100)[foo(),foo()];
print "\n";

Florian Kaufmann, Dec 12, 2007
15. ### Ilya ZakharevichGuest

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Michele Dondi
<>], who wrote in article <>:
> >\$x = (3)[0];

> >work. But then again, why shoudn't that work?
> >\$x = 3[0];

> Because 3 is not a list.

Nonsense. Of course, 3 is a list.

Hope this helps,
Ilya

Ilya Zakharevich, Dec 12, 2007
16. ### Ilya ZakharevichGuest

[A complimentary Cc of this posting was sent to
Florian Kaufmann
<>], who wrote in article <>:
> Perldoc says that "List values are denoted by separating individual
> values by commas (and enclosing the list in parentheses where
> precedence requires it):". To repeat the point, parentheses are not
> required to create/specify lists.

Correct.

> Thus the following two should be equivalent too in my view
> \$x = 3[0];
> \$x = (3)[0];

This is not so straightforward. `[0]' is not a "pure operator"; it is
a "special syntax". When you write \$a[0], it is not equivalent to
(\$a)[0], right? The latter IS an operator; the former is a syntaxic
sugar for aelt_scalar(\@a, 0).

I THINK that the parser tries to handle 3[0] the same as \$3[0], and
the "syntax error" tries to tell you something like that `3' is not a
valid array name.

So there ARE several situations where parentheses mean more than "just
precedence". IMO, it is an indication of the sad state of affair with
Perl documentation that there is no place in perl docs which lists all
of them...

Hope this helps,
Ilya

Ilya Zakharevich, Dec 12, 2007
17. ### Michele DondiGuest

On Wed, 12 Dec 2007 19:50:08 +0000 (UTC), Ilya Zakharevich
<> wrote:

>So there ARE several situations where parentheses mean more than "just
>precedence". IMO, it is an indication of the sad state of affair with
>Perl documentation that there is no place in perl docs which lists all
>of them...

Anyway, while the OP is confused by the fact e.g. 3[0] doesn't do what
he thinks it should, the current syntax for the wanted semantics seems
intuitive and dwimmy to me. I, for one, would find 3[0] to be
syntactically valid and semantically valid, to imply that 3 is an
autoboxed object (which in Perl 5 generally isn't unless using the
autobox module) and doing the role of an array. Perhaps this would
have some sense if the semantics were that [0..2](0), but then it
would be very inconsistent with \$n[0] being the first element of @n.
If sigils were invariant as they are in Perl 6, then this
inconsistency would not exist, but there wouldn't be much need to give
3[0] a meaning, either.

Michele
--
{\$_=pack'B8'x25,unpack'A8'x32,\$a^=sub{pop^pop}->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

Michele Dondi, Dec 12, 2007
18. ### Florian KaufmannGuest

> precedence". IMO, it is an indication of the sad state of affair with
> Perl documentation that there is no place in perl docs which lists all
> of them...

Thats what I think too, although I wouldn't go as far as to label it
sad. I would like to have a book for Perl what the book "The C++
Programming Language" is for C++. Something very clear, very concise,
clearly naming things and give things clear semantics. "Programming
Perl" is a good book, but in my opinion by far not as concise as "The C
++ Programming Language". To be fair I am a Perl novice, and it might
be to early to make such a statement.

I am writing a documentation for Perl for myself. I hope it turns out
more concise, at least in my view, as the documentation about Perl I
have currently in my hands. I am writing it to learn Perl, to order my
thoughts, my understanding of Perl. It has a lot of positive side
effects though
- I learn Perl pretty well
- I learn LaTeX a bit (i decided to write the document in latex)
- I learn how to efficiently edit LaTex files in Emacs
- I learn more about meta syntax notations. I am using an own syntax
notation which I created on this occasion (also to describe bash
scripts), since I find EBNF and the like quite cumbersome. It's more
for the fun of it, to have something I personally like better, not to
have something which is better by objective means.

Flo

Florian Kaufmann, Dec 12, 2007
19. ### Ben MorrowGuest

Quoth Michele Dondi <>:
> On Wed, 12 Dec 2007 19:50:08 +0000 (UTC), Ilya Zakharevich
> <> wrote:
>
> >So there ARE several situations where parentheses mean more than "just
> >precedence". IMO, it is an indication of the sad state of affair with
> >Perl documentation that there is no place in perl docs which lists all
> >of them...

>
> Anyway, while the OP is confused by the fact e.g. 3[0] doesn't do what
> he thinks it should, the current syntax for the wanted semantics seems
> intuitive and dwimmy to me. I, for one, would find 3[0] to be
> syntactically valid and semantically valid, to imply that 3 is an
> autoboxed object (which in Perl 5 generally isn't unless using the
> autobox module) and doing the role of an array.

This isn't possible within the syntax and semantics of Perl 5, as you'd
lose the distinction between \$ary[0] and @ary[0], which is vital to get
the proper RHS context in assignments.

> Perhaps this would have some sense if the semantics were that
> [0..2](0),

Huh? Perl never uses () for subscripting... did you mean (0..2)[0] ?
Still doesn't make a lot of sense...

> but then it
> would be very inconsistent with \$n[0] being the first element of @n.
> If sigils were invariant as they are in Perl 6, then this
> inconsistency would not exist, but there wouldn't be much need to give
> 3[0] a meaning, either.

IIUC 3[0] is valid Perl 6, and means 3.[0], which may or may not make
sense depending on what object '3' evaluates to... but it's possible I'm
wrong, as I haven't tried using Perl 6 in anger yet.

Ben

Ben Morrow, Dec 12, 2007
20. ### Joost DiepenmaatGuest

On Wed, 12 Dec 2007 13:38:24 -0800, Florian Kaufmann wrote:

[...]

> I would like to have a book for Perl what the book "The C++
> Programming Language" is for C++. Something very clear, very concise,
> clearly naming things and give things clear semantics. "Programming
> Perl" is a good book, but in my opinion by far not as concise as "The C
> ++ Programming Language". To be fair I am a Perl novice, and it might be
> to early to make such a statement.

Well, I'm not much of a C++ programmer, but I've read the Soustrup book,
and you're right that "Programming perl" isn't as concise (TCPPPL is very
terse, and it's got about the same number of pages as PP with a much
smaller font). But IMO, the PP book is much easier to read, understand,
and useful to get a grip on the language even if it leaves some of the
details unspecified. I wouldn't recommend someone'd try to learn C++ from
TCPPPL, but I do recomment PP for perl newbies.

On the other hand, a really *complete* reference book for perl may fill a
need.

Currently though, I would have to say that the best way to really lean
perl is to read the PP book (which is IMO the best book to learn perl),
read the man pages and write a lot of code/experiment to find out the
details you're missing. PP gives you a very good idea of the mind-set of
the perl, plus a good overview of all that's in it, but it's not a
complete reference manual for the language and in some places perl's man
pages are more complete and/or up to date than PP, though even the man
pages fall short of being complete.

> I am writing a documentation for Perl for myself. I hope it turns out
> more concise, at least in my view, as the documentation about Perl I
> have currently in my hands. I am writing it to learn Perl, to order my
> thoughts, my understanding of Perl. It has a lot of positive side
> effects though
> - I learn Perl pretty well
> - I learn LaTeX a bit (i decided to write the document in latex) - I
> learn how to efficiently edit LaTex files in Emacs - I learn more about
> meta syntax notations. I am using an own syntax notation which I created
> on this occasion (also to describe bash scripts), since I find EBNF and
> the like quite cumbersome. It's more for the fun of it, to have
> something I personally like better, not to have something which is
> better by objective means.

What are your plans for this documentation? I'm sure people are
interested.

Cheers,
Joost.

Joost Diepenmaat, Dec 12, 2007

### Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.