in reply to why not listed foreach and if?

It's quite dangerous to readability to use flow control structure that are tail-loaded. As you said, they would require reading from right-to-left (or bottom-to-top), but Perl is otherwise arranged in a top-to-bottom, left-to-right order. Tail-loaded control structures are only acceptable, if ever, when the body is minimal. Your second snippet is a prime example of horrible code.

So flow control modifiers can't be tacked onto other flow control structures, including other flow control modifiers.


Correct bracketing:

if ( $a ) { print for @b; }

The following might be an option:

next if !$a; # Or `return` print for @b;

If you don't set $\ and $,, the first snippet above is equivalent to:

print @b if $a;

Replies are listed 'Best First'.
Re^2: why not listed foreach and if?
by vincentaxhe (Scribe) on Jun 17, 2024 at 18:21 UTC
    why the restriction? perl feed subs from right to left, why cannot listed foreach and if or any other control structure. Perl do checks if tail-loaded, and why not keep on? as long as there is no ambiguity.

      Because for readability and thus understandability and maintainability the important stuff should come first. A trailing if that determines if anything is performed at all makes the code much harder to understand because when you reach the if you have to revise your entire mental model of the statement to that point.

      Somewhat like the infamous instructions for disarming a bomb:

      1. ...
      2. Cut the blue wire
      3. But first cut the red wire
      4. ...

      Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond

        When it comes to my codebase, the main result of unreadable code is that i would refuse to merge a coworkers change into the main branch and send them back to their desks. With a long todo list on what to fix in their code.

        It's important to understand that i don't shout. Looking sad and slightly shaking my head in disappointment seems to be way more effective when it comes to improving code quality, especially when they come back with still unreadable code. This seldomly fails, my coworkers know the next step up is the dreaded re-run of my one-hour "how to write maintainable code" eye-to-eye lecture while they sit at my desk, watching me refactor their code, commenting on every single mistake and showing how its done correctly.

        It sounds harsh, but it isn't. It's never "you are too stupid to do this right". It's always "You need to learn how to do this to my coding standards. We pay you for it, so take the time and do it. And this is how it's done: ..." (And yes, if a coworker has a good argument on why his way of doing something is the better way, i am not above spending a weekend or two to adapt my whole codebase to the new way of doing things).

      why the restriction?

      It's just that perl's parsing does not handle these types of constructs.
      It interprets:
      foreach @a if $a as foreach(@a if $a)
      foreach takes a list as its argument, and I guess perl just doesn't see (@a if $a) as being a valid list.

      You know what you mean, and I know what you mean, but perl doesn't.
      I don't know exactly why perl doesn't understand these constructs ... but I suspect there are good reasons.

      Cheers,
      Rob

        I'm also not sure why perl doesn't understand them. I suspect they must lead to parsing ambiguities - that usually seems to be the reason for such restrictions.

        In any case, Perl does not have a history of disallowing things on the grounds of "readability" (that seems much more Python's style). What a person finds readable is very much determined by what they are used to, there really is no single perfect style.

        Around 25 years ago I was working at Elsevier in Amsterdam, and once had a very heated discussion with the project lead when in code review he wanted to turn my mix of loops and map/grep pipelines (carefully curated so that no single construct was overly complex) into a single much more complex map/grep pipeline that to me seemed totally illegible. My line manager eventually explained that the lead had a functional programming background, and that I should look at the proposed change in that light. It took me a while, but eventually I got my head around it, and I'm now much more comfortable with that style (and find it perfectly legible when done right).

        Hi,
        How you know that perl interprets as foreach(@a if $A) but not (foreach @a) if $A?

        I see any of constructs if/for/while can be written inside of parentheses, e.g. a simple ($A if $A) is a syntax error.

        'and' and 'if' internally, as I understand, branch equivalently, only the direction differs. And the result of 'if' becomes not an expression, when the result of 'and' becomes an expression.

      perl feed subs from right to left,

      I don't know what that means? Both sub definitions and sub calls read from left to right.

      Perl do checks if tail-loaded,

      No, that's not the case for either the do function or the do block. Both start with do. They read from left to right.

      Are you talking about do ... if ...;, do ... for ...; and , do ... while ...;? Those are just statement modifiers on a expression. No different than next if ...;, etc.

      And again, you keep giving examples that defy your point. do ... while ...; is rarely used, I've never seen the others used, and I actively avoid them all.

        "perl feed subs from right to left" refers code like
        print join ':', sort qw( b g a)
        as haskell '$' do; I do not like 'do {...}' at all, I wish perl accept more structures when if tailed.