Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

possible inconsistency in "perlop" documentation on associativity of operators #15153

Closed
p5pRT opened this issue Jan 27, 2016 · 17 comments
Closed

Comments

@p5pRT
Copy link

p5pRT commented Jan 27, 2016

Migrated from rt.perl.org#127391 (status was 'resolved')

Searchable as RT127391$

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2016

From wolf-dietrich_moeller@t-online.de

Hello,
I am not sure if the following issue in the "perlop"-documentation needs
clarification.

In the section on "Operator Precedence and Associativity" there is the line​:
"right = += -= *= etc. goto last next redo dump"
The "etc." means to me that all other assignment operators are also
right-associative, i.e. in particular also the short-circuit "&&=", "||="
and "//=".

Taking the explanation in the section on "Assignment Operators" (further
below in perlop), the example given there for a "combined operator" can be
extended to a sequence of operators with "&&="​:
  $y &&= $x += 2; is equivalent to $y = $y && ($x = $x + 2);
Given the short-circuit behavior of '&&', it is clear that the assignment
"($x = $x + 2)" in the "equivalent assignment" (right) is not executed if $y
== 0 (and correctly the "simple" assignment '$y = ' is right-associative).
But looking to the "original assignment" (left), where $y only appears to
the left of the "&&=" operator, the (effective) associativity for this "&&="
operator is "left".

This is counter-intuitive to the text in the documentation given above, that
ALL assignment operators are right-associative.
It seems to me that this only applies if a "combined" operator is separated
into the equivalent form with "simple" operators; but then it is no longer
the "combined" assignment operator.
Should this be reflected somewhere in the documentation (in the section on
"Operator Precedence and Associativity")?

This issue is not related to any particular Perl version, as I found the
same text already in my old Perl 5.0 Manpages.

Best regards
Wolf Moeller

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2016

From @mauke

Am 27.01.2016 um 17​:32 schrieb Wolf-Dietrich Moeller (via RT)​:

# New Ticket Created by Wolf-Dietrich Moeller
# Please include the string​: [perl #127391]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=127391 >

Hello,
I am not sure if the following issue in the "perlop"-documentation needs
clarification.

In the section on "Operator Precedence and Associativity" there is the line​:
"right = += -= *= etc. goto last next redo dump"
The "etc." means to me that all other assignment operators are also
right-associative, i.e. in particular also the short-circuit "&&=", "||="
and "//=".

Taking the explanation in the section on "Assignment Operators" (further
below in perlop), the example given there for a "combined operator" can be
extended to a sequence of operators with "&&="​:
$y &&= $x += 2; is equivalent to $y = $y && ($x = $x + 2);
Given the short-circuit behavior of '&&', it is clear that the assignment
"($x = $x + 2)" in the "equivalent assignment" (right) is not executed if $y
== 0 (and correctly the "simple" assignment '$y = ' is right-associative).

OK so far.

But looking to the "original assignment" (left), where $y only appears to
the left of the "&&=" operator, the (effective) associativity for this "&&="
operator is "left".

I don't understand this at all. If &&= and += were left associative,
then $y &&= $x += 2 would be parsed as ($y &&= $x) += 2, which is
clearly not the case.

What do you mean by effective associativity?

--
Lukas Mai <plokinom@​gmail.com>

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2016

From wolf-dietrich_moeller@t-online.de

Hi Lukas,
thanks for the fast response.

The perlop-documentation specifies associativity as (citation)​:
"Operator associativity defines what happens if a sequence of the same operators is used one after another​: whether the evaluator will evaluate the left operations first, or the right first."

Perhaps my example mislead you, as I did not show a sequence of the SAME operators (sorry for that). But please look at the following test program​:
############
my $x = 3;
my $y = 0;
my $z = 6;
$x &&= $y &&= $z &&= 7;
print "x=$x y=$y z=$z";
###########
The result with my Perl 5.22.1 is​:
x=0 y=0 z=6
############
Taking the specification for associativity cited above, evaluation should start with the rightmost operator, as all 3 operators are &&= (sequence of same operators). And then $z should be 7 and not 6, as $z was preset to 6 (== true), and "$z &&= 7" results in 7.
The second evaluation should be for "$y &&= $z", which correctly yields $y == 0, as $y was preset to 0.
Last the first operator should be evaluated, which correctly yields $x == 0, as $y == 0.

So for the &&= operator to be "right-associative" according to the specification cited above, I am missing the evaluation of the rightmost operator. Thus the associativity of &&= must be something else.
I wrote "effective left-associative", as I studied electrical engineering, and not computer science, and thus I am not sure if this behaviour of &&= is really called left-associative, or something else by CS guys.

Hope this clarifies my issue.

Best regards
Wolf

-----Original Message-----
From​: Lukas Mai via RT [mailto​:perlbug-followup@​perl.org]
Sent​: Mittwoch, 27. Januar 2016 22​:46
To​: wolf-dietrich_moeller@​t-online.de
Subject​: Re​: [perl #127391] possible inconsistency in "perlop" documentation on associativity of operators

Am 27.01.2016 um 17​:32 schrieb Wolf-Dietrich Moeller (via RT)​:

# New Ticket Created by Wolf-Dietrich Moeller
# Please include the string​: [perl #127391]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=127391 >

Hello,
I am not sure if the following issue in the "perlop"-documentation needs
clarification.

In the section on "Operator Precedence and Associativity" there is the line​:
"right = += -= *= etc. goto last next redo dump"
The "etc." means to me that all other assignment operators are also
right-associative, i.e. in particular also the short-circuit "&&=", "||="
and "//=".

Taking the explanation in the section on "Assignment Operators" (further
below in perlop), the example given there for a "combined operator" can be
extended to a sequence of operators with "&&="​:
$y &&= $x += 2; is equivalent to $y = $y && ($x = $x + 2);
Given the short-circuit behavior of '&&', it is clear that the assignment
"($x = $x + 2)" in the "equivalent assignment" (right) is not executed if $y
== 0 (and correctly the "simple" assignment '$y = ' is right-associative).

OK so far.

But looking to the "original assignment" (left), where $y only appears to
the left of the "&&=" operator, the (effective) associativity for this "&&="
operator is "left".

I don't understand this at all. If &&= and += were left associative,
then $y &&= $x += 2 would be parsed as ($y &&= $x) += 2, which is
clearly not the case.

What do you mean by effective associativity?

--
Lukas Mai <plokinom@​gmail.com>

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2016

From zefram@fysh.org

Wolf-Dietrich Moeller wrote​:

Taking the specification for associativity cited above, evaluation
should start with the rightmost operator,

This is a misunderstanding of operator precedence. Precedence resolves
the syntactic ambiguity to determine grouping, *not* order of evaluation.
Order of evaluation is a semantic matter, determined by the meaning of
the operators. Sometimes precedence is described in terms of order of
evaluation, but that correspondence only works in situations where all
the operators evaluate all of their operands and the actual order of
evaluation of the subexpressions doesn't make any difference.

In your example, the expression

  $x &&= $y &&= $z &&= 7

by virtue of precedence groups as

  $x &&= ($y &&= ($z &&= 7))

In evaluation, the operator having greatest control is always the
top-level one. In this case, the top-level operator is the leftmost &&=.
It sees that its lhs $x is true, so decides to evaluate its rhs and
assign the result to $x. Its rhs is

  $y &&= ($z &&= 7)

The top-level operator here is the middle &&= of the original expression.
It sees that its lhs $y is false, and so decides not to evaluate its rhs
and not to modify $y. Therefore the rightmost &&= never gets control.
$z is therefore never in danger of being modified. The middle &&=
yields the false value of $y as the value of the $y&&= expression,
and the leftmost (top-level) &&= assigns that value to $x. Hence the
result that you see. Everything is operating correctly.

I wrote "effective left-associative", as I studied electrical
engineering, and not computer science, and thus I am not sure if this
behaviour of &&= is really called left-associative, or something else
by CS guys.

It's not left-associative. If it were, then the expression you wrote
would group as

  (($x &&= $y) &&= $z) &&= 7

This is a valid expression, and does not behave the same as the
right-associated version. It happens to produce the same answer as
the right-associated version given the starting values in your example,
but the two give different answers if you start with a different set of
values, such as $x=3, $y=6, $z=0. Using an &&= expression as the lhs
of an assignment is quite unusual, and its behaviour is liable to be
surprising, so don't worry too much about understanding it.

The distinctive behaviour of &&= that you mistakenly described as
effective left-associativity is really its selective evaluation of
its rhs. But even operators that evaluate all their operands do so in
a specific order, which has nothing to do with precedence​:

  $ perl -e '(print 1) + (print 2) + (print 3); print "\n"'
  123
  $ perl -e '(print 1) ** (print 2) ** (print 3); print "\n"'
  123

In this example, both + and ** evaluate their operands from left to right,
even though + is left-associative and ** is right-associative.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Feb 1, 2016

From wolf-dietrich_moeller@t-online.de

Hi Zefram,
thanks for your explanation.

You write that describing associativity in terms of order of evaluation is only true
" where all the operators **evaluate all of their operands** and the actual order of evaluation of the subexpressions doesn't make any difference ".

Do I understand you correctly, that you imply that the existing text in the perlop-documentation is wrong for the combined operators with short-circuit operations (&&=, ||= and //=), where not all operands are evaluated by the operator?

The existing text reads (cited)​:
"Operator associativity defines what happens if a sequence of the same operators is used one after another​: whether the evaluator will **evaluate** the left operations first, or the right first. For example, in 8 - 4 - 2, subtraction is left associative so Perl evaluates the expression left to right. 8 - 4 is evaluated first making the expression 4 - 2 == 2 and not 8 - 2 == 6."

(I agree that for the example of subtraction given there the wording with "evaluation" is correct, but it is wrong for the case of combined operators with short-circuit behavior.)

Should this text instead be adapted to refer to "grouping" instead of "evaluation", or should there be an additional sentence catering for the special case of combined operators with short-circuit behaviour?
This would resolve the issue I raised.

Best regards
Wolf

@p5pRT
Copy link
Author

p5pRT commented Feb 1, 2016

From zefram@fysh.org

Wolf-Dietrich Moeller wrote​:

Do I understand you correctly, that you imply that the existing text
in the perlop-documentation is wrong for the combined operators with
short-circuit operations (&&=, ||= and //=), where not all operands are
evaluated by the operator?

Ah yes, the text you quote (and the preceding paragraph about precedence)
is indeed incorrect for short-circuiting operators.

Should this text instead be adapted to refer to "grouping" instead of
"evaluation", or should there be an additional sentence catering for
the special case of combined operators with short-circuit behaviour?

I'd rather not treat short-circuiting as a special case, because it's not,
for this purpose. If anything the special case is the simple operators,
and that's probably worth bringing out explicitly. I suggest those two
paragraphs should become

  I<Operator precedence> means some operators group more tightly than
  others. For example, in C<2 + 4 * 5>, the multiplication has higher
  precedence, so C<4 * 5> is grouped together as the right-hand operand
  of the addition, rather than C<2 + 4> being grouped together as the
  left-hand operand of the multiplication. It is as if the expression
  were written C<2 + (4 * 5)>, not C<(2 + 4) * 5>. So the expression
  yields C<2 + 20 == 22>, rather than C<6 * 5 == 30>.

  I<Operator associativity> defines what happens if a sequence of the
  same operators is used one after another​: whether they will be grouped
  at the left or the right. For example, in C<9 - 3 - 2>, subtraction
  is left associative, so C<9 - 3> is grouped together as the left-hand
  operand of the second subtraction, rather than C<3 - 2> being grouped
  together as the right-hand operand of the first subtraction. It is
  as if the expression were written C<(9 - 3) - 2>, not C<9 - (3 - 2)>.
  So the expression yields C<6 - 2 == 4>, rather than C<9 - 1 == 8>.

  For simple operators that evaluate all their operands and then
  combine the values in some way, precedence and associativity (and
  parentheses) imply some ordering requirements on those combining
  operations. For example, in C<2 + 4 * 5>, the grouping implied by
  precedence means that the multiplication of 4 and 5 must be performed
  before the addition of 2 and 20, simply because the result of that
  multiplication is required as one of the operands of the addition.
  But the order of operations is not fully determined by this​: in C<2 *
  2 + 4 * 5> both multiplications must be performed before the addition,
  but the grouping does not say anything about the order in which the
  two multiplications are performed. In fact Perl has a general rule
  that the operands of an operator are evaluated in left-to-right order.
  A few operators such as C<&&=> have special evaluation rules that
  can result in an operand not being evaluated at all; in general, the
  top-level operator in an expression has control of operand evaluation.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2016

From wolf-dietrich_moeller@t-online.de

Zefram wrote​:

I'd rather not treat short-circuiting as a special case, because it's not,
for this purpose. If anything the special case is the simple operators,
and that's probably worth bringing out explicitly. I suggest those two
paragraphs should become ....

I agree with the text you suggest to replace the existing text in perlop-documentation.
This now clearly shows behaviour as specified and implemented in Perl.
I think this should go into the forthcoming version of Perl.

Thanks
Wolf

@p5pRT
Copy link
Author

p5pRT commented Apr 21, 2016

From @jkeenan

On Mon Feb 01 09​:29​:42 2016, zefram@​fysh.org wrote​:

Wolf-Dietrich Moeller wrote​:

Do I understand you correctly, that you imply that the existing text
in the perlop-documentation is wrong for the combined operators with
short-circuit operations (&&=, ||= and //=), where not all operands are
evaluated by the operator?

Ah yes, the text you quote (and the preceding paragraph about precedence)
is indeed incorrect for short-circuiting operators.

Should this text instead be adapted to refer to "grouping" instead of
"evaluation", or should there be an additional sentence catering for
the special case of combined operators with short-circuit behaviour?

I'd rather not treat short-circuiting as a special case, because it's not,
for this purpose. If anything the special case is the simple operators,
and that's probably worth bringing out explicitly. I suggest those two
paragraphs should become

I\<Operator precedence> means some operators group more tightly than
others\.  For example\, in C\<2 \+ 4 \* 5>\, the multiplication has higher
precedence\, so C\<4 \* 5> is grouped together as the right\-hand operand
of the addition\, rather than C\<2 \+ 4> being grouped together as the
left\-hand operand of the multiplication\.  It is as if the expression
were written C\<2 \+ \(4 \* 5\)>\, not C\<\(2 \+ 4\) \* 5>\.  So the expression
yields C\<2 \+ 20 == 22>\, rather than C\<6 \* 5 == 30>\.

I\<Operator associativity> defines what happens if a sequence of the
same operators is used one after another&#8203;: whether they will be grouped
at the left or the right\.  For example\, in C\<9 \- 3 \- 2>\, subtraction
is left associative\, so C\<9 \- 3> is grouped together as the left\-hand
operand of the second subtraction\, rather than C\<3 \- 2> being grouped
together as the right\-hand operand of the first subtraction\.  It is
as if the expression were written C\<\(9 \- 3\) \- 2>\, not C\<9 \- \(3 \- 2\)>\.
So the expression yields C\<6 \- 2 == 4>\, rather than C\<9 \- 1 == 8>\.

For simple operators that evaluate all their operands and then
combine the values in some way\, precedence and associativity \(and
parentheses\) imply some ordering requirements on those combining
operations\.  For example\, in C\<2 \+ 4 \* 5>\, the grouping implied by
precedence means that the multiplication of 4 and 5 must be performed
before the addition of 2 and 20\, simply because the result of that
multiplication is required as one of the operands of the addition\.
But the order of operations is not fully determined by this&#8203;: in C\<2 \*
2 \+ 4 \* 5> both multiplications must be performed before the addition\,
but the grouping does not say anything about the order in which the
two multiplications are performed\.  In fact Perl has a general rule
that the operands of an operator are evaluated in left\-to\-right order\.
A few operators such as C\<&&=> have special evaluation rules that
can result in an operand not being evaluated at all; in general\, the
top\-level operator in an expression has control of operand evaluation\.

-zefram

In order to move this ticket toward resolution I've formatted Zefram's recommendation into a patch attached to this ticket.

Please discuss so that we know whether we want to apply this in 5.25.1.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Apr 21, 2016

From @jkeenan

127391-0001-Improve-documentation-of-operator-precedence-and-ass.patch
From fc6fe274f70057369f007f92305e3a31ae706a68 Mon Sep 17 00:00:00 2001
From: Zefram <zefram@fysh.org>
Date: Wed, 20 Apr 2016 22:00:09 -0400
Subject: [PATCH] Improve documentation of operator precedence and
 associativity.

For RT #127391
---
 pod/perlop.pod | 42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/pod/perlop.pod b/pod/perlop.pod
index 17d24bb..ef47b45 100644
--- a/pod/perlop.pod
+++ b/pod/perlop.pod
@@ -27,17 +27,37 @@ X<operator, precedence> X<precedence> X<associativity>
 Operator precedence and associativity work in Perl more or less like
 they do in mathematics.
 
-I<Operator precedence> means some operators are evaluated before
-others.  For example, in S<C<2 + 4 * 5>>, the multiplication has higher
-precedence so S<C<4 * 5>> is evaluated first yielding S<C<2 + 20 ==
-22>> and not S<C<6 * 5 == 30>>.
-
-I<Operator associativity> defines what happens if a sequence of the
-same operators is used one after another: whether the evaluator will
-evaluate the left operations first, or the right first.  For example, in
-S<C<8 - 4 - 2>>, subtraction is left associative so Perl evaluates the
-expression left to right.  S<C<8 - 4>> is evaluated first making the
-expression S<C<4 - 2 == 2>> and not S<C<8 - 2 == 6>>.
+I<Operator precedence> means some operators group more tightly than others.
+For example, in C<2 + 4 * 5>, the multiplication has higher precedence, so C<4
+* 5> is grouped together as the right-hand operand of the addition, rather
+than C<2 + 4> being grouped together as the left-hand operand of the
+multiplication. It is as if the expression were written C<2 + (4 * 5)>, not
+C<(2 + 4) * 5>. So the expression yields C<2 + 20 == 22>, rather than
+C<6 * 5 == 30>.
+
+I<Operator associativity> defines what happens if a sequence of the same
+operators is used one after another: whether they will be grouped at the left
+or the right. For example, in C<9 - 3 - 2>, subtraction is left associative,
+so C<9 - 3> is grouped together as the left-hand operand of the second
+subtraction, rather than C<3 - 2> being grouped together as the right-hand
+operand of the first subtraction. It is as if the expression were written
+C<(9 - 3) - 2>, not C<9 - (3 - 2)>. So the expression yields C<6 - 2 == 4>,
+rather than C<9 - 1 == 8>.
+
+For simple operators that evaluate all their operands and then combine the
+values in some way, precedence and associativity (and parentheses) imply some
+ordering requirements on those combining operations. For example, in C<2 + 4 *
+5>, the grouping implied by precedence means that the multiplication of 4 and
+5 must be performed before the addition of 2 and 20, simply because the result
+of that multiplication is required as one of the operands of the addition. But
+the order of operations is not fully determined by this: in C<2 * 2 + 4 * 5>
+both multiplications must be performed before the addition, but the grouping
+does not say anything about the order in which the two multiplications are
+performed. In fact Perl has a general rule that the operands of an operator
+are evaluated in left-to-right order. A few operators such as C<&&=> have
+special evaluation rules that can result in an operand not being evaluated at
+all; in general, the top-level operator in an expression has control of
+operand evaluation.
 
 Perl operators have the following associativity and precedence,
 listed from highest precedence to lowest.  Operators borrowed from
-- 
1.9.1

@p5pRT
Copy link
Author

p5pRT commented Apr 21, 2016

From @demerphq

I vote yes.

On 21 April 2016 at 04​:05, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Mon Feb 01 09​:29​:42 2016, zefram@​fysh.org wrote​:

Wolf-Dietrich Moeller wrote​:

Do I understand you correctly, that you imply that the existing text
in the perlop-documentation is wrong for the combined operators with
short-circuit operations (&&=, ||= and //=), where not all operands are
evaluated by the operator?

Ah yes, the text you quote (and the preceding paragraph about precedence)
is indeed incorrect for short-circuiting operators.

Should this text instead be adapted to refer to "grouping" instead of
"evaluation", or should there be an additional sentence catering for
the special case of combined operators with short-circuit behaviour?

I'd rather not treat short-circuiting as a special case, because it's not,
for this purpose. If anything the special case is the simple operators,
and that's probably worth bringing out explicitly. I suggest those two
paragraphs should become

I\<Operator precedence> means some operators group more tightly than
others\.  For example\, in C\<2 \+ 4 \* 5>\, the multiplication has higher
precedence\, so C\<4 \* 5> is grouped together as the right\-hand operand
of the addition\, rather than C\<2 \+ 4> being grouped together as the
left\-hand operand of the multiplication\.  It is as if the expression
were written C\<2 \+ \(4 \* 5\)>\, not C\<\(2 \+ 4\) \* 5>\.  So the expression
yields C\<2 \+ 20 == 22>\, rather than C\<6 \* 5 == 30>\.

I\<Operator associativity> defines what happens if a sequence of the
same operators is used one after another&#8203;: whether they will be grouped
at the left or the right\.  For example\, in C\<9 \- 3 \- 2>\, subtraction
is left associative\, so C\<9 \- 3> is grouped together as the left\-hand
operand of the second subtraction\, rather than C\<3 \- 2> being grouped
together as the right\-hand operand of the first subtraction\.  It is
as if the expression were written C\<\(9 \- 3\) \- 2>\, not C\<9 \- \(3 \- 2\)>\.
So the expression yields C\<6 \- 2 == 4>\, rather than C\<9 \- 1 == 8>\.

For simple operators that evaluate all their operands and then
combine the values in some way\, precedence and associativity \(and
parentheses\) imply some ordering requirements on those combining
operations\.  For example\, in C\<2 \+ 4 \* 5>\, the grouping implied by
precedence means that the multiplication of 4 and 5 must be performed
before the addition of 2 and 20\, simply because the result of that
multiplication is required as one of the operands of the addition\.
But the order of operations is not fully determined by this&#8203;: in C\<2 \*
2 \+ 4 \* 5> both multiplications must be performed before the addition\,
but the grouping does not say anything about the order in which the
two multiplications are performed\.  In fact Perl has a general rule
that the operands of an operator are evaluated in left\-to\-right order\.
A few operators such as C\<&&=> have special evaluation rules that
can result in an operand not being evaluated at all; in general\, the
top\-level operator in an expression has control of operand evaluation\.

-zefram

In order to move this ticket toward resolution I've formatted Zefram's recommendation into a patch attached to this ticket.

Please discuss so that we know whether we want to apply this in 5.25.1.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=127391

From fc6fe274f70057369f007f92305e3a31ae706a68 Mon Sep 17 00​:00​:00 2001
From​: Zefram <zefram@​fysh.org>
Date​: Wed, 20 Apr 2016 22​:00​:09 -0400
Subject​: [PATCH] Improve documentation of operator precedence and
associativity.

For RT #127391
---
pod/perlop.pod | 42 +++++++++++++++++++++++++++++++-----------
1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/pod/perlop.pod b/pod/perlop.pod
index 17d24bb..ef47b45 100644
--- a/pod/perlop.pod
+++ b/pod/perlop.pod
@​@​ -27,17 +27,37 @​@​ X<operator, precedence> X<precedence> X<associativity>
Operator precedence and associativity work in Perl more or less like
they do in mathematics.

-I<Operator precedence> means some operators are evaluated before
-others. For example, in S<C<2 + 4 * 5>>, the multiplication has higher
-precedence so S<C<4 * 5>> is evaluated first yielding S<C<2 + 20 ==
-22>> and not S<C<6 * 5 == 30>>.
-
-I<Operator associativity> defines what happens if a sequence of the
-same operators is used one after another​: whether the evaluator will
-evaluate the left operations first, or the right first. For example, in
-S<C<8 - 4 - 2>>, subtraction is left associative so Perl evaluates the
-expression left to right. S<C<8 - 4>> is evaluated first making the
-expression S<C<4 - 2 == 2>> and not S<C<8 - 2 == 6>>.
+I<Operator precedence> means some operators group more tightly than others.
+For example, in C<2 + 4 * 5>, the multiplication has higher precedence, so C<4
+* 5> is grouped together as the right-hand operand of the addition, rather
+than C<2 + 4> being grouped together as the left-hand operand of the
+multiplication. It is as if the expression were written C<2 + (4 * 5)>, not
+C<(2 + 4) * 5>. So the expression yields C<2 + 20 == 22>, rather than
+C<6 * 5 == 30>.
+
+I<Operator associativity> defines what happens if a sequence of the same
+operators is used one after another​: whether they will be grouped at the left
+or the right. For example, in C<9 - 3 - 2>, subtraction is left associative,
+so C<9 - 3> is grouped together as the left-hand operand of the second
+subtraction, rather than C<3 - 2> being grouped together as the right-hand
+operand of the first subtraction. It is as if the expression were written
+C<(9 - 3) - 2>, not C<9 - (3 - 2)>. So the expression yields C<6 - 2 == 4>,
+rather than C<9 - 1 == 8>.
+
+For simple operators that evaluate all their operands and then combine the
+values in some way, precedence and associativity (and parentheses) imply some
+ordering requirements on those combining operations. For example, in C<2 + 4 *
+5>, the grouping implied by precedence means that the multiplication of 4 and
+5 must be performed before the addition of 2 and 20, simply because the result
+of that multiplication is required as one of the operands of the addition. But
+the order of operations is not fully determined by this​: in C<2 * 2 + 4 * 5>
+both multiplications must be performed before the addition, but the grouping
+does not say anything about the order in which the two multiplications are
+performed. In fact Perl has a general rule that the operands of an operator
+are evaluated in left-to-right order. A few operators such as C<&&=> have
+special evaluation rules that can result in an operand not being evaluated at
+all; in general, the top-level operator in an expression has control of
+operand evaluation.

Perl operators have the following associativity and precedence,
listed from highest precedence to lowest. Operators borrowed from
--
1.9.1

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Jun 20, 2016

From @iabyn

On 21 April 2016 at 04​:05, James E Keenan via RT

In order to move this ticket toward resolution I've formatted Zefram's recommendation into a patch attached to this ticket.

Please discuss so that we know whether we want to apply this in 5.25.1.

On Thu, Apr 21, 2016 at 09​:24​:20AM +0200, demerphq wrote​:

I vote yes.

Me too.

--
"You may not work around any technical limitations in the software"
  -- Windows Vista license

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2017

From wolf-dietrich_moeller@t-online.de

What happened to this proposal?
As of Perl 5.26, the text in perlop is still the old text, which is wrong with respect to the short-circuiting operators "&&=", "||=" and "//=".
I think this should be included in Perl 5.28.

Wolf

-----Original Message-----
From​: Dave Mitchell via RT [mailto​:perlbug-followup@​perl.org]
Sent​: Montag, 20. Juni 2016 11​:05
To​: wolf-dietrich_moeller@​t-online.de
Subject​: Re​: [perl #127391] possible inconsistency in "perlop" documentation on associativity of operators

On 21 April 2016 at 04​:05, James E Keenan via RT

In order to move this ticket toward resolution I've formatted Zefram's recommendation into a patch attached to this ticket.

Please discuss so that we know whether we want to apply this in 5.25.1.

On Thu, Apr 21, 2016 at 09​:24​:20AM +0200, demerphq wrote​:

I vote yes.

Me too.

--
"You may not work around any technical limitations in the software"
  -- Windows Vista license

@p5pRT
Copy link
Author

p5pRT commented Dec 5, 2017

From zefram@fysh.org

Wolf-Dietrich Moeller (Munchen) wrote​:

What happened to this proposal?

It got dropped on the floor, sorry. I've now patched the documentation
in commit 3c0dbbb.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 5, 2017

@cpansprout - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented Jun 23, 2018

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release yesterday of Perl 5.28.0, this and 185 other issues have been
resolved.

Perl 5.28.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.28.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT
Copy link
Author

p5pRT commented Jun 23, 2018

@khwilliamson - Status changed from 'pending release' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant