in reply to Re: for loop localisation bug?
in thread for loop localisation bug?

I find calling something broken before you even know the reason to be.. daring to say the least.

If it were "fixed", a number of things we're used to doing with the aliasing property of foreach such as s/foo/bar/ for @array; would cease to work. Frankly I wouldn't have it another way - more than a few times have I found the persisting iteration variable value behaviour of FOR loops in Pascal and C annoying, and more than a few times have I found the aliasing behaviour of Perl's foreach useful.

If you need the value, then just do manually what Perl avoids to: copy it to a variable from the surrounding scope on each iteration.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re^2: for loop localisation bug?
by BrowserUk (Patriarch) on Dec 29, 2003 at 18:35 UTC

    Fair enough. My choice of the word broken, even when expressed only as 'my opinion', was probably rash.

    I should have said, unintuative, unhelpful or (as I did) Doing What I Didn't Mean.

    By using a predeclared variable as the loop counter, I am explicitly attempting to retain the exit value of loop counter. This behaviour is implicitly overriding that attempt -- in order to provide a behaviour that is available to me explicitly, by declaring the loop variable within the for loop construct for my $n ( ... ) -- and hence not doing what I mean.

    I understand, utilise, and admire the design of the aliasing done by the for loop, and I agree with you that it is a useful feature that is DWIM in most instances. The fact that I couldn't explicitly override it when I tried to, took me by surprise, and (still) leaves me wishing that I could.

    I guess that this is a throwover from pre-lexical days rather than an explicitly sought-after design feature. Then, someone will pop up and tell me that I guess wrong:)

    In any case, I didn't mean to indicate that it should be fixed at this late stage, just that I would prefer that implicit behaviours would take a back seat to explicit behaviours. In most cases, perl gets that right (IMO), but in this instance, probably as a matter of history, I think it gets this wrong.

    No biggy, just an embarrased reaction to an implicit behaviour (that I had never before encountered) overriding my explicit attempt to define WIM. Despite reducing the problem to it's simplest in a test script and spending half an hour staring at it to see what I was doing wrong, it turned out to be "user error".

    I didn't even consider looking it up, because based upon both my intuition, and experience of other languages, the behaviour I was seeing "couldn't possibly be correct". The fact that it is documented as working this way means it is 'correct', but I would never have guessed that it would be so.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

      Don't worry you are not alone in being caught by this, see (s)coping with foreach :-)

      --
      Do not seek to follow in the footsteps of the wise. Seek what they sought. -Basho

      I am explicitly attempting to retain the exit value of loop counter. This behaviour is implicitly overriding that attempt -- in order to provide a behaviour that is available to me explicitly, by declaring the loop variable within the for loop construct for my $n ( ... )

      [ ... ]

      I would prefer that implicit behaviours would take a back seat to explicit behaviours. In most cases, perl gets that right (IMO), but in this instance, probably as a matter of history, I think it gets this wrong.

      You're confusing implicit and explicit behaviours. foreach is an explicit aliasing construct and never behaves any differently.

      This is a conscious design decision. It's not going to change come Perl 6 either. Aliasing is not reasonably feasible if you want to retain the value past the loop, unless you're willing to introduce convoluted semantics about when the value retained is a copy and when it is still an alias. Your proposed semantics would therefor have to be implemented as something along the lines of "aliasing when my, copying when absent". Of course that would require some extra special case treatment of $_.

      I'd prefer simply having foreach be consistent with itself even if there wasn't a lot of legacy code to cater for. So I'll say that Perl got this one right.

      Makeshifts last the longest.

      This is a real issue that bites people from time to time, and it seems to me that it could be fixed with a minor extension of syntax to specify that a foreach loop should not do aliasing. Of course, it can also be addressed by a little code (and awareness):
      my $n; # Going to set this for my $a (1..100) { if ($a == 50) { $n = $a; last; } } # $n is 50
      The advantage to new syntax would be that it promotes awareness of the two non-compatible WIMs. It could also have the ever-so-slight advantage of reducing the number of variables declared. I've thought of three possible syntax extensions:
      1. An alias pragma, on by default:
        no alias; for $n (1..100)
      2. The addition of an equals sign to indicate that each element is assigned, rather than aliased:
        for $n = (1..100)
      3. Using a ref to a scalar var instead of a scalar var to indicate non-localization:
        for \$n (1..100)
      None of these would affect existing code (unless there's already an alias module/pragma of which I'm unaware).

      The PerlMonk tr/// Advocate
Re^2: for loop localisation bug?
by SavannahLion (Pilgrim) on Dec 29, 2003 at 18:28 UTC
    Frankly I wouldn't have it another way - more than a few times have I found the persisting iteration variable value behaviour of FOR loops in Pascal and C annoying, and more than a few times have I found the aliasing behaviour of Perl's foreach useful.

    Just to throw my two pennies in on this one. I feel that that's merely the, "feature set," of the different languages. There are different instances where I would rather have the iteration variable persist and other times where I don't want it to persist.

    I guess what I'm saying is that not every language can meet the needs of every situation nor make every developer happy. I can't vouch for anyone else, but that's why I have so many different languages installed. Different tools for different needs.

    ----
    Is it fair to stick a link to my site here?

    Thanks for you patience.