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 47450 articles. 0 followers. Follow

11 Replies
49 Views

Similar Articles

[PageSpeed] 52

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
--0000000000005318e605741e6e9e
Content-Type: multipart/alternative; boundary="0000000000005318e105741e6e9c"

--0000000000005318e105741e6e9c
Content-Type: text/plain; charset="UTF-8"

On Sat, Aug 11, 2018 at 10:40 AM Dave Mitchell <davem@iabyn.com> wrote:

>
> 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.
>

Attached, and here in-line, is a revised proposed patch to the
documentation, about the behavior change. It might be too long, as it seems
to state everything twice.


diff -r 67f5ed179113 pod/perlop.pod
--- a/pod/perlop.pod    Mon Aug 13 11:57:05 2018 -0500
+++ b/pod/perlop.pod    Thu Aug 23 13:18:07 2018 -0500
@@ -389,6 +389,16 @@
 X<->

 Binary C<"."> concatenates two strings.
+
+As of version 5.28, a series of terms joined by  C<"."> operators are
+evaluated prior to all getting concatenated, rather than the first
+two getting joined, followed by each additional in its own binary
+operation. This affects the result when the terms return aliases that
+get modified in later terms, such as preincremented scalars. Prior to
+version 5.28, aliasing issues only affected the first term in a series
+of concatenations, as the left side of the second and later operations
+was the unaliased result of the previous binary operation.
+
 X<string, concatenation> X<concatenation>
 X<cat> X<concat> X<concatenate> X<.>


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

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

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Sat=
, Aug 11, 2018 at 10:40 AM Dave Mitchell &lt;<a href=3D"mailto:davem@iabyn.=
com">davem@iabyn.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><br>
This isn&#39;t an example of ordering of operand execution inconsistency,<b=
r>
but of fetching the results of such executions. It none the less<br>
demonstrates the danger of relying on an assumed order.<br></blockquote><di=
v><br></div><div>Attached, and here in-line, is a revised proposed patch to=
 the documentation, about the behavior change. It might be too long, as it =
seems to state everything twice.</div><div><br></div><div><br></div><div><f=
ont face=3D"monospace, monospace">diff -r 67f5ed179113 pod/perlop.pod</font=
></div><div><font face=3D"monospace, monospace">--- a/pod/perlop.pod=C2=A0 =
=C2=A0 Mon Aug 13 11:57:05 2018 -0500</font></div><div><font face=3D"monosp=
ace, monospace">+++ b/pod/perlop.pod=C2=A0 =C2=A0 Thu Aug 23 13:18:07 2018 =
-0500</font></div><div><font face=3D"monospace, monospace">@@ -389,6 +389,1=
6 @@</font></div><div><font face=3D"monospace, monospace">=C2=A0X&lt;-&gt;<=
/font></div><div><font face=3D"monospace, monospace"><br></font></div><div>=
<font face=3D"monospace, monospace">=C2=A0Binary C&lt;&quot;.&quot;&gt; con=
catenates two strings.</font></div><div><font face=3D"monospace, monospace"=
>+</font></div><div><font face=3D"monospace, monospace">+As of version 5.28=
, a series of terms joined by=C2=A0 C&lt;&quot;.&quot;&gt; operators are</f=
ont></div><div><font face=3D"monospace, monospace">+evaluated prior to all =
getting concatenated, rather than the first</font></div><div><font face=3D"=
monospace, monospace">+two getting joined, followed by each additional in i=
ts own binary</font></div><div><font face=3D"monospace, monospace">+operati=
on. This affects the result when the terms return aliases that</font></div>=
<div><font face=3D"monospace, monospace">+get modified in later terms, such=
 as preincremented scalars. Prior to</font></div><div><font face=3D"monospa=
ce, monospace">+version 5.28, aliasing issues only affected the first term =
in a series</font></div><div><font face=3D"monospace, monospace">+of concat=
enations, as the left side of the second and later operations</font></div><=
div><font face=3D"monospace, monospace">+was the unaliased result of the pr=
evious binary operation.</font></div><div><font face=3D"monospace, monospac=
e">+</font></div><div><font face=3D"monospace, monospace">=C2=A0X&lt;string=
, concatenation&gt; X&lt;concatenation&gt;</font></div><div><font face=3D"m=
onospace, monospace">=C2=A0X&lt;cat&gt; X&lt;concat&gt; X&lt;concatenate&gt=
; X&lt;.&gt;</font></div><div>=C2=A0</div></div><div><br></div>-- <br><div =
dir=3D"ltr" class=3D"gmail_signature">&quot;At this point, given the limite=
d available data, certainty about only a very small number of things can be=
 achieved.&quot; -- Plato, and others</div></div>

--0000000000005318e105741e6e9c--
--0000000000005318e605741e6e9e
Content-Type: application/octet-stream; 
	name="multiconcatdoc_dln_20180823A.patch"
Content-Disposition: attachment; 
	filename="multiconcatdoc_dln_20180823A.patch"
Content-Transfer-Encoding: base64
Content-ID: <f_jl6w8yhj0>
X-Attachment-Id: f_jl6w8yhj0

ZGlmZiAtciA2N2Y1ZWQxNzkxMTMgcG9kL3BlcmxvcC5wb2QKLS0tIGEvcG9kL3BlcmxvcC5wb2QJ
TW9uIEF1ZyAxMyAxMTo1NzowNSAyMDE4IC0wNTAwCisrKyBiL3BvZC9wZXJsb3AucG9kCVRodSBB
dWcgMjMgMTM6MTk6MDEgMjAxOCAtMDUwMApAQCAtMzg5LDYgKzM4OSwxNiBAQAogWDwtPgogCiBC
aW5hcnkgQzwiLiI+IGNvbmNhdGVuYXRlcyB0d28gc3RyaW5ncy4KKworQXMgb2YgdmVyc2lvbiA1
LjI4LCBhIHNlcmllcyBvZiB0ZXJtcyBqb2luZWQgYnkgIEM8Ii4iPiBvcGVyYXRvcnMgYXJlCitl
dmFsdWF0ZWQgcHJpb3IgdG8gYWxsIGdldHRpbmcgY29uY2F0ZW5hdGVkLCByYXRoZXIgdGhhbiB0
aGUgZmlyc3QKK3R3byBnZXR0aW5nIGpvaW5lZCwgZm9sbG93ZWQgYnkgZWFjaCBhZGRpdGlvbmFs
IGluIGl0cyBvd24gYmluYXJ5CitvcGVyYXRpb24uIFRoaXMgYWZmZWN0cyB0aGUgcmVzdWx0IHdo
ZW4gdGhlIHRlcm1zIHJldHVybiBhbGlhc2VzIHRoYXQKK2dldCBtb2RpZmllZCBpbiBsYXRlciB0
ZXJtcywgc3VjaCBhcyBwcmVpbmNyZW1lbnRlZCBzY2FsYXJzLiBQcmlvciB0bwordmVyc2lvbiA1
LjI4LCBhbGlhc2luZyBpc3N1ZXMgb25seSBhZmZlY3RlZCB0aGUgZmlyc3QgdGVybSBpbiBhIHNl
cmllcworb2YgY29uY2F0ZW5hdGlvbnMsIGFzIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIHNlY29uZCBh
bmQgbGF0ZXIgb3BlcmF0aW9ucword2FzIHRoZSB1bmFsaWFzZWQgcmVzdWx0IG9mIHRoZSBwcmV2
aW91cyBiaW5hcnkgb3BlcmF0aW9uLgorCiBYPHN0cmluZywgY29uY2F0ZW5hdGlvbj4gWDxjb25j
YXRlbmF0aW9uPgogWDxjYXQ+IFg8Y29uY2F0PiBYPGNvbmNhdGVuYXRlPiBYPC4+CiAK
--0000000000005318e605741e6e9e--
0
davidnicol
8/23/2018 6:28:17 PM
--000000000000c9a6a005741f6b69
Content-Type: text/plain; charset="UTF-8"

Made it shorter:


--- a/pod/perlop.pod    Mon Aug 13 11:57:05 2018 -0500
+++ b/pod/perlop.pod    Thu Aug 23 14:35:46 2018 -0500
@@ -389,6 +389,13 @@
 X<->

 Binary C<"."> concatenates two strings.
+
+A series of terms joined by  C<"."> operators are evaluated prior to
+all getting concatenated in a single operation.  Prior to version 5.28,
+aliasing issues only affected the value of the first term in a series
+of concatenations, as the left side of the second and later operations
+was the intermediate result of the previous binary operation.
+
 X<string, concatenation> X<concatenation>
 X<cat> X<concat> X<concatenate> X<.>


On Thu, Aug 23, 2018 at 1:29 PM David Nicol <davidnicol@gmail.com> wrote:

>
>  It might be too long, as it seems to state everything twice.
>
>

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

<div dir=3D"ltr"><div><br></div>Made it shorter:<br><div><br></div><div><di=
v><br></div><div><font face=3D"monospace, monospace">--- a/pod/perlop.pod=
=C2=A0 =C2=A0 Mon Aug 13 11:57:05 2018 -0500</font></div><div><font face=3D=
"monospace, monospace">+++ b/pod/perlop.pod=C2=A0 =C2=A0 Thu Aug 23 14:35:4=
6 2018 -0500</font></div><div><font face=3D"monospace, monospace">@@ -389,6=
 +389,13 @@</font></div><div><font face=3D"monospace, monospace">=C2=A0X&lt=
