in reply to Control Structures

I'd like to see fewer control structures in perl. Both unless() and the trailing if() are constant sources of bugs in the code I see.

Replies are listed 'Best First'.
Re^2: Control Structures
by demerphq (Chancellor) on May 10, 2005 at 07:48 UTC

    Really? Thats an interesting observation, I always found both forms useful for minimizing noise and making flow control clearer. I find unless in either form (block or modifier) somewhat more inclined to be difficult, but the modifier if, and even unless coupled with loop control statements like next and last to be very useful in enhancing readability.

    When I see something like

    next if $condition;

    it allows me to think "condition is prohibited past this line", i dont have to worry that later on the block ends and !$condition is still possible. For instance in the following code if at a later I point I forget the importance of the next, or possible restructure code so it doesnt fire sometimes something bad could happen after the block and I might not even notice it until debugging. The statement form doesnt allow such complexity so it sort of red-flags itself as being "mess with this and the code below has to be completely reconsidered."

    if ($condition) { ... next; } # !$condition stuff can happen here
    ---
    $world=~s/war/peace/g

      Trailing if() leads to this incredibly hard to debug problem, which I have seen in production code. So, you could say that trailing if() would be fine except that perl has bugs with it, but that doesn't really help the current situation.
        I disagree - that's not a problem with the trailing if(). That's a problem with how my() is implemented as both a compile-time and run-time actor. The trailing if() is doing exactly what it's supposed to do, which is execute the statement at run-time if the conditional is true.

        The reason it's counter-intuitive is because my() is the only statement that affects the current scope with both compile-time and run-time actions. If you use a standard if-block with {}, you create a new scope and everything acts as expected.


        • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
        • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"

        Ah, that error. Well i thought 5.8.x was supposed to warn when this happened but based on the tests I just did it doesnt. Maybe its 5.10 when its supposed to happen. But I do agree with dragonchild that its a bit hard on if() to consider it a bug when in fact the error is in the my(). :-)

        Anyway, it is a good thing to keep in mind. If you want to do conditional initialization as part of the declaration of a lexical you should always use the ternary operator and not a modifier. I guess I have this lesson so hammered into my head that I find it hard to see it as an error, which of course it is.

        ---
        $world=~s/war/peace/g

        Seems like a classic case of "doctor, it hurts when I do this".

        I'd consider myself a mid-level Perl programmer, it's never even occured to me to try my $foo if $bar, simply because "conditional declaration" isn't a concept that makes sense to me. I understand the linked explanation, I'm just saying I would never have arrived at that construct on my own, so it seems unlikely to cause trouble for new programmers.

        If people feel the need to abuse the side effects of an implementation bug in production code, well, that's not a problem with the language design.

Re^2: Control Structures
by adrianh (Chancellor) on May 10, 2005 at 08:24 UTC
    Both unless() and the trailing if() are constant sources of bugs in the code I see.

    Depends in my experience. With newbie developers or with people new to Perl it can cause problems. Appropriately used I find they produce clearer and more readable code.

    Personally I'd rather train up the developer than simplify the language.

      New developers will create bugs regardless of language. It is a gift, without which they would never learn.

        New developers will create bugs regardless of language. It is a gift, without which they would never learn.

        To put my devil's advocate hat on for a minute - new developers will create bugs, but language choice can have a huge effect on what kind of bugs.

        For example a newbie developer using a language that naturally supports iteration over containers like Perl's foreach() or Ruby's each() won't hit a whole bunch of off-by-one errors that languages like C curse people with.

        I remember very well an introductory AI programming course that I helped teach a few years back. At the same time as the students were building a GUI driven 3D block world in Pop-11 they were bashing their heads against the wall with segfaults with simple "add up a list of numbers" programs in their C based introductory programming course. No experience before or since has been a better demonstration to me that language choice really matters.

        I just happen to think that trailing if and unless() are not a major cause of problems for novice developers. Certainly not enough of a problem to remove the gain in clarity that they give to experienced developers.

      The problem with unless() is just that people get lost in double negatives and precedence. The problem with trailing if() is this.
        The problem with unless() is just that people get lost in double negatives and precedence.

        Some people do certainly but in my experience it's not a "constant sources of bugs". Certainly not enough of a problem for me to drop the improved clarity I see when the construct is used well.

        The problem with trailing if() is this.

        I'd count that a perl bug, and since perl 5.9.1 we'll get a warning for this "dubious and deprecated construct". I've never seen this in live code, and have never been tempted to write anything that looked like it. If this is the only problem then I'm not worried :-)

Re^2: Control Structures
by Anonymous Monk on May 10, 2005 at 08:03 UTC
    You should stop looking at buggy code :)
      You should stop looking at buggy code :)

      Bah. If only I had the option :-/

Re^2: Control Structures
by Mutant (Priest) on May 10, 2005 at 11:51 UTC
    As others have posted, I don't find problems with this either. Although as soon as these sort of statements start becoming complicated, you're much better off using a proper if () {} block.

    I find trailing if/unless can greatly improve the readability of code (which hopefully helps to reduce bugs).