http://qs321.pair.com?node_id=649608

o0lit3 has asked for the wisdom of the Perl Monks concerning the following question:

Perlmonks and golf aliens,

Is there a shorter way to write:
while(@x){1while$x!=$y}
...ideally such that any braces and/or parentheses can be removed (without causing syntax errors - c.f. the code below).
1while$x!=$y while@x
Cheers,
o0lit3

Replies are listed 'Best First'.
Re: Golf Question - Shortest way to write while inside while
by ikegami (Patriarch) on Nov 08, 2007 at 01:01 UTC

    The following will produce the same result (a conditional infinite loop):

    {@x&&redo}

    If you're asking if it's possible to use more than one statement modifier in a statement, it's not in Perl5. Quote perlsyn (emphasis in original):

    Any simple statement may optionally be followed by a SINGLE modifier, just before the terminating semicolon (or block ending).

Re: Golf Question - Shortest way to write while inside while
by ambrus (Abbot) on Nov 08, 2007 at 09:14 UTC

    If you want to use lots of whiles in a code, define a sub. For example (untested):

    sub w (\&@) { while (&{$_[0]}()) { &{$_[1]}() } } sub d (\&) { $_[0]; } # then, instead of while (foo) { bar }, you can say w{foo}d{bar};
    or, like
    sub l(\&) { WHILE: while(1) { &{$_[0]}(); } } sub w($) { $_[0] or last WHILE } # then, instead of while (foo) { bar }, l{w foo;bar};

      Bugs:

      • The proto is &, not \&.

      Golf

      • The label is not needed in the second snippet.
      • x->() is shorter than &{x}().
      • &{x} is even shorter if you don't care about @_.
      • y while x is shorter than while (x) { y }.
      • {x;redo} is shorter than x while 1.
      • || is shorter than  or.
      • Proto not needed for w in second snippet.
      sub w(&$){&{$_[1]}while&{$_[0]}}sub d(&){$_[0]} # then, instead of while (foo) { bar }, w{foo}d{bar};
      sub l(&){{&{$_[0]};redo}}sub w{$_[0]||last} # then, instead of while (foo) { bar }, l{w foo;bar};
        • The proto is &, not \&.

        True. I keep messing this one up.

        • x->() is shorter than &{x}().
        • y while x is shorter than while (x) { y }.
        • || is shorter than or .
        • The label is not needed in the second snippet.

        Yep. I thought of the case when you need lots of while loops, so the size of the definition doesn't really matter, only the way you use them.

        • {x;redo} is shorter than x while 1.

        Doesn't help here anymore I guess, because we have nonalnums around while.

        • &{x} is even shorter if you don't care about @_.

        Yes, but that doesn't really help because you don't get the @_ of the loop context, only the @_ passed to w or l.

        While we're there, &{+pop} is even shorter than &{$_[0]} in the defn of l, and pop is shorter than $_[0] in w.

        • Proto not needed for w in second snippet.

        It puts the condition in scalar context, like while does, so it might save some characters in the loops.