in reply to Re^6: Pre vs Post Incrementing variables
in thread Pre vs Post Incrementing variables

Because I know something by another name

That doesn't wash either.

  1. In this: f( 1 , 2 );, The constants 1 & 2 are the operands of the comma operator.
  2. But in this: f( 1+2 , 3+4 ),

    the operands of the comma operator are the results of the subexpressions: 1+2 and 3+4.

    Ie. The operands of the comma operator are the values 3 & 7.

By analogy, in this: f( ++$n , ++$n ), the operands of the comma operator should be the results of the preincrement subexpressions.

Not two references to $n after both sub-expressions have been evaluated.

As for your ploy of resorting to meta-argument to distract from the argument, I'm going to ignore it this time, just like I did last time. And the time before...


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

Replies are listed 'Best First'.
Re^8: Pre vs Post Incrementing variables
by ikegami (Patriarch) on Sep 13, 2010 at 07:54 UTC

    the operands of the comma operator should be the results of the preincrement subexpressions.

    Correct. And it does. For good or bad, the result of preincrement is the variable that was incremented. We've covered that you wish it wasn't. I don't disagree.

    Not two references to $n after both sub-expressions have been evaluated.

    Correct. It doesn't. It returns $n after the first preincrement has been evaluated and $n after the second preincrement has been evaluated. Like I said earlier, the evaluation order is already what you would expect it to be.

    use 5.010; # say use Data::Alias; sub f { say @_; } $n=3; f(++$n, 0+$n, ++$n); $n=3; do { local @_; alias $_[0] = ++$n; alias $_[1] = 0+$n; alias $_[2] = ++$n; &f; };
    545 545

    As for your ploy of resorting to meta-argument to distract from the argument

    "You think that you know better what the authors of that passage meant when they wrote it, than they did." is not an argument.

    Update: Improved example.

      "You think that you know better what the authors of that passage meant when they wrote it, than they did." is not an argument.

      Oh, but it so is.

      Having already attempted to point out the significant difference between your "operand evaluation order"--which appears nowhere in either the quoted passage, nor elsewhere in the post; and the phrase "the order of evaluations of expressions"--which does; and having attempted to give you the benefit if the doubt.

      I had to conclude, that your conflation of the two terms was not accidental, but rather, knowing and deliberate. At which point, my conclusion was not "slander", but rather 'paraphrase'.

      You said it; in the face of my clear attempt at clarification, you repeated it. I paraphrased you. That isn't "slander", it is fact. Slander has to be false.

      Slander also has to be spoken. If it's written, it becomes libel, but it still has to be false, but your conflation of two entirely different terms, was palpable; obvious. My conclusion, unavoidable.

      And your confusion, deliberate or otherwise, continues.

      You appear to be trying to make a distinction, between:

      two references to $n after both sub-expressions have been evaluated.

      And:

      Correct. It doesn't. It returns $n after the first preincrement has been evaluated and $n after the second preincrement has been evaluated.

      But, $n_after_the_first_increment would be different, by 1, to $n_after_the_second_increment, but your own output--in both the relevant case and your two fantasy cases--shows both digits are the same.

      And the only way for that to happen, is for both pre-increments to have occurred, before the subroutine gets whatever it is given. And that is self-evidently wrong, sub-expression evaluation order specified or not.

      But...(I can see you clasping your hands together in triumph)... if sub-expression evaluation order was specified, then there is no way possible that the current behaviour could be excused under the "Don't use 2 or more side-effectful operations on a single variable, within a single expression" missive.

      In other words, in the hope that it will penetrate this time. If the excuse of "unspecified order of sub-expression evaluation" had never existed, then the current behaviour would have been recognised a bug the moment it was implemented.

      And one more try.

      If the order of evaluation of sub-expressions was defined--whether left to right, right to left, or in the most obvious order of respecting both precedence and parentheses--then the current implementation of passing lvalue references to the target (operand) of sub-expression operations--rather than the results produced by those sub-expressions--would have stood as an indefensible bug long ago.


      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.

        But, $n_after_the_first_increment would be different, by 1, to $n_after_the_second_increment, but your own output--in both the relevant case and your two fantasy cases--shows both digits are the same.

        It returns $n (the scalar, not the value within) after first increment, not some copy $n_after_the_first_increment after the first increment.

        And the only way for that to happen, is for both pre-increments to have occurred, before the subroutine gets whatever it is given.

        You are mistaken. The first result in placed on the stack before the second is evaluated. See the code in the grandparent.

        Correct. It doesn't. It returns $n after the first preincrement has been evaluated and $n after the second preincrement has been evaluated.
        But, $n_after_the_first_increment would be different, by 1, to $n_after_the_second_increment, but your own output--in both the relevant case and your two fantasy cases--shows both digits are the same.
        Uhm, there's only one variable here, $n. Note that $n is returned, not "the value of $n". Preincrement ++ behaves just like += 1 in this respect.

        Having already attempted to point out the significant difference between your "operand evaluation order

        The only post between my first use of the term and your slander is Re^3: Pre vs Post Incrementing variables, but it indentifies no differences. Did you forget to post them? If I'm misusing the term, I'll be glad to correct myself.

