Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Hard syntax error or disambiguable parsing?

by merlyn (Sage)
on Jan 29, 2009 at 03:18 UTC ( #739752=note: print w/replies, xml ) Need Help??


in reply to Hard syntax error or disambiguable parsing?

A foreach loop (which you've written there misspelled as "for") absolutely wants to create a new local scalar variable to refer to each of the items of the list. You can't make this part of a larger existing structure... it doesn't make sense.
  • Comment on Re: Hard syntax error or disambiguable parsing?

Replies are listed 'Best First'.
Re^2: Hard syntax error or disambiguable parsing?
by ikegami (Pope) on Jan 29, 2009 at 07:30 UTC

    A foreach loop (which you've written there misspelled as "for")

    eh? Not only are the keywords interchangeable, but for $i ( 0 .. 5 ) is not a foreach loop as defined in perlsyn. It shares traits with both foreach loops (syntax) and for loops (purpose and efficiency).

    It's not as clear, and this is clearly a beginner, so I thought I'd bring clarity back.

    So how do you decide which keywords to use? Choosing the keyword based on syntax (looks like a list or not) is redundant. The only meaningful criteria I can think of are memory efficiency (you'd use for here) or purpose (you'd use for here).

      but for $i ( 0 .. 5 ) is not a foreach loop as defined in perlsyn.

      It's good to know that someone else around here actually reads the docs--and arrives at the same interpretation as me.

      Personally, the whole 'unavoidable implicit localisation' of for loop variables smacks of an accidental implementation bug that got post-facto ligitimisation via Marketeer Maintainenance: The re-branding of bugs as features.

      There doesn't seem to be any logical reason why an existing variable shouldn't be used (unlocalised) as the loop iterator, given that if a strictly loop scoped iterator is required, the inline-my version achieves that perfectly.

      This would allow several common uses that currently require extra steps to achieve. For example, retaining the information of how far the loop iterated if it is terminated early via last, that currently requires an extra variable and another assignment.

      If this was an explicit decision--rather than an accidental happenstance as suggested by some of the comments in the source files--then it would be good to see the reasons laid out.


      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.
        Personally, the whole 'unavoidable implicit localisation' of for loop variables smacks of an accidental implementation bug that got post-facto ligitimisation via Marketeer Maintainenance: The re-branding of bugs as features.
        Indeed. The original designer of Perl ought to have repented long ago and designed a better language as penance. :-)

        When I look at this whole discussion, I see:

        Perl 5: A loop variable is defined as BLAH BLAH BLAH BLAH BLAH BLAH BLAH BLAH BLAH BLAH BLAH BLAH except when BLAH BLAH BLAH BLAH BLAH BLAH BLAH BLAH except nowadays you should really BLAH BLAH BLAH BLAH no it isn't yes it is no it isn't BLAH BLAH BLAH BLAH BLAH BLAH BLAH BLAH...

        Perl 6: A loop variable is simply a formal parameter to a block.

      for $i ( 0 .. 5 ) is not a foreach loop

      May I ask you in what way

      for $i ( 0 .. 5 )
      and
      foreach $i ( 0 .. 5 )
      differ, according to your opinion? perlsyn says The "foreach" keyword is actually a synonym for the "for" keyword, so I don't see how you came to the idea that the for loop your mention, would not be a foreach loop. Did I miss something here?

      -- 
      Ronald Fischer <ynnor@mm.st>

        Did I miss something here?

        You probably think the ".." in "for[each] $i ( 0 .. 5 )" is the range operator and that it creates a list of 6 elements. It's not, and no list of 6 elements is created.

        perlsyn distinguishes between For Loops ("C"-style For Loops) and Foreach Loops (List Iteration Loops), but "for[each] $i ( 0 .. 5 )" is neither. It's actually a Counting Loop like FOR ... NEXT in BASIC.

Re^2: Hard syntax error or disambiguable parsing?
by rovf (Priest) on Jan 29, 2009 at 08:50 UTC
    A foreach loop absolutely wants to create a new local scalar variable

    Somehow I forgot about the scoping rules within foreach, so I reread perlsyn:

    The "foreach" loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. If the variable is preceded with the keyword "my", then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with "my", it uses that variable instead of the global one, but it's still localized to the loop.

    If I understand this right, we have 4 cases:

    { foreach my $v (...) {} } # 1 { foreach $v (...) {} } # 2 { my $v; foreach $v (...) {} } # 3 { my $v; foreach my $v (...) {} } # 4
    In case 1, $v is a lexical variable where the lifetime ends with the end of the loop. In case 2, $v is in the global symbol table, but localized, in the sense we usually get by local $v;; the localization ends at the end of the loop. As for case 3, I don't really understand the text of the man page; what does localizing a lexical variable mean? As for case 4, the man page doesn't say anything explicitly, so it must be in effect the same as case 1.

    Is this correct, and could you please give some explication about case 3?

    -- 
    Ronald Fischer <ynnor@mm.st>

      Case 4 is in fact identical to case 3, since $v in both cases is already a 'my' variable, subject to lexical scoping.

        Case 4 is in fact identical to case 3, since $v in both cases is already a 'my' variable, subject to lexical scoping.

        That doesn't make sense to me. If anything, if I understand the documentation, Case 2 and 3 are almost identical and Cases 1 and 4 are almost identical.

        In Cases 1 and 2, there is no indication about whether the outer, enclosing scope (outside of the scope of the foreach loop) there is any variable $v wandering around. Since it is not shown, I would presume that the intent is that no such varible exists in exterior scope(s). And I'm not sure that it really matters, in the context of what I'm thinking.

        But, if I understand the documentation, in Cases 1 and 4, the use of my in the creation of the loop variable results in a lexically scoped variable and it never appears in any package symbol table.

        However, in the situations in Cases 2 and 3, the loop variable is created as if it were created with a local construct. In which case the $v exists in the package symbol table, but a copy is created and used within the scope of the loop and the original value of $v is not touched. At the end of the loop's scope, the original value of $v is restored to the variable in the package symbol table.

        So the difference, it seems to me, is whether the package symbol table's variables (symbols?) are used or a new, unseen (by the package symbol table) variable (symbol?) are created for the duration of the loop's scope.

        For me, that would seem to make Cases 2 & 3 almost identical and Cases 1 & 4 almost identical.

        But then, I'm still learning and could be wrong.

        ack Albuquerque, NM

      Yet again I learn...and I even read the documentation (I even went back and read what I thought was the full description of this construct). But clearly I did not.

      rovf's extract actually reminded me of what I had learned for what seems like a long time ago...the difference between my and local in the context of the loop variable. And it is the local at work that made my test code (listed in an earlier thread on this inquiry)...not because, as I mis-stated, the loop variable is automatically lexically scoped (ala, my or an implicit my).

      Thanks, rovf. Maybe someday I'll be able to keep more of Perl's wonderments straight in my mind.

      ack Albuquerque, NM
Re^2: Hard syntax error or disambiguable parsing?
by BrowserUk (Pope) on Jan 29, 2009 at 03:28 UTC
      Sure, the words are interchangable, in the same way that you can omit $_ a lot. It's not as clear, and this is clearly a beginner, so I thought I'd bring clarity back.

      As for the second statement, I don't understand your complaint. The first loop does indeed create a new local scalar variable, as I said.

        It doesn't reuse the one created in the above line my $i;? Or do you mean uninitialized, rather than previously undeclared. Either way, why does a scalar member of an array not qualify?

        for(split(" ","tsuJ rehtonA lreP rekcaH")){print reverse . " "}print "\b.\n";
        I for one applaud your statement about clarity! I see a lot of code on Monks that uses obscure features of Perl when they aren't necessary.

        I also see a massive fascination with $#list. I don't understand why that is! The scalar value of @list does everything I need.

        One of the magic things about Perl is the ability to iterate over a list without knowing or caring about the "last index" or how many things are even in the list!

        I always use foreach(@list){} instead of for(@list){}. A "C" style "for loop" is a rare duck in Perl (although seldom doesn't mean never). Even though "for" and "foreach" are equivalent in this case, foreach my $variable (@list){} is more clear. HORRAY!

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (8)
As of 2021-01-27 20:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?