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

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!

Replies are listed 'Best First'.
Re: Re: Re^2: for loop localisation bug?
by greenFox (Vicar) on Dec 30, 2003 at 11:27 UTC
    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

Re^4: for loop localisation bug?
by Aristotle (Chancellor) on Dec 30, 2003 at 13:27 UTC
    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.

Re^2^2: for loop localisation bug?
by Roy Johnson (Monsignor) on Dec 30, 2003 at 16:30 UTC
    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