Velocity Reviews > Perl > (1)[0] ok but not 1[0]

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

Florian Kaufmann
Guest
Posts: n/a

 12-12-2007
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

Michele Dondi
Guest
Posts: n/a

 12-12-2007
On Wed, 12 Dec 2007 01:55:23 -0800 (PST), Florian Kaufmann
<(E-Mail Removed)> 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,

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

Dr.Ruud
Guest
Posts: n/a

 12-12-2007
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."

Florian Kaufmann
Guest
Posts: n/a

 12-12-2007
> 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
Guest
Posts: n/a

 12-12-2007
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

John W. Krahn
Guest
Posts: n/a

 12-12-2007
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

Ben Morrow
Guest
Posts: n/a

 12-12-2007

Quoth Florian Kaufmann <(E-Mail Removed)>:
>
> 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
Guest
Posts: n/a

 12-12-2007

Quoth Michele Dondi <(E-Mail Removed)>:
> On Wed, 12 Dec 2007 01:55:23 -0800 (PST), Florian Kaufmann
> <(E-Mail Removed)> 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
Guest
Posts: n/a

 12-12-2007

Quoth "John W. Krahn" <(E-Mail Removed)>:
> 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

Michele Dondi
Guest
Posts: n/a

 12-12-2007
On Wed, 12 Dec 2007 05:05:26 -0800 (PST), Florian Kaufmann
<(E-Mail Removed)> 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,