# Syntax understanding problem - Page 2

•  Subject
• Author
• Posted on

## Re: Syntax understanding problem

Of course, as written, that would obviously simplify into two cases.
But I don't understand what's going on.

print (scalar ((\$a = 23)), "\n");
print (scalar ((\$a = 23) = 45), "\n");

prints

23
1

... unless the parentheses around the second assignment, which I added
merely for precedence, make it considered a list assignment.  But that
would be so insanely stupid -- there would be no way to get a scalar
assignment as in case 1, except maybe with an intervening sub call or
somewhting.

--
Tim McDaniel, tmcd@panix.com

## Re: Syntax understanding problem

tmcd@panix.com (Tim McDaniel) writes:

[...]

Ehh ... well ... (\$a = 23) is obviously a list with a single elementy so

(\$a = 23) = 45

is obviously a list assignment.

## Re: Syntax understanding problem

On Mon, 30 Dec 2013 17:44:47 +0000 in comp.lang.perl.misc, Rainer

How should I write it if I just want to clarify the precedence
without creating a list context?

## Re: Syntax understanding problem

This is incorrect. In an expression such as

(\$a = 23) + 1

the parenthesised part is not a list, it is a scalar.

If the LHS of an assignment is parenthesised it is always a list
assignment. There is no way to avoid this, nor, I believe, is there any
good reason to need to do so. (If you can come up with one I'd be
interested to see it.)

Ben

## Re: Syntax understanding problem

It is a kind of term, an expression in parentheses, and it will be
interpreted based on its context. The +-operator enforces a scalar
context for both of its operands. But the result of

(\$a = 23) + 1

is really the same as the result of

(\$b = 24, \$a = 23) + 1

Grammatically (5.10.1),

term    :       termbinop

[...]

|       '(' expr ')'
}

expr    :       expr ANDOP expr

[...]

|       argexpr %prec PREC_LOW

/* Expressions are a list of terms joined by commas */
argexpr :       argexpr ','

which is the 5.10.1 'list production'.

## Re: Syntax understanding problem

Quoth tmcd@panix.com:

Yes. (Or, 'as a list of modifiable lvalues'.)

(Language!) Yes. This is the weird case, added because the logical
return would be 'the last element of the LHS as a modifiable lvalue',
and a count is more useful (when you remember you can do that).

Yes.

No, a scalar assignment in scalar context returns the LHS as a
modifiable lvalue, again:

say \my \$x;
say \scalar(\$x = 3);

Yes, an assignment whose LHS is explicitly parenthesised is always a
list assignment. Otherwise there's no way to perform a list assignment
to a list of one element; this is the difference between

\$x = /(...)/;

and

(\$x) = /(...)/;

for example.

There's no simple way to perform a scalar assignment into the result of
another scalar assignment, no; but why would you want to do that?

Ben

## Lists (was Re: Syntax understanding problem)

A little more on lists and assignments.

There was a discussion at work that touched on the difference between
"array" and "list".  There was an assertion along the lines of "lists
*do not exist* in scalar context".  In composing a reply, including
why I don't agree with that mental model, I tried this (lots of
extraneous stuff there from previous versions):

\$ perl -e 'sub foo sub bar { 14 } sub baz { @a = (5,6,7); @a }; (1 ? \$x : @y) = (foo(), bar(), baz()); print \$x, "\n"'

I was hoping that it would show that the list on the right could be
evaluated either in a scalar or a list context.  But the parens needed
around the ?: operator made it a list LHS, so the RHS was evaluated in
a list context, so it prints

13

just as if I'd written "(\$x) = (13, 14, 5, 6, 6);".

Only after I rechecked "man perlop" did I realize that ?: has higher
precedence than =, so the parens weren't necessary.

\$ perl -e 'sub baz { @a = (5,6,7); @a }; 0 ? \$x : @y = (13, 14, baz()); print "x=\$x", ", y=", join(" ", @y), "\n"'
x=, y=13 14 5 6 7
\$ perl -e 'sub baz { @a = (5,6,7); @a }; 1 ? \$x : @y = (13, 14, baz()); print "x=\$x", ", y=", join(" ", @y), "\n"'
x=3, y=

But then I tried with a variable, in a test program

sub baz { my @a = (5,6,7); @a };
foreach (0, 1) {
\$_ ? \$x : @y = (13, 14, baz());
print "x=\$x", ", y=", join(" ", @y), "\n";
}
exit 0;

I got the error
Assignment to both a list and a scalar at local/test/117.pl line 3, near ");"
Apparently 1?: and 0?: did compile-time constant folding and avoided
the problem.

The ": lvalue" attribute for a sub only allows a SCALAR lvalue, so
I can't bury the conditional in a sub.

So I don't know of any way to write
... something ... = (13, 14, 5, 6, 7);
in Perl so that it doesn't know at compile time whether the right-hand
side is in a scalar or list context.

But
sub foo {
return (1, 2, 5, 3);
}
doesn't know from just that code what the context is, so I think this
sub is enough of an example that it's not so useful to say "lists do
not exist in scalar context": I aver that it's better to think that
there's a list there, and in a scalar context it is evaluated to its
last element.

--
Tim McDaniel, tmcd@panix.com

## Re: Syntax understanding problem

On 12/30/2013 9:20 AM, Tim McDaniel wrote:

>>  ...

The only quick ways to finesse the list context that occur to me:

perl -E 'say scalar( ((\$a=23)=45)[-1] )'
perl -E 'say scalar( do )'

(can't think of any reason to do so however).

--
Charles DeRykus

## Re: Syntax understanding problem

[...]

I'm not sure what these are meant to do... in both cases the '= 45' is a
list assignment. If you want to perform a scalar context assignment to
the result of a scalar context assignment, I believe the simplest way is
like this:

\${\(\$a = 23)} = 45;

(Neither scalar() nor a do{} block can be assigned to, so although they
would be conceptually simpler they don't work.)

Ben

## Re: Syntax understanding problem

On 12/31/2013 3:42 PM, Ben Morrow wrote:

Did I skew off-tangent...?  this was just a workaround to
finesse the list context within case #2 and get the same results as
case #1, ie, the complaint/challenge: "no way to get a scalar assignment
as in case 1, except maybe with an intervening sub call or something"

> print (scalar ((\$a = 23)), "\n");    # case 1
> print (scalar ((\$a = 23) = 45), "\n"); # case 2
> prints
> 23
> 1

--
Charles DeRykus

## Re: Syntax understanding problem

Someone is certainly confused here, but I'm not sure who it is...

In all the code snippets in this post, the expression '\$a = 23' is a
scalar assignment. In all but mine, the expression '(...) = 45' is a
list assignment. I thought (but I could be wrong) that this was what Tim
was complaining about: that the brackets, which he included only for
precedence, also ended up changing which assignment operator was
invoked.

I'm still not sure what you mean by 'finessing the list context'. Your
first example evaluates the '() = 45' list assignment in list context
(returning a list of one element containing \$a as an lvalue), then
slices out the last element of that list, evaluating the slice in scalar
context (returning \$a as an rvalue). The second achieves the same thing
by a different route, evaluating the list assignment in void context and
then returning \$a as an rvalue directly from the do block. Neither case
returns a value that can be assigned to directly.

Ben

## Re: Syntax understanding problem

On 12/31/2013 8:53 PM, Ben Morrow wrote:

Hm, I assumed there was already consensus that case #2 created a list
context and case #1 didn't. The "finesses" were simple workarounds to
force identical print output as I mentioned earlier. I suspect a more
penetrating analysis was sought :)

--
Charles DeRykus

## Re: Syntax understanding problem

This is just a cryptic perlish way of saying this:

if (/^Relayed messages/) {
next;
}

It was just a way of dispensing with {} and making it a one-liner,
which some people consider cool. (I'm not commenting on that opinion).

\$ perldoc perlop

Cheers
Tony
--
Tony Mountifield
Work: tony@softins.co.uk - http://www.softins.co.uk
Play: tony@mountifield.org - http://tony.mountifield.org

## Re: Syntax understanding problem

tony@mountifield.org (Tony Mountifield) writes:

It should be noted that this is your opinion about people who use
certain syntactic constructs (they're irrational and do bad things
because of that), camouflaged as asessement of the "deep, inner
motivations of someone who 'does something you'd never do yourself'" and
- completely unsurprisingly - you came to the conclusion that "they're
probably mad" (since 'drunk' won't suffice here).

\$discard = 0, next if /^Relayed messages/;

is another way of writing

/^Related messages/ and \$discard = 0, next;

That's an expression using the short-ciruiting behaviour of the boolean
operators for flow control, a possibility which has existed at least
since C, except that Perl provides an alternate set of these operators
whose precedence makes them more suitable for this use and an alternate
syntax someone presumably considered to be clearer than using the
operators. AFAIK, statement modifiers are indeed unique to Perl but
different programming languages actually differ and decrying them as
'cryptic' because they do make little sense ("You're all full of shit
and everything someone who has learnt Math doesn't understand ought to be
banned!" is an old Xah-Lee chestnut, pax hibiscus ...)

## Re: Syntax understanding problem

And exactly for this reason it is just as insane.

Just do not mix code (control flow) and data (expressions).

jue

## Re: Syntax understanding problem

Nope. Larry stole them from BASIC-PLUS (from whence also came the term
'ppcode', and possibly the whole idea of half-compiling).

Ben