in reply to $i=$i++

You have to understand how expressions evaluate. The pre- and post-increment (and decrement) operators change the variables value, but the variable plus the operator constitute and expression who's value varies depending upon the placement of the ++. Essentially, the value of the expression $i++ is original value of $i and $i is incremented by 1. The value of the expression ++$i is new value of $i after $i is incremented by 1.

$i = ++$i + $i++;

In the above example, we evaluate the expression right to left. The expression, $i++, evaluates as zero, even though $i is now 1. The second expression, ++$i, evaluates as 2 (since $i is now 1) and 2+1 equals 3.

$i = $i++ + ++$i;

Pretty straightforward now. The rightmost ++$i evaluates as 1 and $i is set to one. The $i++ also evaluates to 1 (remember, with a post-increment operator doesn't change the return value of the expression, just the variable -- confused yet? :). So, 1 + 1 equals two.

Cheers,
Ovid

Update: Got the concept right, but I evaluated in reverse order. Whoops! Juerd is right.

Update2: Okay, I'm smoking crack. If things are evaluated left to right, then the following is true:

$ perl -e 'print 1-3+2' 0

Well, it turns out that this is true. If it were evaluated right to left, then the answer would negative four. What I think is going on (though I can't prove it offhand) is that built-in unary operators are evaluated right to left, and then the rest of the expression is evaluated based upon precedence rules, if any. Anyone want to shed light on this?

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Replies are listed 'Best First'.
Re: Re: $i=$i++
by Juerd (Abbot) on Apr 29, 2002 at 15:50 UTC

    In the above example, we evaluate the expression right to left.

    Is that always, or just in this case? When are expressions evaluated left-to-right, and when right-to-left? And why is that so? I would have thought that do { $i = 0; ++$i + $i++; } would evaluate to 2 because (0 + 1) + 1 == 2, but apparently, I'm wrong.

    Update: Got the concept right, but I evaluated in reverse order. Whoops! Juerd is right.

    Answer to Ovid's update: No, I'm not, as do { $i = 0; ++$i + $i++ } does NOT equal 2 -- the right-to-left apparently is correct, I'm just wondering why it is that way.

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

Re: Re: $i=$i++
by Juerd (Abbot) on Apr 29, 2002 at 17:04 UTC

    If it were evaluated right to left, then the answer would negative four

    No, it's a per-operator thing, as + and - are different operators, and their precedence defines they should be evaluated left-to-right. This is done by implicit parentheses:

    2;0 juerd@ouranos:~$ perl -MO=Deparse,-p -e'sub one { 1 } sub two { 2 +} sub three { 3 } print one() - three() + two()' sub one { 1; } sub two { 2; } sub three { 3; } print(((one() - three()) + two()));
    (I had to use these subs, because Perl optimizes 1-2+3 to a literal 0 :)

    So we have these calculation:
    1. 1 - 3 = -2
    2. answer ( = -2 ) + 2 = 0
    But which are evaluated first? the 1 or the 3? The -2 or the 2? It becomes clear when you test the operators one by one (or so I thought):
    2;0 juerd@ouranos:~$ perl -le'sub foo { print "foo"; return 1 } sub ba +r { print "bar"; return 2 } print foo + bar' bar foo 1 2;0 juerd@ouranos:~$ perl -le'sub foo { print "foo"; return 1 } sub ba +r { print "bar"; return 2 } print foo && bar' foo bar 2
    So I decided to test a lot of operator this way, but found out that everything was evaluated left-to-right, but not if I left out the parens. Why did my first test print bar before foo then? Because I didn't print foo() + bar() but did print foo( +bar() ).

    So that still doesn't solve our mistery...

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.