Hello folks!

recently I visited code-golf.io and i found my (terrible) 99 bottles of beer marked as broken. A lot of glass on the floor..

I tried it locally and it was correct on perl 5.24 (and 5.26) but no more on 5.28 Basically the heart of the code was:

$n=4; print $n." -- ".(--$n||'no more'),".\n" while $n; # output on perl 5.26 5.24 and before 4 -- 3. 3 -- 2. 2 -- 1. 1 -- no more. # output on perl 5.28 3 -- 3. 2 -- 2. 1 -- 1. 0 -- no more.

I tried looking in perldelta if something changed in autoincrement autodecrement between versions, but nothing.

The rule of thumb in official docs goes: This also means that modifying a variable twice in the same statement will lead to undefined behavior.

But I supposed this was not the case: I was using and modifying it, not modifying it twice.

The cloister was empty and only brother Eily was here to help (thanks) pointing me to undefined behaviour associated with some case of autodecrement.

Then I knocked the irc door where (when I finally was able to reduce the failing code to the above) the wise Grinnz bet on the issue was due to multiconcat performance enhancement. Tadąaaa!

Is not the autoincrement/autodecrement to had changed but the time where concatenation happens: infact the above code with commas behaves the same across versions:

$n=4; print $n." -- ",(--$n||'no more'),".\n" while $n; #^--- is a comma now! # output on perl 5.28 4 -- 3. 3 -- 2. 2 -- 1. 1 -- no more.

So, be aware of the above my friends! From 5.28 onward the dot can be the point!

L*

PS

the above provoked a small flame on irc but a wise named integral posted an interesting piece of code (I admit I do not understand it, but look for concat/multiconcat):

use B::Concise; sub sample { $n=4; print $n." -- ".(--$n||'no more'),".\n" while $n; } + B::Concise::compile('-exec', "sample", \&sample)->(); __DATA__ # output in perl 5.24 main::sample: 1 <;> nextstate(main -12 99bottles.pl:2) v:{ 2 <$> const[IV 4] s 3 <#> gvsv[*n] s 4 <2> sassign vKS/2 5 <;> nextstate(main -12 99bottles.pl:2) v:{ 6 <0> enter 7 <#> gvsv[*n] s 8 <|> and(other->9) K/1 9 <0> pushmark s a <#> gvsv[*n] s b <$> const[PV " -- "] s c <2> concat[t3] sK/2 d <#> gvsv[*n] s e <1> predec sK/1 f <|> or(other->g) sK/1 g <$> const[PV "no more"] s h <2> concat[t5] sKS/2 i <$> const[PV ".\n"] s j <@> print sK k <0> unstack s goto 7 l <@> leave K* m <1> leavesub[1 ref] K/REFC,1 B::Concise::compile(CODE(0x5ef428)) 1 <;> nextstate(main -12 99bottles.pl:2) v:{ 2 <$> const[IV 4] s 3 <#> gvsv[*n] s 4 <2> sassign vKS/2 5 <;> nextstate(main -12 99bottles.pl:2) v:{ 6 <0> enter 7 <#> gvsv[*n] s 8 <|> and(other->9) K/1 9 <0> pushmark s a <#> gvsv[*n] s b <$> const[PV " -- "] s c <2> concat[t3] sK/2 d <#> gvsv[*n] s e <1> predec sK/1 f <|> or(other->g) sK/1 g <$> const[PV "no more"] s h <2> concat[t5] sKS/2 i <$> const[PV ".\n"] s j <@> print sK k <0> unstack s goto 7 l <@> leave K* m <1> leavesub[1 ref] K/REFC,1 # output in 5.28 main::sample: 1 <;> nextstate(main -8 99bottles.pl:2) v:{ 2 <$> const[IV 4] s 3 <#> gvsv[*n] s 4 <2> sassign vKS/2 5 <;> nextstate(main -8 99bottles.pl:2) v:{ 6 <0> enter 7 <#> gvsv[*n] s 8 <|> and(other->9) K/1 9 <0> pushmark s a <#> gvsv[*n] s b <#> gvsv[*n] s c <1> predec sK/1 d <|> or(other->e) sK/1 e <$> const[PV "no more"] s f <+> multiconcat(" -- ",-1,4,-1)[t5] sK g <$> const[PV ".\n"] s h <@> print sK i <0> unstack s goto 7 j <@> leave K* k <1> leavesub[1 ref] K/REFC,1 B::Concise::compile(CODE(0x4fe6e0)) 1 <;> nextstate(main -8 99bottles.pl:2) v:{ 2 <$> const[IV 4] s 3 <#> gvsv[*n] s 4 <2> sassign vKS/2 5 <;> nextstate(main -8 99bottles.pl:2) v:{ 6 <0> enter 7 <#> gvsv[*n] s 8 <|> and(other->9) K/1 9 <0> pushmark s a <#> gvsv[*n] s b <#> gvsv[*n] s c <1> predec sK/1 d <|> or(other->e) sK/1 e <$> const[PV "no more"] s f <+> multiconcat(" -- ",-1,4,-1)[t5] sK g <$> const[PV ".\n"] s h <@> print sK i <0> unstack s goto 7 j <@> leave K* k <1> leavesub[1 ref] K/REFC,1

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

In reply to I crashed 99 bottles.. the dot was the point (multiconcat) by Discipulus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.