list context inside term

X

xueweizhong

Hi perl guys,

Let's discuss 2 expressions here:

1.
perl -e 'stat (".") [0]'
syntax error at -e line 1, near ") ["

2.
perl -e '( stat (".") ) [0]'
The 2nd one compiles right.

My question is:

In `( stat (".") ) [0]', the `()' don't decide the list context, but
`()[0]' decides it a list context. Following this way, in `stat(".")
[0]', why [0] doesn't decide that the left side `stat(".")' is
evaluated in list context?

BTW, the `[]' is not counted as an operator in perlop(in C, it's an
binary operator), it's counted as an term delimiter, so we can
redeclare our questions as:

How to decide the list context inside term?

Best regards
Todd
 
J

John W. Krahn

Let's discuss 2 expressions here:

1.
perl -e 'stat (".") [0]'
syntax error at -e line 1, near ") ["

perldoc perlfunc
[ SNIP ]
Any function in the list below may be used either with or
without parentheses around its arguments. (The syntax
descriptions omit the parentheses.) If you use the
parentheses, the simple (but occasionally surprising) rule
is this: It looks like a function, therefore it is a
function, and precedence doesn't matter. Otherwise it's a
list operator or unary operator, and precedence does
matter. And whitespace between the function and left
parenthesis doesn't count--so you need to be careful
sometimes:

print 1+2+4; # Prints 7.
print(1+2) + 4; # Prints 3.
print (1+2)+4; # Also prints 3!
print +(1+2)+4; # Prints 7.
print ((1+2)+4); # Prints 7.

If you run Perl with the -w switch it can warn you about
this. For example, the third line above produces:

print (...) interpreted as function at - line 1.
Useless use of integer addition in void context at - line 1.

2.
perl -e '( stat (".") ) [0]'
The 2nd one compiles right.

My question is:

In `( stat (".") ) [0]', the `()' don't decide the list context, but
`()[0]' decides it a list context. Following this way, in `stat(".")
[0]', why [0] doesn't decide that the left side `stat(".")' is
evaluated in list context?

Its a syntax error so it doesn't compile at all so there is no context.

BTW, the `[]' is not counted as an operator in perlop(in C, it's an
binary operator), it's counted as an term delimiter, so we can
redeclare our questions as:

How to decide the list context inside term?

Context is decided by, well, context. In a list slice like ( stat "."
)[0] there is of course list context. If you want it in scalar context
then put it in scalar context:

my $var = stat ".";

if ( stat "." ) {



John
 
X

xueweizhong

Hi John,

Thanks for you comprehensive answer. But my question still hold:

For stat(".")[0], why the compiler think stat(".") is in a void
context? This is different from print(1)+2 where ...+2 ditermined the
print is evaluated in scalar context.

To be detailed:

stat(".") --- void context, be warned
(stat(".")) --- still void context, be warned
(stat("."))[0] --- list context for stat
stat(".")[0] --- why the language is not smart enough like the (...)
[0] case to the guess the programmer's intent? The intent is obvious
here, we want ...[0] treated as a list context.

Best regards
Todd
 
X

xueweizhong

Hi John,

Why the language is not smart enough to treat ...[0] as a list
context? So that we can write clean code:

stat(".")[0]
rather than boring one:
(stat("."))[0]


-Todd
 
P

Paul Lalli

Hi John,

Thanks for you comprehensive answer. But my question still hold:

For stat(".")[0], why the compiler think stat(".") is in a void
context? This is different from print(1)+2 where ...+2 ditermined the
print is evaluated in scalar context.

To be detailed:

stat(".") --- void context, be warned

No. Not enough information to determine context. Context is
determined by how the expression is used.

stat("."); #void context.
$x = stat("."); #scalar context.
@x = stat("."); #list context.
(stat(".")) --- still void context, be warned

Nope. Still not enough information to determine context. The
parentheses have nothing to do with it.

(stat(".")); #void context.
$x = (stat(".")); #scalar context.
@x = (stat(".")); #list context.
(stat("."))[0] --- list context for stat

Yes. This is list context because the (...)[0] is a list slice. The
[0] applied to something in parentheses makes the list slice.
Obviously you can only take a list slice of a list, so the expression
within the (...) is in list context.
stat(".")[0] --- why the language is not smart enough like the
(...)[0] case to the guess the programmer's intent? The intent is
obvious here, we want ...[0] treated as a list context.

It's not at all obvious to me. In fact, it's very much ambiguous.
Do you want
stat(".")[0]
to mean
(stat("."))[0]
that is "evaluate stat(".") in list context and then take the first
element of the resulting list", or to mean
stat((".")[0])
that is, "take the first element of the list ("."), and pass that
element to the stat() function?"

Because it's ambiguous, Perl makes the decision to call it a syntax
error.

Paul Lalli
 
S

smallpond

Thanks for you comprehensive answer. But my question still hold:
For stat(".")[0], why the compiler think stat(".") is in a void
context? This is different from print(1)+2 where ...+2 ditermined the
print is evaluated in scalar context.
To be detailed:
stat(".") --- void context, be warned

No. Not enough information to determine context. Context is
determined by how the expression is used.

stat("."); #void context.
$x = stat("."); #scalar context.
@x = stat("."); #list context.
(stat(".")) --- still void context, be warned

Nope. Still not enough information to determine context. The
parentheses have nothing to do with it.

(stat(".")); #void context.
$x = (stat(".")); #scalar context.
@x = (stat(".")); #list context.
(stat("."))[0] --- list context for stat

Yes. This is list context because the (...)[0] is a list slice. The
[0] applied to something in parentheses makes the list slice.
Obviously you can only take a list slice of a list, so the expression
within the (...) is in list context.
stat(".")[0] --- why the language is not smart enough like the
(...)[0] case to the guess the programmer's intent? The intent is
obvious here, we want ...[0] treated as a list context.

It's not at all obvious to me. In fact, it's very much ambiguous.
Do you want
stat(".")[0]
to mean
(stat("."))[0]
that is "evaluate stat(".") in list context and then take the first
element of the resulting list", or to mean
stat((".")[0])
that is, "take the first element of the list ("."), and pass that
element to the stat() function?"

Because it's ambiguous, Perl makes the decision to call it a syntax
error.

Paul Lalli

It's not ambiguous. perlop has precedence rules for determining
which of those two cases would apply. Terms and list operators
are left-associative and all equal precedence so
stat(".")[0] would be (stat("."))[0].

The missing list context in this case is a known perl5 bug.
perl6 proposes a list keyword for just this issue:
http://dev.perl.org/perl6/rfc/175.html
 
X

xhoster

BTW, the `[]' is not counted as an operator in perlop(in C, it's an
binary operator), it's counted as an term delimiter, so we can
redeclare our questions as:

Is this from the docs, or your interpretation of observed behavior?
If from the docs, can you point me to the section?

Thanks,

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
R

Randal L. Schwartz

xueweizhong> In `( stat (".") ) [0]', the `()' don't decide the list context, but
xueweizhong> `()[0]' decides it a list context. Following this way, in `stat(".")
xueweizhong> [0]', why [0] doesn't decide that the left side `stat(".")' is
xueweizhong> evaluated in list context?

Because that's not a standlone syntax.

You can have:

$foo[$bar] - element of an array
@foo[@bar] - many elements of an array
(SomeListExpression)[@bar] - many elements of a list expression

But [] by itself as a suffix doesn't mean anything.
 
D

Dr.Ruud

smallpond schreef:
The missing list context in this case is a known perl5 bug.
perl6 proposes a list keyword for just this issue:
http://dev.perl.org/perl6/rfc/175.html

How about the missing boolean context.

$x = grep( sometest($_), @values ) ? 'yes' : 'no';

in which grep() could shortcut, meaning stop when the first value would
make sometest() return true.

See also List::Util::first().
 
D

Dr.Ruud

Dr.Ruud schreef:
smallpond schreef:

How about the missing boolean context.

$x = grep( sometest($_), @values ) ? 'yes' : 'no';

Correction:

$x = (grep( sometest($_), @values ) ? 'yes' : 'no');
 

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

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top