Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Re: For loop problem

by srawls (Friar)
on Jun 03, 2001 at 22:56 UTC ( #85354=note: print w/ replies, xml ) Need Help??


in reply to Re: For loop problem
in thread For loop problem

Ok, thanks bikeNomad, that does make sense. What I'm still confused at, though, is how the interperter decides the order it evaluates in. Here are a few test cases:

for(++$....$..$.)
When I use this is evaluates the left side first, and cycles through 1 to 11.
for(++$....$.++.$.)
But as soon as I add that second ++, it evaluates the right side first, and cyles through 2 to 12.
for(++$....$..++$.)
And this is perhaps the strangest of them all. It evaluates the right side of the ...(flip flop) operator first, and also evaluates the right side of the . (concatanation) operator first. It cycles through 2 to 22.

The 15 year old, freshman programmer,
Stephen Rawls


Comment on Re: Re: For loop problem
Select or Download Code
Re: Re: Re: For loop problem
by japhy (Canon) on Jun 03, 2001 at 23:19 UTC
    The problem is that the list ($a .. ++$a) is not evaluating a list like you think it is. It is not doing:
    $start = $a; $end = ++$a; for ($_ = $start; $_ <= $end; $_++) { ... }
    But rather, it is evaluating its endpoints, and then constructing the list from that. That is the cause of your problem:
    for (++$x .. $x++ . $x) { ... } # starting at ++$x # ending at $x++ . $x # THE END HAS MODIFIED THE START
    You can witness a similar result from:
    print ++$x, ++$x, ++$x; # 333
    You see, the arguments to a function aren't copies of the variables, but rather aliases -- by modifying ONE of the $x's, you've modified the others as well.

    Knowing this, the output of this program makes sense to me:

    $x = 3; print ++$x/$x--; # 3/4 => 0.75
    Why is that? Well, the numerator is ++$x, and the denominator is $x--; but in subtracting 1 from $x in the denominator, we have now altered the numerator back to its original state!

    I've worked out a solution to your 1 .. 12 loop, then.

    for (++$x .. $x++ . $x--) { ... } # or for (++$....$.++.$.--) { ... }
    See if you can work out why the starting point is 1.

    japhy -- Perl and Regex Hacker
      print ++$x, ++$x, ++$x; #333 print ++$x, $x++, ++$x; #313

      Given a left to right evaluation, to me this should produce 123 and 113 respectively.

      "You see, the arguments to a function aren't copies of the variables, but rather aliases -- by modifying ONE of the $x's, you've modified the others as well"

      I can accept that but what about this:
      my $x=3; print $x, $x=5, ++$x, $x--, $x, $x++, $x=0; #0006050 print $x++, $x=5, ++$x, $x--, $x, $x++, $x=0; #3006050

      Again, 3566550 seems the reasonable output (to me) for both accounts. Instead the post-(in|de)crement operators seem to be squireling away their value of $x when it came by them in a left to right evaluation of the terms.

      I can see the pattern and work with it, my question is why is it that way? What are the advantages to this type of evaluation? I don't know enough Perl to extrapolate the reasoning behind them.

      As one final example consider:
      $x = 3; print ++$x/$x--;

      Coming into the function x is 3, it gets pre-incremented (now 4), it's divided by x (still 4), x is post-decremented (to 3). Print outputs 1 (4/4) and x leaving the function is 3. This is how it _should_ happen to my mind, instead it's 3/4 as stated earlier.

      Maybe it's just my logic that's skewed or I'm showing a glaring flaw in my understanding of how operations need to work internally, but it seems rather convoluted for no good reason.

      -- I seek enlightenment
        Instead the post-(in|de)crement operators seem to be squireling away their value of $x when it came by them in a left to right evaluation of the terms.
        Post-increment and -decrement have to squirrel away their value of $x, because they change the value of $x in place but return the previous value.

        Pre-increment and -decrement, on the other hand, change the value of $x in place and then return the new value. Returning a pointer to the location of $x, rather than to a copy of the value in $x, is an optimization.

        $x = 3; print ++$x/$x--;
        Coming into the function x is 3, it gets pre-incremented (now 4), it's divided by x (still 4), x is post-decremented (to 3). Print outputs 1 (4/4) and x leaving the function is 3. This is how it _should_ happen to my mind, instead it's 3/4 as stated earlier.
        You appear to have the order of evaluation all wrong. The operands to /, this case ++$x and $x--, must both be evaluated before the division. What you describe sounds more like: (++$x/$x)--
        except, of course, that it's a syntax error.

        By the way, you'll see the same results with other operations that modify variables in place, such as +=. print $x, $x += 1;
        Creating a separate copy of every value in every variable, to prevent such effects, would cost a lot in execution time and memory usage. It could also get very complicated with constructions like this: print +(($x+=1)+=1) + ($x+=$x++);

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://85354]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (5)
As of 2014-09-15 02:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (145 votes), past polls