;-&gt;</font></div><div><font face=3D"monospace, monospace"><br></font></di=
v><div><font face=3D"monospace, monospace">=C2=A0Binary C&lt;&quot;.&quot;&=
gt; concatenates two strings.</font></div><div><font face=3D"monospace, mon=
ospace">+</font></div><div><font face=3D"monospace, monospace">+A series of=
 terms joined by=C2=A0 C&lt;&quot;.&quot;&gt; operators are evaluated prior=
 to</font></div><div><font face=3D"monospace, monospace">+all getting conca=
tenated in a single operation.=C2=A0 Prior to version 5.28,</font></div><di=
v><font face=3D"monospace, monospace">+aliasing issues only affected the va=
lue of the first term in a series</font></div><div><font face=3D"monospace,=
 monospace">+of concatenations, as the left side of the second and later op=
erations</font></div><div><font face=3D"monospace, monospace">+was the inte=
rmediate result of the previous binary operation.</font></div><div><font fa=
ce=3D"monospace, monospace">+</font></div><div><font face=3D"monospace, mon=
ospace">=C2=A0X&lt;string, concatenation&gt; X&lt;concatenation&gt;</font><=
/div><div><font face=3D"monospace, monospace">=C2=A0X&lt;cat&gt; X&lt;conca=
t&gt; X&lt;concatenate&gt; X&lt;.&gt;</font></div></div><div><br></div><br>=
<div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Aug 23, 2018 at 1:29 PM=
 David Nicol &lt;<a href=3D"mailto:davidnicol@gmail.com">davidnicol@gmail.c=
om</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<br><div class=3D"gmail_quote"><div>=C2=A0It might be too long, as it seems=
 to state everything twice.</div><div><br></div></div></div></blockquote></=
div></div>

--000000000000c9a6a005741f6b69--
0
davidnicol
8/23/2018 7:39:08 PM
On Thu, Aug 23, 2018 at 02:39:08PM -0500, David Nicol wrote:
>  Binary C<"."> concatenates two strings.
> +
> +A series of terms joined by  C<"."> operators are evaluated prior to
> +all getting concatenated in a single operation.  Prior to version 5.28,
> +aliasing issues only affected the value of the first term in a series
> +of concatenations, as the left side of the second and later operations
> +was the intermediate result of the previous binary operation.

What this documentation patch does, is change what was undefined
behaviour (or at least that was my feeling of where the discussion ended
up) into defined behaviour, which we are now committed to support.

I don't want the internal (and possibly changeable) details of an
optimisation to become a straight jacket.

But the actual details of the ordering are much more complicated than
implied by the text of your patch. For example in 5.28.0 onwards, which
order do you think these functions are called and the concatenations done:

    ( f1() . f2() )   .   ( f3() . f4() )

The order is actually equivalent to

    $tmp1   = f1();
    $tmp2   = f2();
    $tmp3   = f3();
    $tmp4   = f4();
    $tmp5   = $tmp3 . $tmp4;
    $result = $tmp1 . $tmp2 . $tmp5;

Would you have predicted that? Does your text describe that? Could you
come up with some text that could always describe what happens.

In conclusion, I don't think the pod for the concatenation op should
specify anything about order. I think that we should however fix the text
recently added to perlop which implied a guarantee about the ordering of
arg evaluation in general which we shouldn't have given.

-- 
"I used to be with it, but then they changed what ‘it’ was, and now what
I’m with isn’t it. And what’s ‘it’ seems weird and scary to me."
  -- Grandpa Simpson
(It will happen to you too.)
0
davem
8/24/2018 8:38:29 AM

On 08/24/2018 11:38 AM, Dave Mitchell wrote:
> On Thu, Aug 23, 2018 at 02:39:08PM -0500, David Nicol wrote:
>>  Binary C<"."> concatenates two strings.
>> +
>> +A series of terms joined by  C<"."> operators are evaluated prior to
>> +all getting concatenated in a single operation.  Prior to version 5.28,
>> +aliasing issues only affected the value of the first term in a series
>> +of concatenations, as the left side of the second and later operations
>> +was the intermediate result of the previous binary operation.
> What this documentation patch does, is change what was undefined
> behaviour (or at least that was my feeling of where the discussion ended
> up) into defined behaviour, which we are now committed to support.
>
> I don't want the internal (and possibly changeable) details of an
> optimisation to become a straight jacket.
>
> [...]
>
> In conclusion, I don't think the pod for the concatenation op should
> specify anything about order. I think that we should however fix the text
> recently added to perlop which implied a guarantee about the ordering of
> arg evaluation in general which we shouldn't have given.

The documentation could specify the lack of guarantee. That would remove
any possible ambiguity about whether it's defined or not.

"The order in which concatenated expressions is undefined and should not
be relied upon."

(Or some better phrasing.)
0
xsawyerx
8/24/2018 1:58:59 PM
Reply: