in reply to Doing "it" only once

Is it me, or wouldn't

while ( <FH> ) { last if $_ eq 'foo'; # Where foo can only appear once in the file print; } while ( <FH> ) { print; }

do the trick? (in this situation, of course)

Replies are listed 'Best First'.
Re^2: Doing "it" only once
by Limbic~Region (Chancellor) on Sep 21, 2005 at 15:22 UTC
    cog,
    Yes of course, in this situation. The reason it works is because file handles are iterators remembering where they left off and because our condition was simple. There are far more situations in which it wouldn't work so the meditation is on the idea of dynamically splicing in code blocks while code is running and what neat things might you do if the functionality existed without heavy penalties.

    Cheers - L~R

      Eh, I've a hard time believe there exists a situation where it [statically splicing the code, as in cog's solution] wouldn't work, but where it's still possible to dynamically splicing in code blocks while code is running.

      Could you give an example of such code?

      BTW, what you are asking for is a special case of "loop enlightment", and cog's solution is the standard way of solving this. It belongs in Programming 102.

        Anonymous Monk,
        No, what I am asking for is not a special case of "loop enlightment". What I am asking for is for people to consider what they would do if they had the ability to modify the optree (or the p6 equivalent) while the code is running.

        To answer you code question - consider the following trivial example:

        for ( @some_array ) { if ( $_ eq 'foo' ) { print "skipping foo\n"; next; } if ( $_ eq 'bar' ) { handle_bar($_); next; } handle_rest($_); }
        To re-write this we need to first change
        for ( @some_array ) { ... } # to my $index = -1; while ( ++$index <= $#some_array ) { ... }
        So that when we break out of the first loop to enter the second, we can remember where we left off. Unfortunately, the order that we will encounter 'foo' and 'bar' is unknown so we also have to create a flag variable and end up with 4 while loops instead of the original 1: This was a translation of a very simple example. I do not if there is any case where it would be impossible to do, but it certainly isn't easy. Again, the point of the medidation is to just take the functionality as a given for a second and think about what you would do with it.

        Cheers - L~R

Re^2: Doing "it" only once
by blazar (Canon) on Sep 22, 2005 at 10:35 UTC
    Indeed there are not unexpectedly many WTDI. As the author of the original post in p6l, I must say that Limbic~Region is one of the few that seem to have authentically understood the real point of the issue and in his much better phrasing than mine it all boils down to the hypothetical possibility of modifying the optree at runtime.

    Now, BrowserUK informed us here that this kind of code self-modification was very common in early languages, but also regarded as a horror, which is one of the reasons that led to structured programming and later to OO programming, etc. OTOH it has become common again, in FP languages, as a compiler optimization.

    But then it's hard to think that in such a dynamic and multi-paradigmatic language like Perl, be it 5 or 6, something exactly along these lines could be done. So my question, in the context of Perl6, regarded the possibility to do so by means of some syntactic sugar visually distinctive enough to avoid an unintentional use of it and to make clear what that the one using it wants and at the same time cheap enough, type-wise, to make it preferable over any of the already proposed alternatives.

    Now, wrt you code above:

    while ( <FH> ) { last if $_ eq 'foo'; # Where foo can only appear once in the file print; } while ( <FH> ) { print; }
    it obviously looks nice enough and it makes clear why you're doing so. But it's still nearly double the code that one conceptually could want. Not only: if print were really a longer portion of code, you may {want,need} to refactor it into a sub, with the added overhead of a sub call (and here we're being -for once- really paranoid 'bout efficiency and micro-optimizations), which would not have been necessary at all if we had that kind of syntactic sugar...
      Not only: if print were really a longer portion of code, you may {want,need} to refactor it into a sub, with the added overhead of a sub call (and here we're being -for once- really paranoid 'bout efficiency and micro-optimizations), which would not have been necessary at all if we had that kind of syntactic sugar...
      Well, that would ask for syntactic sugar with an overhead of less than a subroutine call....

      Note that with clever use of string eval you can duplicate the code without having to maintain it twice, and not have the overhead of calling a subroutine from a loop. And you can move the eval as far out as you want (so the overhead of calling it becomes small enough).

        Of course my original question was asked in the context of Perl6, and there my reasoning goes one. Just as obviously eval is the answer to most self-modifying-code(-like) needs in Perl5, but we all rather prefer to avoid it if possible...