in reply to Re^2: Doing "it" only once
in thread Doing "it" only once

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.

Replies are listed 'Best First'.
Re^4: Doing "it" only once
by Limbic~Region (Chancellor) on Sep 21, 2005 at 16:24 UTC
    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

      I think you want the match-only-once operator:
      for ( @some_array ) { if ( ?^foo$? ) { print "skipping foo\n"; next; } if ( ?^bar$? ) { handle_bar($_); next; } handle_rest($_); }

      Caution: Contents may have been coded under pressure.
        Roy Johnson,
        Wow - thanks! That's neat, but I am not sure if it fits the bill. If my understanding of this is correct, it basically ignores subsequent matches if a match has already been found. If that is technically accurate, it fails in that it still checks to see if there is a match before deciding to ignore it.

        This really is a meditation about being able to modify the optree (or the p6 equivalent) while the code is running and what you would do with it if you could. I provided the example of removing a conditional block once the condition has been met and the block ran once. This means not even the condition itself is checked, it would just be "gone". This, I am sure, is not the only application.

        Cheers - L~R

      my %things = (foo => sub {print "skipping foo\n"; next}, bar => sub {handle_bar($_); next}, ); for (@some_array) { (delete $things{$_})->() if exists $things{$_}; handle_rest($_); }
        Anonymous Monk,
        But that doesn't quite fit the bill. That is the equivalent of keeping it as if statements. Since the value is known to only exist one time the body will only ever be ran once but you still check for it every single time. The difference here is instead of checking the fetching a value and comparing it you are checking for the existance of a key. The point is to make the check and the attached block of code completely go away.

        Cheers - L~R