Raku last on non-loops
Asked Answered
C

1

7

I have something that I can do easily in Perl, but not in Raku without fiddling around with flag variables. Here's the Perl code:

#!/usr/bin/perl

MAIN_BLOCK: {
        foreach $item (1 2 3 4 5) {
                $item == 6 and last MAIN_BLOCK;
        }
        print "No items matched!\n";
}

The relevant difference here is that Perl will allow you to use last to exit from any labelled block. Raku will only do this if the block is a loop.

Is there a good way to do this? I feel like there should be a phaser for this, but haven't figured out how to do it without flag variables, which seem like they should be avoidable.

Thanks,

Callaghan answered 8/12, 2021 at 21:17 Comment(1)
In theory the appropriate Raku incantation would be leave MAIN_BLOCK (instead of last MAIN_BLOCK). In practice it will currently net you a leave not yet implemented. Sorry. message. Filed many years ago as leave NYI. Issues since then about the related LEAVE phaser include 1, 2, 3. So don't hold your breath for leave...Pier
Q
6

Raku supports similar control flow with given blocks.

Here's a fairly literal translation (i.e., not necessarily idiomatic Raku) from the Perl code you posted:

given * {
    for ^6 -> $item {
        succeed if $item == 6;
    }
    default { print "No items matched!\n"; }
}

edit: Oh, and for a less-literally-translated/more-idiomatic-Raku solution, well, TIMTOWTDI but I might go with returning from an anonymous sub:

sub { for ^6 { return when 6 }
      say "No items matched!" }()

(Of course, I suppose it's possible that the most Raku-ish way to solve do that doesn't involve any Raku syntax at all – but instead involves modifying one of Raku's braided languages to allow for loops to take an else block. But I'm not advising those sort of shenanigans!)

Quadrennial answered 8/12, 2021 at 21:59 Comment(12)
"If you are not inside a when or default block, it is an error to try to use proceed or succeed." You could add a default block, but that only makes it more artificial.Tired
@Tired thanks! I had the default block locally – not sure how I managed to forget it in the answer ^^^Quadrennial
it says you can only succeed out of a when or default. That's still not right, AFAICS.Tired
Hmm... it works in real life, the docs just say it shouldn't :)Tired
@Tired I was just noticing that too. I wonder if the docs are wrong or if Rakudo is being more permissive than it should?Quadrennial
Thanks guys! Great solutions. Accepted!Callaghan
Between this any Damien Conway's code, though, I'm wondering if we don't need more phasers. But, given the number we already have, I think it's more likely that we need to somehow make more flexible phasers that maybe take a parameter or 2. Maybe in Raku 2 :) .Callaghan
@TimothyNelson See my comment on your question. There's already a LEAVE phaser, and a leave keyword that was designed to be able to apply to a labelled block. That is the solution designed precisely for your Q's scenario.Pier
@Pier if we're bringing not-yet-implemented features into the mix, there's also a NYI goto statement that would solve every problem :DQuadrennial
@Quadrennial :) Aiui leave ... et al are what .@Larry designed as the block structured programming constructs for the "more flexible phasers" that .@TimothyNelson is wondering about. My guess is it would be easier to implement leave per design than goto but, much more importantly, while Raku's design presumes goto will one day be implemented (on the basis it is sometimes just the ticket), it's not block structured programming like last, leave et al. Imo goto's reputation as generally evil is valid, and use of it to just leave a block would be an anti-pattern. You agree, right?Pier
Referencing: design.raku.org/S04.html#The_goto_statementJamilajamill
@Pier Agreed about the LEAVE phaser. It'd be nice, though, if a) it was possible to pass a topicaliser to phasers (the same as given) that defaulted to something like maybe &?BLOCK, and b) if there were an easy way to detect if &?BLOCK had exited without an exception (not even a Control Exception).Callaghan

© 2022 - 2024 — McMap. All rights reserved.