Re^8: Pre vs Post Incrementing variables
by JavaFan (Canon) on Sep 13, 2010 at 08:45 UTC
    By analogy, in this: f( ++$n , ++$n ), the operands of the comma operator should be the results of the preincrement subexpressions.
    By the same logic in f($n) f should be passed the result (value) of $n, disallowing f from modifying $n.

    Perl doesn't work that way.

      By the same logic in f($n) f should be passed the result (value) of $n, disallowing f from modifying $n.

      Not so.

      If I pass variables to a function, then I expect to get reference to those variables:

      $n = 1; $m = 2; print \$n, \$m;; SCALAR(0x3d3cf08) SCALAR(0x3e12508) sub { print \$_[0], \$_[1] }->( $n, $m );; SCALAR(0x3d3cf08) SCALAR(0x3e12508)

      But, if I pass sub-expressions to a function, I expect to get references to (temporary) variables containing the results of those sub-expressions. And in most cases that's exactly what I get:

      sub { print \$_[0], \$_[1] }->( $n+1, $m+1 );; SCALAR(0x3cc86d0) SCALAR(0x3d3f320)

      I can even mutate those references to results without error:

      [0] Perl> sub { print \$_[0], \$_[1]; +$_++ for @_ }->( $n+1, $m+1 );; SCALAR(0x3cc86d0) SCALAR(0x3d3f320) 2 3

      but, and here is the significant point, those mutations do not modify the variable involved in the sub-expressions from which those results were derived:

      print $n, $m;; 1 2

      It is only in the case of pre-increment expressions (and a few other similar anomalies), that the function receives a reference to the target of the sub-expression, rather than a reference to the result of it.

      And the clincher that this is a bug, rather than an implementation specific optimisation allowable within the rules of the language definition, is that there is no good use for it.

      The justification for many of the anomalies that exist in Perl, is that there are one or more very common cases where the anomalous behaviour is useful, Because it allows the capture, within a concise idiom, a piece of behaviour that is sufficiently commonplace to warrent it. This has no such justification.


      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.
        The justification for many of the anomalies that exist in Perl, is that there are one or more very common cases where the anomalous behaviour is useful, Because it allows the capture, within a concise idiom, a piece of behaviour that is sufficiently commonplace to warrent it. This has no such justification.

        Well, it might be a common golf case :-D

        perlop states

        Terms and List Operators (Leftward)
        A TERM has the highest precedence in Perl. They include variables, quote and quote-like operators, any expression in parentheses, and any function whose arguments are parenthesized. Actually, there aren’t really functions in this sense, just list operators and unary operators behaving as functions because you put parentheses around the arguments.

        If that statement was correct, then in the case of sub { }->(++$c, $c++) pre- and postincrement would conflate to simple increments of the variable after the sub returned, since -- and ++ have lower precedence than TERM according to the docs, no matter whether pre or post.

        But for arguments to a sub call, pre-increment seems to mean "increment before sub call" ($var done, can be passed as alias), postincrement "increment after sub call" ($var must be retained for ++, copy is passed) - which, while intuitive, isn't documented anywhere afaics.

        But then, one could argue that

        perl -E '$c=1; sub{$_[0]+=5}->($c++);say $c'

        should yield 7 instead of 2. Ah, well... ;-)

        But, if I pass sub-expressions to a function, I expect to get references to (temporary) variables containing the results of those sub-expressions.
        Then your expectation is wrong. Perl doesn't guarantee this. And if you want a regular language, Perl isn't for you.
        It is only in the case of pre-increment expressions (and a few other similar anomalies), that the function receives a reference to the target of the sub-expression, rather than a reference to the result of it.
        Yeah. It's called lvalues. Just labelling them anomalies doesn't make them bugs. As I said, if you want a regular language, don't use Perl.
        And the clincher that this is a bug
        And the ID of your bug report is?
        This has no such justification.
        The justification is optimization. (Just as the orginal reason for C). Not in keystrokes, but in execution. Here the optimization is that by returning an alias, it saves creating a new SV. If you don't want the alias, create a copy.