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

F

Florian Kaufmann

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
 
M

Michele Dondi

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
 
F

Florian Kaufmann

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
 
F

Florian Kaufmann

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
 
J

John W. Krahn

Florian said:
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
 
B

Ben Morrow

Quoth Florian Kaufmann said:
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
 
B

Ben Morrow

Quoth Michele Dondi said:
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.
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
 
B

Ben Morrow

Quoth "John W. Krahn said:
Florian said:
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
 
M

Michele Dondi

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
 
M

Michele Dondi

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
 
M

Michele Dondi

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
 
B

Ben Morrow

Quoth Ben Morrow said:
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
 
F

Florian Kaufmann

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";
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Florian Kaufmann
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
 
M

Michele Dondi

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
 
F

Florian Kaufmann

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
 
B

Ben Morrow

Quoth Michele Dondi said:
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
 
J

Joost Diepenmaat

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top