Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • You don't need a separate boolean to handle LAST - if the loop never ran, then there has never been an assignment of the LAST sub, so: if it is defined call it.
    • You are, of course, completely correct. Moritz pointed this out as well [perlgeek.de]. Not sure why I left the boolean in anyway. Esthetics, maybe. Or perhaps just absent-mindedness. I also considered defining it as {;} before the loop, and then running it afterwards no matter what. Saves us an if statement.

      Of course, implementing Perl 6 on top of Perl 6 means I'm pretty much screwed speed-wise no matter how many micro-optimizations I find. I'm left having to optimizing for other things, such as getting all the cool phas

  • Hi Carl, I do not know if this is the right forum for this. I like the phasers, they are really programmer friendly as many other novel Perl6 constructs. But I find the name of the phasers a bit missleading. FIRST and LAST are executed BEFORE and AFTER the first resp last iteration of the loop and is not directly associated with the logic of a loop iteration. Long time ago (in 360 assembler macros) I did similar loop constructs and used the words INITIALIZE, TERMINATE and NEXT and used Booleans FIRST and LA
  • Executing FIRST before anything in the loop makes it pretty uninteresting. It would be more useful if it were run conditionally but on its place.

    About implementing it, how about maintaining a loop iteration counter in some internal variable as $?I.

    The same applies for LAST, but how do you know you are running the last iteration until after the loop check has failed?

    • Hi Salva, I assume your post was to me, it made me look at SO4 abouth phasers WOW that's a lot. I done it again, talk/write first without thinking. My construct were more of documentary purpose and to tie code together. And since I did it mostly for myself I didn't have to take care of every edge case e.g. when an empty loop mattered I did the check in the 'phasers'. As for setting LAST just be one step ahead, it's not a big deal for finit resources. I had good use for my construct, but that was not even a
      • Next time I have opinions about Perl6 I read the specs first.

        Ka-ching! You've just earned 100 experience points, and may proceed to the next level of Perl 6. :)

    • Executing FIRST before anything in the loop makes it pretty uninteresting. It would be more useful if it were run conditionally but on its place.

      ...and that, to be clear, is how it's spec'd to work, and how I actually end up implementing it in the post.

      The same applies for LAST, but how do you know you are running the last iteration until after the loop check has failed?

      Also addressed in the blog post in whose comment thread you are commenting. :)

      • It seems I have not explained my opinion clearly, let me illustrate it with some code:

        for 1..3 { say "enter"; FIRST { say "first run" } LAST { say "last run" } say "leave" }

        I would consider FIRST and LAST to be interesting if that code printed enter, first run, leave, enter, leave, enter, last run, leave.

        • Then what you want is probably not a phaser. Happily, the "create this exact behavior with a home-made module" option is still available as a way out.

          A simple way to do what you want without any syntax modifications to the language would be to iterate over .kv of the list, and then check the .value part in if statements in the loop block.

          In general, it's not possible to know which iteration will become the last one until it's already finished. It is possible in your example, with a finite, statically intros

        • for 1..3 {
              my $first; FIRST { $first = 1 }
              my  $last;  LAST {  $last = 1 }

              say "enter";
              if $first { say "first run" }
              if $last  { say "last run" }
              say "leave"
          }

  • If you asume that any block got FIRST and LAST but by default those fellows are empty function calls, you could move the condition to call FIRST and/or LAST out of the pointy block and into for.

    The only condition you have left then would be if the list is empty. "for" has to check that anyway (at some point) so you don't really add anything.

    I don't really like to have $LOOP_HAS_RUN = True; any time you call the pointy block.

    I tried to implement it in javascript and ended up with the following.

    window.super_f
    • Your solution works fine when the FIRST and LAST does not access any lexical variables specific to the loop block. $a in your Perl 6 code at the end is such a variable. Sending $code_first and $code_last in as unrelated closures doesn't give those closures access to $a.

      For a solution that does work for these cases, please re-read the blog post. :)