Because long, long ago, in a land far away, the designer's of a language wrote in their specification:

The precedence and associativity of all the expression operators is summarised in section 18. Otherwise, the order of evaluations of expressions is undefined. In particular the compiler considers itself(*) free to compute sub-expressions in the order it believes(*) most efficient, even if the sub-expressions involve side effects. The order in which side effects take place is unspecified. Expressions involving a commutative and associative operator (*, +, &, |, ^) may be rearranged arbitrarily, even in the presence of parentheses; to force a particular order of evaluation, an explicit temporary must be used.

(*) Who knew they had sentient software way back then :)

Essentially, the designers of the C language traded source code ambiguity, programmer intuition, and program correctness, for performance.

Instead of allowing the programmer to specify exactly the order in which sub-expressions would be executed--through the intuitive use of parentheses and precedence, rather than clumsy hack of creating unnecessary temporary variables--they opted to allow compiler writers to re-order those sub-expressions "for efficiency".

Perhaps the most short-sighted and pervasive premature optimisation ever.

In the days when cpu clock speeds were measured in low megahertz and single opcodes could take dozens of those clock cycles to perform; in a language that was explicitly designed to compiled directly to machine code; such optimisations could have a significant impact on program performance. So programmers would tolerate such inconveniences, for the gains that could be achieved.

Now, it is arguable that the trade-off no longer makes sense: when you have processors with speeds measured in Gigahertz executing multiple instruction per clock cycle; in a language were even the simplest of sub-expressions takes dozens if not hundreds of op-codes. The scope for performance optimisation through the reordering of sub-expressions is essentially non-existent.

But, for better or worse, Perl apes many of the rules laid down by the C language. In part I believe, because it made things easier for C programmers moving to Perl. So, we have the situation whereby the order of sub-expression evaluation is "unspecified", meaning that you cannot predict the result of using two or more side-effectful operations on a single variable within the same expression, on the basis of the language description alone.

It also means that when ambiguities arise in the implementation, such as the one you describe, you cannot point a finger and called it a bug, because "the behaviour is unspecified". You'll simply be told: "Don't do that!".

The fact that there is no logical reason, performance or otherwise, for having pre- and post-increment operate differently in this regard:

$n=0; print ++$n, ++$n, ++$n, ++$n;; 4 4 4 4 $n=0; print $n++, $n++, $n++, $n++;; 0 1 2 3

is simply dismissed as user error. "Because you shouldn't be doing it anyway!".

One day, someone will see through these hoary ol' chestnuts of programming lore, and define a language that allows the programmer to write source code that specifies exactly what he wants to happen, and know it will happen. Without having to recourse to inventing unnameable intermediary variables for no good reason.

Till then, you'll just have to get used to not using two or more side-effectful operators, on the same variable, within the same statement. {shrug}


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP an inspiration; A true Folk's Guy

In reply to Re: Pre vs Post Incrementing variables by BrowserUk
in thread Pre vs Post Incrementing variables by SavannahLion

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.