RE: [perl #133301] Evalulation order during concat changed

Hi,
I think James got the correct point, that the new OP_MULTICONCAT
changes the order of execution.
Unfortunately he used a in-/decrement to change his variable $n,
so I agree with the comments of others with regard to the
order of storing of in-/decremeted variables.
But this has hidden the real issue.

Please see the following:

#### test program ####
$e = 'ab'; $f = 'cd'; $x = $e.$f.($f = 'FF');print '$x = '.$x;
#### end test program ####

#### output test program ####
$x = abcdFF     #### up to Perl 5.26
$x = abFFFF     #### in Perl 5.28.0
#### end output ####

As 'concat' operation is left-associative (see perlop-documentation),
first $e.$f is evaluated. As second step the following bracket
is evaluated, assigning 'FF' to $f. As third step the second
concat is evaluated.

Now in Perl 5.28 with the MULTI_CONCAT this execution model
is no longer valid. Now all inputs to the multiconcat are collected
before the execution of any concatenation, as if the series of concat
operations would be one list operator expecting a list
(but still giving scalar context to the elements in the list).
This means that all concatenations are executed after evaluation of
all arguments (as it is correct for functions in list context).

For me the test program above does not violate any requirements
in the perl documentation, and the result abcdFF should be the
correct result (as up to Perl 5.26).
Thus for me this is an incompatible change to a
series of single concat '.' operations.

Wolf
0
wolf
8/10/2018 4:24:56 PM
perl.perl5.porters 47302 articles. 0 followers. Follow

7 Replies
12 Views

Similar Articles

[PageSpeed] 50

On Fri, Aug 10, 2018 at 06:24:56PM +0200, Wolf-Dietrich Moeller (Munchen) wrote:
> $e = 'ab'; $f = 'cd'; $x = $e.$f.($f = 'FF');print '$x = '.$x;
> 
> $x = abcdFF     #### up to Perl 5.26
> $x = abFFFF     #### in Perl 5.28.0

> As 'concat' operation is left-associative (see perlop-documentation),
> first $e.$f is evaluated. As second step the following bracket
> is evaluated, assigning 'FF' to $f. As third step the second
> concat is evaluated.

The issue here is what order (if any) does perl guarantee sub-expressions
to be evaluated? For example in

    ($a+$b) * ($c*$d)

does perl guarantee that the first addition will take place before the
second addition? I think the answer is no, although I'm willing to be
proved wrong. If not, then multiconcat has only changed undefined
behaviour.

-- 
Diplomacy is telling someone to go to hell in such a way that they'll
look forward to the trip
0
davem
8/10/2018 5:55:58 PM
--000000000000bdf03c05731a4ad2
Content-Type: text/plain; charset="UTF-8"

I don't think it's possible to interpret perldoc perlop's

*Operator precedence* means some operators are evaluated before others. For
example, in 2 + 4 * 5 , the multiplication has higher precedence so 4 * 5 is
evaluated first yielding 2 + 20 == 22 and not 6 * 5 == 30 .

*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 == 2and not 8 -
2 == 6 .

in a way that allows the right side of a left-associative operation to be
evaluated first and still conform with the documentation.

Dot has always been documented as left associative, making Moeller's result
a bug.

(the rest of this e-mail is half-baked)

How heavy would the modification to the multiconcat code be to allow
"snapshots" that would upgrade to copies of the before state when a thing
gets modified later on, instead of simple aliases? I'm guessing just using
copies everywhere would defeat the purpose of the initiative.

How big of a change is recategorizing Dot as non-associative instead of
left-associative? I think huge, in that any code written to rely on the
associativity will not work after upgrade.


Here's a reasonable (contrived for this message, but reasonable) use which
relies on documented evaluation order, and would woefully break (or
possibly not, as postincrement already returns a copy not a lvalue)


my $line_number = 1;

for my $thing (@ListOfThingsThatTakeFourLinesToOutput){

   # all the line methods return lines ending with newlines.

   print $line_number++.' '.$thing->first_line()

        .$line_number++.' '.$thing->second_line()

        .$line_number++.' '.$thing->third_line()

        .$line_number++.' '.$thing->fourth_line();

}



On Fri, Aug 10, 2018 at 12:56 PM Dave Mitchell <davem@iabyn.com> wrote:

> The issue here is what order (if any) does perl guarantee sub-expressions
> to be evaluated? For example in
>
>     ($a+$b) * ($c+$d)
>
> does perl guarantee that the first addition will take place before the
> second addition? I think the answer is no, although I'm willing to be
> proved wrong. If not, then multiconcat has only changed undefined
> behaviour.
>
> --
> Diplomacy is telling someone to go to hell in such a way that they'll
> look forward to the trip
>


-- 
"At this point, given the limited available data, certainty about only a
very small number of things can be achieved." -- Plato, and others

--000000000000bdf03c05731a4ad2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I don&#39;t think it&#39;s possible to interpret perldoc p=
erlop&#39;s<div><p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;c=
olor:rgb(81,81,81);font-family:&quot;Helvetica Neue&quot;,Arial,Helvetica,G=
eneva,sans-serif;font-size:12.8px"><span style=3D"background-color:rgb(255,=
255,0)"><i>Operator precedence</i>=C2=A0means some operators are evaluated =
before others. For example, in=C2=A0<code class=3D"gmail-inline" style=3D"b=
ackground-image:initial;background-position:initial;background-size:initial=
;background-repeat:initial;background-origin:initial;background-clip:initia=
l;border-width:1px;border-style:solid;border-color:rgb(204,204,204);font-si=
ze:1.2em"><span class=3D"gmail-n" style=3D"color:rgb(180,82,205)">2</span>=
=C2=A0+=C2=A0<span class=3D"gmail-n" style=3D"color:rgb(180,82,205)">4</spa=
n>=C2=A0*=C2=A0<span class=3D"gmail-n" style=3D"color:rgb(180,82,205)">5</s=
pan></code>=C2=A0, the multiplication has higher precedence so=C2=A0<code c=
lass=3D"gmail-inline" style=3D"background-image:initial;background-position=
:initial;background-size:initial;background-repeat:initial;background-origi=
n:initial;background-clip:initial;border-width:1px;border-style:solid;borde=
r-color:rgb(204,204,204);font-size:1.2em"><span class=3D"gmail-n" style=3D"=
color:rgb(180,82,205)">4</span>=C2=A0*=C2=A0<span class=3D"gmail-n" style=
=3D"color:rgb(180,82,205)">5</span></code>=C2=A0is evaluated first yielding=
=C2=A0<code class=3D"gmail-inline" style=3D"background-image:initial;backgr=
ound-position:initial;background-size:initial;background-repeat:initial;bac=
kground-origin:initial;background-clip:initial;border-width:1px;border-styl=
e:solid;border-color:rgb(204,204,204);font-size:1.2em"><span class=3D"gmail=
-n" style=3D"color:rgb(180,82,205)">2</span>=C2=A0+=C2=A0<span class=3D"gma=
il-n" style=3D"color:rgb(180,82,205)">20</span>=C2=A0=3D=3D=C2=A0<span clas=
s=3D"gmail-n" style=3D"color:rgb(180,82,205)">22</span></code>=C2=A0and not=
=C2=A0<code class=3D"gmail-inline" style=3D"background-image:initial;backgr=
ound-position:initial;background-size:initial;background-repeat:initial;bac=
kground-origin:initial;background-clip:initial;border-width:1px;border-styl=
e:solid;border-color:rgb(204,204,204);font-size:1.2em"><span class=3D"gmail=
-n" style=3D"color:rgb(180,82,205)">6</span>=C2=A0*=C2=A0<span class=3D"gma=
il-n" style=3D"color:rgb(180,82,205)">5</span>=C2=A0=3D=3D=C2=A0<span class=
=3D"gmail-n" style=3D"color:rgb(180,82,205)">30</span></code>=C2=A0.</span>=
</p><p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,=
81,81);font-family:&quot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-s=
erif;font-size:12.8px"><span style=3D"background-color:rgb(255,255,0)"><i>O=
perator associativity</i>=C2=A0defines what happens if a sequence of the sa=
me operators is used one after another: whether the evaluator will evaluate=
 the left operations first, or the right first. For example, in=C2=A0<code =
class=3D"gmail-inline" style=3D"background-image:initial;background-positio=
n:initial;background-size:initial;background-repeat:initial;background-orig=
in:initial;background-clip:initial;border-width:1px;border-style:solid;bord=
er-color:rgb(204,204,204);font-size:1.2em"><span class=3D"gmail-n" style=3D=
"color:rgb(180,82,205)">8</span>=C2=A0-=C2=A0<span class=3D"gmail-n" style=
=3D"color:rgb(180,82,205)">4</span>=C2=A0-=C2=A0<span class=3D"gmail-n" sty=
le=3D"color:rgb(180,82,205)">2</span></code>=C2=A0, subtraction is left ass=
ociative so Perl evaluates the expression left to right.=C2=A0<code class=
=3D"gmail-inline" style=3D"background-image:initial;background-position:ini=
tial;background-size:initial;background-repeat:initial;background-origin:in=
itial;background-clip:initial;border-width:1px;border-style:solid;border-co=
lor:rgb(204,204,204);font-size:1.2em"><span class=3D"gmail-n" style=3D"colo=
r:rgb(180,82,205)">8</span>=C2=A0-=C2=A0<span class=3D"gmail-n" style=3D"co=
lor:rgb(180,82,205)">4</span></code>=C2=A0is evaluated first making the exp=
ression=C2=A0<code class=3D"gmail-inline" style=3D"background-image:initial=
;background-position:initial;background-size:initial;background-repeat:init=
ial;background-origin:initial;background-clip:initial;border-width:1px;bord=
er-style:solid;border-color:rgb(204,204,204);font-size:1.2em"><span class=
=3D"gmail-n" style=3D"color:rgb(180,82,205)">4</span>=C2=A0-=C2=A0<span cla=
ss=3D"gmail-n" style=3D"color:rgb(180,82,205)">2</span>=C2=A0=3D=3D=C2=A0<s=
pan class=3D"gmail-n" style=3D"color:rgb(180,82,205)">2</span></code>and no=
t=C2=A0<code class=3D"gmail-inline" style=3D"background-image:initial;backg=
round-position:initial;background-size:initial;background-repeat:initial;ba=
ckground-origin:initial;background-clip:initial;border-width:1px;border-sty=
le:solid;border-color:rgb(204,204,204);font-size:1.2em"><span class=3D"gmai=
l-n" style=3D"color:rgb(180,82,205)">8</span>=C2=A0-=C2=A0<span class=3D"gm=
ail-n" style=3D"color:rgb(180,82,205)">2</span>=C2=A0=3D=3D=C2=A0<span clas=
s=3D"gmail-n" style=3D"color:rgb(180,82,205)">6</span></code>=C2=A0.</span>=
</p><p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,=
81,81);font-family:&quot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-s=
erif;font-size:12.8px">in a way that allows the right side of a left-associ=
ative operation to be evaluated first and still conform with the documentat=
ion.</p><p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb=
(81,81,81);font-family:&quot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sa=
ns-serif;font-size:12.8px">Dot has always been documented as left associati=
ve, making Moeller&#39;s result a bug.</p><p style=3D"margin:0px;padding-to=
p:5px;padding-bottom:5px;color:rgb(81,81,81);font-family:&quot;Helvetica Ne=
ue&quot;,Arial,Helvetica,Geneva,sans-serif;font-size:12.8px">(the rest of t=
his e-mail is half-baked)</p><p style=3D"margin:0px;padding-top:5px;padding=
-bottom:5px;color:rgb(81,81,81);font-family:&quot;Helvetica Neue&quot;,Aria=
l,Helvetica,Geneva,sans-serif;font-size:12.8px">How heavy would the modific=
ation to the multiconcat code be to allow &quot;snapshots&quot; that would =
upgrade to copies of the before state when a thing gets modified later on, =
instead of simple aliases? I&#39;m guessing just using copies everywhere wo=
uld defeat the purpose of the initiative.=C2=A0</p><p style=3D"margin:0px;p=
adding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-family:&quot;Hel=
vetica Neue&quot;,Arial,Helvetica,Geneva,sans-serif;font-size:12.8px">How b=
ig of a change is recategorizing Dot as non-associative instead of left-ass=
ociative? I think huge, in that any code written to rely on the associativi=
ty will not work after upgrade.</p><p style=3D"margin:0px;padding-top:5px;p=
adding-bottom:5px;color:rgb(81,81,81);font-family:&quot;Helvetica Neue&quot=
;,Arial,Helvetica,Geneva,sans-serif;font-size:12.8px"><br></p><p style=3D"m=
argin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-famil=
y:&quot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-serif;font-size:12=
..8px">Here&#39;s a reasonable (contrived for this message, but reasonable) =
use which relies on documented evaluation order, and would woefully break (=
or possibly not, as postincrement already returns a copy not a lvalue)</p><=
p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81=
);font-family:&quot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-serif;=
font-size:12.8px"><br></p><p style=3D"margin:0px;padding-top:5px;padding-bo=
ttom:5px;color:rgb(81,81,81);font-size:12.8px"><font face=3D"monospace, mon=
ospace">my $line_number =3D 1;</font></p><p style=3D"margin:0px;padding-top=
:5px;padding-bottom:5px;color:rgb(81,81,81);font-size:12.8px"><font face=3D=
"monospace, monospace">for my $thing (@ListOfThingsThatTakeFourLinesToOutpu=
t){</font></p><p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;col=
or:rgb(81,81,81);font-size:12.8px"><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0# all the line methods return lines ending with newlines.</font><=
/p><p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,8=
1,81);font-size:12.8px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0pr=
int $line_number++.&#39; &#39;.$thing-&gt;first_line()</font></p><p style=
=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-=
size:12.8px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 .$line_number++.&#39; &#39;.$thing-&gt;second_line()</font></p><p style=
=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-=
size:12.8px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 .$line_number++.&#39; &#39;.$thing-&gt;third_line()</font></p><p style=
=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-=
size:12.8px"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 .$line_number++.&#39; &#39;.$thing-&gt;fourth_line();</font></p><p styl=
e=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font=
-size:12.8px"><font face=3D"monospace, monospace">}</font></p><p style=3D"m=
argin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-famil=
y:&quot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-serif;font-size:12=
..8px"><br></p></div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri,=
 Aug 10, 2018 at 12:56 PM Dave Mitchell &lt;<a href=3D"mailto:davem@iabyn.c=
om">davem@iabyn.com</a>&gt; wrote:</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The issue here is what order (if any) does perl guarantee sub-expressions<b=
r>
to be evaluated? For example in<br>
<br>
=C2=A0 =C2=A0 ($a+$b) * ($c+$d)<br>
<br>
does perl guarantee that the first addition will take place before the<br>
second addition? I think the answer is no, although I&#39;m willing to be<b=
r>
proved wrong. If not, then multiconcat has only changed undefined<br>
behaviour.<br>
<br>
-- <br>
Diplomacy is telling someone to go to hell in such a way that they&#39;ll<b=
r>
look forward to the trip<br>
</blockquote></div><br clear=3D"all"><div><br></div>-- <br><div dir=3D"ltr"=
 class=3D"gmail_signature" data-smartmail=3D"gmail_signature">&quot;At this=
 point, given the limited available data, certainty about only a very small=
 number of things can be achieved.&quot; -- Plato, and others</div></div>

--000000000000bdf03c05731a4ad2--
0
davidnicol
8/10/2018 8:06:48 PM
--0000000000004e71d605731aade0
Content-Type: text/plain; charset="UTF-8"

On Fri, Aug 10, 2018 at 4:08 PM David Nicol <davidnicol@gmail.com> wrote:

> How heavy would the modification to the multiconcat code be to allow
> "snapshots" that would upgrade to copies of the before state when a thing
> gets modified later on, instead of simple aliases? I'm guessing just using
> copies everywhere would defeat the purpose of the initiative.
>
> How big of a change is recategorizing Dot as non-associative instead of
> left-associative? I think huge, in that any code written to rely on the
> associativity will not work after upgrade.
>
>
>
There's a third option, which is to not apply the optimization (or apply
the copying behavior) when operands of the concatenation are not simple
scalars.

-Dan

--0000000000004e71d605731aade0
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, Aug 10=
, 2018 at 4:08 PM David Nicol &lt;<a href=3D"mailto:davidnicol@gmail.com">d=
avidnicol@gmail.com</a>&gt; wrote:</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><p style=3D"margin:0px;padding-top:5px;padding-bottom:5px;colo=
r:rgb(81,81,81);font-family:&quot;Helvetica Neue&quot;,Arial,Helvetica,Gene=
va,sans-serif;font-size:12.8px">How heavy would the modification to the mul=
ticoncat code be to allow &quot;snapshots&quot; that would upgrade to copie=
s of the before state when a thing gets modified later on, instead of simpl=
e aliases? I&#39;m guessing just using copies everywhere would defeat the p=
urpose of the initiative.=C2=A0</p><p style=3D"margin:0px;padding-top:5px;p=
adding-bottom:5px;color:rgb(81,81,81);font-family:&quot;Helvetica Neue&quot=
;,Arial,Helvetica,Geneva,sans-serif;font-size:12.8px">How big of a change i=
s recategorizing Dot as non-associative instead of left-associative? I thin=
k huge, in that any code written to rely on the associativity will not work=
 after upgrade.</p><p style=3D"margin:0px;padding-top:5px;padding-bottom:5p=
x;color:rgb(81,81,81);font-family:&quot;Helvetica Neue&quot;,Arial,Helvetic=
a,Geneva,sans-serif;font-size:12.8px"><br></p></div></blockquote><div><br><=
/div><div>There&#39;s a third option, which is to not apply the optimizatio=
n (or apply the copying behavior) when operands of the concatenation are no=
t simple scalars.</div><div><br></div><div>-Dan=C2=A0</div></div></div>

--0000000000004e71d605731aade0--
0
grinnz
8/10/2018 8:34:45 PM
--0000000000003e5a7705731b5006
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Fri, Aug 10, 2018 at 10:08 PM David Nicol <davidnicol@gmail.com> wrote:

> I don't think it's possible to interpret perldoc perlop's
>
> *Operator precedence* means some operators are evaluated before others.
> For example, in 2 + 4 * 5 , the multiplication has higher precedence so 4
>  * 5 is evaluated first yielding 2 + 20 =3D=3D 22 and not 6 * 5 =3D=3D 30=
 .
>
> *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 =3D=3D 2and n=
ot 8
>  - 2 =3D=3D 6 .
>
> in a way that allows the right side of a left-associative operation to be
> evaluated first and still conform with the documentation.
>

  Oh, yes it is: The docs for associativity here speak of the order in
which the ("same-operator") _operations_ will be evaluated =E2=80=93 not th=
e order
in which their _operands_ will be evaluated.

  In C<< $e.$f.($f =3D 'FF') >>, the left-most concatenation is, per the
associativity docs, evaluated before the right-most concatenation.  But the
evaluation order of the _operands_ of the right-most concatenation =E2=80=
=93 that
is, whether or not the left-most concatenation is evaluated before the
assignment =E2=80=93 is not specified in the quoted part of the docs.  And =
that is
the change in question; it may be fair to criticise it, but I don't think
it is fair to suggest it doesn't conform with this documentation.

  If I recall correctly (and it hasn't changed since last this topic was
raised), the assignment, short-cutting (logical), and comma are the only
operators that specify an (operand) evaluation order.  Every other operator
leaves the (operand) evaluation order unspecified.


Eirik

--0000000000003e5a7705731b5006
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Fri, Aug 10, 2018 at 10:08 PM David Nicol &lt;<a href=
=3D"mailto:davidnicol@gmail.com">davidnicol@gmail.com</a>&gt; wrote:<br><di=
v class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I d=
on&#39;t think it&#39;s possible to interpret perldoc perlop&#39;s<div><p s=
tyle=3D"margin:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);f=
ont-family:&quot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-serif;fon=
t-size:12.8px"><span style=3D"background-color:rgb(255,255,0)"><i>Operator =
precedence</i>=C2=A0means some operators are evaluated before others. For e=
xample, in=C2=A0<code class=3D"m_899118873573136070gmail-inline" style=3D"b=
ackground-image:initial;background-position:initial;background-size:initial=
;background-repeat:initial;background-origin:initial;background-clip:initia=
l;border-width:1px;border-style:solid;border-color:rgb(204,204,204);font-si=
ze:1.2em"><span class=3D"m_899118873573136070gmail-n" style=3D"color:rgb(18=
0,82,205)">2</span>=C2=A0+=C2=A0<span class=3D"m_899118873573136070gmail-n"=
 style=3D"color:rgb(180,82,205)">4</span>=C2=A0*=C2=A0<span class=3D"m_8991=
18873573136070gmail-n" style=3D"color:rgb(180,82,205)">5</span></code>=C2=
=A0, the multiplication has higher precedence so=C2=A0<code class=3D"m_8991=
18873573136070gmail-inline" style=3D"background-image:initial;background-po=
sition:initial;background-size:initial;background-repeat:initial;background=
-origin:initial;background-clip:initial;border-width:1px;border-style:solid=
;border-color:rgb(204,204,204);font-size:1.2em"><span class=3D"m_8991188735=
73136070gmail-n" style=3D"color:rgb(180,82,205)">4</span>=C2=A0*=C2=A0<span=
 class=3D"m_899118873573136070gmail-n" style=3D"color:rgb(180,82,205)">5</s=
pan></code>=C2=A0is evaluated first yielding=C2=A0<code class=3D"m_89911887=
3573136070gmail-inline" style=3D"background-image:initial;background-positi=
on:initial;background-size:initial;background-repeat:initial;background-ori=
gin:initial;background-clip:initial;border-width:1px;border-style:solid;bor=
der-color:rgb(204,204,204);font-size:1.2em"><span class=3D"m_89911887357313=
6070gmail-n" style=3D"color:rgb(180,82,205)">2</span>=C2=A0+=C2=A0<span cla=
ss=3D"m_899118873573136070gmail-n" style=3D"color:rgb(180,82,205)">20</span=
>=C2=A0=3D=3D=C2=A0<span class=3D"m_899118873573136070gmail-n" style=3D"col=
or:rgb(180,82,205)">22</span></code>=C2=A0and not=C2=A0<code class=3D"m_899=
118873573136070gmail-inline" style=3D"background-image:initial;background-p=
osition:initial;background-size:initial;background-repeat:initial;backgroun=
d-origin:initial;background-clip:initial;border-width:1px;border-style:soli=
d;border-color:rgb(204,204,204);font-size:1.2em"><span class=3D"m_899118873=
573136070gmail-n" style=3D"color:rgb(180,82,205)">6</span>=C2=A0*=C2=A0<spa=
n class=3D"m_899118873573136070gmail-n" style=3D"color:rgb(180,82,205)">5</=
span>=C2=A0=3D=3D=C2=A0<span class=3D"m_899118873573136070gmail-n" style=3D=
"color:rgb(180,82,205)">30</span></code>=C2=A0.</span></p><p style=3D"margi=
n:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-family:&q=
uot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-serif;font-size:12.8px=
"><span style=3D"background-color:rgb(255,255,0)"><i>Operator associativity=
</i>=C2=A0defines 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=C2=A0<code class=3D"m_8991188735=
73136070gmail-inline" style=3D"background-image:initial;background-position=
:initial;background-size:initial;background-repeat:initial;background-origi=
n:initial;background-clip:initial;border-width:1px;border-style:solid;borde=
r-color:rgb(204,204,204);font-size:1.2em"><span class=3D"m_8991188735731360=
70gmail-n" style=3D"color:rgb(180,82,205)">8</span>=C2=A0-=C2=A0<span class=
=3D"m_899118873573136070gmail-n" style=3D"color:rgb(180,82,205)">4</span>=
=C2=A0-=C2=A0<span class=3D"m_899118873573136070gmail-n" style=3D"color:rgb=
(180,82,205)">2</span></code>=C2=A0, subtraction is left associative so Per=
l evaluates the expression left to right.=C2=A0<code class=3D"m_89911887357=
3136070gmail-inline" style=3D"background-image:initial;background-position:=
initial;background-size:initial;background-repeat:initial;background-origin=
:initial;background-clip:initial;border-width:1px;border-style:solid;border=
-color:rgb(204,204,204);font-size:1.2em"><span class=3D"m_89911887357313607=
0gmail-n" style=3D"color:rgb(180,82,205)">8</span>=C2=A0-=C2=A0<span class=
=3D"m_899118873573136070gmail-n" style=3D"color:rgb(180,82,205)">4</span></=
code>=C2=A0is evaluated first making the expression=C2=A0<code class=3D"m_8=
99118873573136070gmail-inline" style=3D"background-image:initial;background=
-position:initial;background-size:initial;background-repeat:initial;backgro=
und-origin:initial;background-clip:initial;border-width:1px;border-style:so=
lid;border-color:rgb(204,204,204);font-size:1.2em"><span class=3D"m_8991188=
73573136070gmail-n" style=3D"color:rgb(180,82,205)">4</span>=C2=A0-=C2=A0<s=
pan class=3D"m_899118873573136070gmail-n" style=3D"color:rgb(180,82,205)">2=
</span>=C2=A0=3D=3D=C2=A0<span class=3D"m_899118873573136070gmail-n" style=
=3D"color:rgb(180,82,205)">2</span></code>and not=C2=A0<code class=3D"m_899=
118873573136070gmail-inline" style=3D"background-image:initial;background-p=
osition:initial;background-size:initial;background-repeat:initial;backgroun=
d-origin:initial;background-clip:initial;border-width:1px;border-style:soli=
d;border-color:rgb(204,204,204);font-size:1.2em"><span class=3D"m_899118873=
573136070gmail-n" style=3D"color:rgb(180,82,205)">8</span>=C2=A0-=C2=A0<spa=
n class=3D"m_899118873573136070gmail-n" style=3D"color:rgb(180,82,205)">2</=
span>=C2=A0=3D=3D=C2=A0<span class=3D"m_899118873573136070gmail-n" style=3D=
"color:rgb(180,82,205)">6</span></code>=C2=A0.</span></p><p style=3D"margin=
:0px;padding-top:5px;padding-bottom:5px;color:rgb(81,81,81);font-family:&qu=
ot;Helvetica Neue&quot;,Arial,Helvetica,Geneva,sans-serif;font-size:12.8px"=
>in a way that allows the right side of a left-associative operation to be =
evaluated first and still conform with the documentation.</p></div></div></=
blockquote><div><br></div><div>=C2=A0 Oh, yes it is: The docs for associati=
vity here speak of the order in which the (&quot;same-operator&quot;) _oper=
ations_ will be evaluated =E2=80=93 not the order in which their _operands_=
 will be evaluated.</div><div><br></div><div>=C2=A0 In C&lt;&lt; <span clas=
s=3D"gmail-im">$e.$f.($f =3D &#39;FF&#39;) &gt;&gt;, the left-most concaten=
ation is, per the associativity docs, evaluated before the right-most conca=
tenation.=C2=A0 But  the evaluation order of the _operands_ of the right-mo=
st concatenation =E2=80=93 that is, whether or not the left-most concatenat=
ion is evaluated before the assignment =E2=80=93 is not specified in the qu=
oted part of the docs.=C2=A0 And that is the change in question; it may be =
fair to criticise it, but I don&#39;t think it is fair to suggest it doesn&=
#39;t conform with this documentation.<br></span></div><div><br></div></div=
><div class=3D"gmail_quote"><div>=C2=A0 If I recall correctly (and it hasn&=
#39;t changed since last this=20
topic was raised), the assignment, short-cutting (logical), and comma are
 the only operators that specify an (operand) evaluation order.=C2=A0 Every=
 other operator leaves the (operand) evaluation order unspecified.</div><di=
v><br></div><div><br></div><div>Eirik<br></div></div></div>

--0000000000003e5a7705731b5006--
0
Eirik
8/10/2018 9:20:20 PM
Resent because of problems. Sorry

-----Original Message-----
From: Wolf-Dietrich Moeller (M=C3=BCnchen) =
[mailto:wolf-dietrich_moeller@t-online.de]=20
Sent: Samstag, 11. August 2018 10:34
To: 'perlbug-followup@perl.org'
Cc: 'Dave Mitchell'; 'Eirik Berg Hanssen'; 'David Nicol'; =
'sisyphus@cpan.org'; 'Dan Book'
Subject: RE: [perl #133301] Evalulation order during concat changed

David cited the old perlop doc (up to Perl 5.26). This documentation
was changed in Perl 5.28 and the section on operator precedence and
associativity was extended quite a lot (see [perl #127391]).

One sentence there reads:
"In fact Perl has a general rule that the operands of an operator
are evaluated in left-to-right order."

Eirik, did you consider this new text?

Wolf
0
wolf
8/11/2018 10:56:47 AM
--00000000000076f9bd057328f2ec
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sat, Aug 11, 2018 at 12:58 PM Wolf-Dietrich Moeller (M=C3=BCnchen) <
wolf-dietrich_moeller@t-online.de> wrote:

> Resent because of problems. Sorry
>
> -----Original Message-----
> From: Wolf-Dietrich Moeller (M=C3=BCnchen) [mailto:
> wolf-dietrich_moeller@t-online.de]
> Sent: Samstag, 11. August 2018 10:34
> To: 'perlbug-followup@perl.org'
> Cc: 'Dave Mitchell'; 'Eirik Berg Hanssen'; 'David Nicol'; '
> sisyphus@cpan.org'; 'Dan Book'
> Subject: RE: [perl #133301] Evalulation order during concat changed
>
> David cited the old perlop doc (up to Perl 5.26). This documentation
> was changed in Perl 5.28 and the section on operator precedence and
> associativity was extended quite a lot (see [perl #127391]).
>
> One sentence there reads:
> "In fact Perl has a general rule that the operands of an operator
> are evaluated in left-to-right order."
>
> Eirik, did you consider this new text?
>

  No, sorry; I was unaware of it.

  That might be a game changer.

  Or not; the new text is still pretty vague, and don't strictly match the
behaviour of perl.  I also don't see any discussion of this part of the
patch in the RT ticket ...

  Reading that ticket, I get the impression of a failure to properly
distinguish between (operand) evaluation order and the order in which
_operations_ are evaluated.  I'm sorry I didn't catch that at the time: I
surely would have quibbled.

  This example demonstrates that the left-hand operand is evaluated _after_
the right-hand operand, in violation of this "general rule":

eirik@greencat[15:26:12]~$ perl -E 'say for ($x=3D1 + say "LHS") =3D ($x=3D=
2 +
say "RHS")'
RHS
LHS
2
eirik@greencat[15:27:56]~$

  ... assuming that did not also change?  (I don't have a new perl here;
currently stuck on vanilla Ubuntu 18.04.1 LTS and it system perl v5.26.1.)

Eirik

--00000000000076f9bd057328f2ec
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sat, Aug 11, 2018 at 12:58 PM Wolf-Dietrich Moeller (M=
=C3=BCnchen) &lt;<a href=3D"mailto:wolf-dietrich_moeller@t-online.de">wolf-=
dietrich_moeller@t-online.de</a>&gt; wrote:<br><div class=3D"gmail_quote"><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex">Resent because of problems=
.. Sorry<br>
<br>
-----Original Message-----<br>
From: Wolf-Dietrich Moeller (M=C3=BCnchen) [mailto:<a href=3D"mailto:wolf-d=
ietrich_moeller@t-online.de" target=3D"_blank">wolf-dietrich_moeller@t-onli=
ne.de</a>] <br>
Sent: Samstag, 11. August 2018 10:34<br>
To: &#39;<a href=3D"mailto:perlbug-followup@perl.org" target=3D"_blank">per=
lbug-followup@perl.org</a>&#39;<br>
Cc: &#39;Dave Mitchell&#39;; &#39;Eirik Berg Hanssen&#39;; &#39;David Nicol=
&#39;; &#39;<a href=3D"mailto:sisyphus@cpan.org" target=3D"_blank">sisyphus=
@cpan.org</a>&#39;; &#39;Dan Book&#39;<br>
Subject: RE: [perl #133301] Evalulation order during concat changed<br>
<br>
David cited the old perlop doc (up to Perl 5.26). This documentation<br>
was changed in Perl 5.28 and the section on operator precedence and<br>
associativity was extended quite a lot (see [perl #127391]).<br>
<br>
One sentence there reads:<br>
&quot;In fact Perl has a general rule that the operands of an operator<br>
are evaluated in left-to-right order.&quot;<br>
<br>
Eirik, did you consider this new text?<br></blockquote><div><br></div><div>=
=C2=A0 No, sorry; I was unaware of it.</div><div><br></div><div>=C2=A0 That=
 might be a game changer.</div><div><br></div><div>=C2=A0 Or not; the new t=
ext is still pretty vague, and don&#39;t strictly match the behaviour of pe=
rl.=C2=A0 I also don&#39;t see any discussion of this part of the patch in =
the RT ticket ...<br></div><div><br></div><div><div>=C2=A0 Reading that tic=
ket, I get the impression of a failure to properly=20
distinguish between (operand) evaluation order and the order in which _oper=
ations_ are evaluated.=C2=A0 I&#39;m sorry I didn&#39;t catch that at the t=
ime: I surely would have quibbled.<br></div><div><br></div></div><div>=C2=
=A0 This example demonstrates that the left-hand operand is evaluated _afte=
r_ the right-hand operand, in violation of this &quot;general rule&quot;:</=
div><div><br></div><div>eirik@greencat[15:26:12]~$ perl -E &#39;say for ($x=
=3D1 + say &quot;LHS&quot;) =3D ($x=3D2 + say &quot;RHS&quot;)&#39;<br>RHS<=
br>LHS<br>2<br>eirik@greencat[15:27:56]~$ <br></div><div><br></div><div>=C2=
=A0 ... assuming that did not also change?=C2=A0 (I don&#39;t have a new pe=
rl here; currently stuck on vanilla Ubuntu 18.04.1 LTS and it system perl v=
5.26.1.)<br></div><div><br></div><div>Eirik<br></div></div></div>

--00000000000076f9bd057328f2ec--
0
Eirik
8/11/2018 1:36:15 PM
On Sat, Aug 11, 2018 at 03:36:15PM +0200, Eirik Berg Hanssen wrote:
>   This example demonstrates that the left-hand operand is evaluated _after_
> the right-hand operand, in violation of this "general rule":

There's also an example just with a concat mutator, where the order of
FETCH()es of tied arg changes depending on what the args are. This
ordering is unaffected by the introduction of multiconcat:

    sub TIESCALAR { bless [ $_[1] ]; }
    sub FETCH { my $s = $_[0][0]; print "FETCH($s)\n"; $s }
    sub STORE { print "STORE($_[0][0] => $_[1])\n"; $_[0][0] = $_[1] }

    my ($a,$b,$c);
    tie $a, 'main', 'A';
    tie $b, 'main', 'B';
    tie $c, 'main', 'C';

    $a .= $b;
    #$a .= $b . $c;

with $a .= $b, you get:

    FETCH(A)
    FETCH(B)
    STORE(A => AB)

with $a .= $b . $c you get

    FETCH(B)
    FETCH(C)
    FETCH(A)
    STORE(A => ABC)

Note how it changes from FETCHing the LHS first to the RHS first.

This isn't an example of ordering of operand execution inconsistency,
but of fetching the results of such executions. It none the less
demonstrates the danger of relying on an assumed order.



-- 
"You may not work around any technical limitations in the software"
    -- Windows Vista license
0
davem
8/11/2018 3:37:18 PM
Reply: