Ben Morrow said:
Quoth Rainer Weikusat said:
The key is the "it's just the list argument separator" here which
implies that a comma in list context is not 'the comma operator' (which
takes two arguments, evaluates both left-to-right and returns the
result of the right one[*]) but a separator.
There is only one comma operator. It always parses the same, and it
always compiles down to the same opcode (it has to, because context
isn't always known at compile time).
Judging from the 5.10.1 perly.y, there's actually no such thing as 'a
comma operator' which would need to be a 'binary operator between
terms'. The lexer treats it as such but in the parser, it's only (slight
simplification)
/* Expressions are a list of terms joined by commas */
argexpr : argexpr ','
{
#ifdef MAD
OP* op = newNULLLIST();
token_getmad($2,op,',');
$$ = append_elem(OP_LIST, $1, op);
#else
$$ = $1;
#endif
}
| argexpr ',' term
{
OP* term = $3;
DO_MAD(
term = newUNOP(OP_NULL, 0, term);
token_getmad($2,term,',');
)
$$ = append_elem(OP_LIST, $1, term);
}
| term %prec PREC_LOW
;
ie, there is something like a list operator and the , is used as purely
syntactical element for separating terms in a list.
[...]
[*] Technically, the scalar-context comma operator is also not an operator
in the sense that + is, it's rather a compiler directive.
Nonsense. The lexer, parser and optree handle it exactly the same way as
they handle +, except for the fact that OP_LIST takes multiple arguments.
At least in certain cases, the list is expanded inline, with no 'list
operator' anywhere in sight, eg
[rw@sable]~#perl -MO=Concise,-exec,a -e 'sub a { return ($_[0], $_[3], $_[2]); }'
main::a:
1 <;> nextstate(main 1 -e:1) v
2 <0> pushmark s
3 <#> aelemfast[*_] s
4 <#> aelemfast[*_] s/3
5 <#> aelemfast[*_] s/2
6 <@> return KP
7 <1> leavesub[1 ref] K/REFC,1
In constrast to this, an addition compiles to
[rw@sable]~#perl -MO=Concise,-exec,a -e 'sub a { return ($_[0] + $_[3] + $_[2]); }'
main::a:
1 <;> nextstate(main 1 -e:1) v
2 <0> pushmark s
3 <#> aelemfast[*_] s
4 <#> aelemfast[*_] s/3
5 <2> add[t3] sK/2
6 <#> aelemfast[*_] s/2
7 <2> add[t5] sKP/2
8 <@> return K
9 <1> leavesub[1 ref] K/REFC,1
And in any case,
[rw@sable]~#perl -e 'LIST =~ /,|comma/i or print "something else\n"'
something else
It would be interesting to know if 'the comma operator' in C is actually
treated as an operator or if the historical misnomer actually came from
there.
NB: I'm very much obliged to you for posting this because it has greatly
helped my understanding of perl, even though this reply may not sound
like this. I don't have an affirmtative mind ...