开发者

Why do Perl control statements require braces?

开发者 https://www.devze.com 2022-12-14 02:25 出处:网络
This may look like the recent question that asked why Perl doesn\'t allow one-liners to be \"unblocked,\" but I found the answers to that question unsatisfactory because they either referred to the sy

This may look like the recent question that asked why Perl doesn't allow one-liners to be "unblocked," but I found the answers to that question unsatisfactory because they either referred to the syntax documentation that says that braces are required, which I think is jus开发者_JAVA技巧t begging the question, or ignored the question and simply gave braceless alternatives.

Why does Perl require braces for control statements like if and for? Put another way, why does Perl require blocks rather than statements, like some other popular languages allow?


One reason could be that some styles dictate that you should always use braces with control structures, even for one liners, in order to avoid breaking them later, e.g.:

if (condition) 
   myObject.doSomething();
else 
   myObject.doSomethingElse();

Then someone adds something more to the first part:

if (condition)
   myObject.doSomething();
   myObject.doSomethingMore(); // Syntax error next line
else 
   myObject.doSomethingElse();

Or worse:

if (condition)
   myObject.doSomething();
else 
   myObject.doSomethingElse();
   myObject.doSomethingMore(); // Compiles, but not what you wanted.

In Perl, these kinds of mistakes are not possible, because not using braces with control structures is always a syntax error. In effect, a style decision has been enforced at the language syntax level.

Whether that is any part of the real reason, only Larry's moustache knows.


One reason could be that some constructs would be ambiguous without braces :

foreach (@l) do_something unless $condition;

Does unless $condition apply to the whole thing or just the do_something statement?

Of course this could have been worked out with priority rules or something, but it would have been yet another way to create confusing Perl code :-)


One problem with braceless if-else clauses is they can lead to syntactic ambiguity:

if (foo)
    if (bar)
       mumble;
    else
       tumble;

Given the above, under what condition is tumble executed? It could be interpreted as happening when !foo or foo && !bar. Adding braces clears up the ambiguity without dirtying the source too much. You could then go on to say that it's always a good idea to have the braces, so let's make the language require it and solve the endless C bickering over whether they should be used or not. Or, of course, you could address the problem by getting rid of the braces completely and using the indentation to indicate nesting. Both are ways of making clear, unambiguous code a natural thing rather than requiring special effort.


In Programming Perl (which Larry Wall co-authored), 3rd Edition, page 113, compound statements are defined in terms of expressions and blocks, not statements, and blocks have braces.

Note that unlike in C and Java, [compound statements] are defined in terms of BLOCKS, not statements. This means that the braces are requried--no dangling statements allowed.

I don't know if that answers your question but it seems like in this case he chose to favor a simple language structure instead of making exceptions.


Perhaps not directly relevant to your question about (presumably) Perl 5 and earlier, but…

In Perl 6, control structures do not require parentheses:

if $x { say '$x is true' }

for <foo bar baz> -> $s { say "[$s]" }

This would be horrendously ambiguous if the braces were also optional.


Isn't it that Perl allows you to skip the braces, but then you have to write statement before condition? i.e.

#!/usr/bin/perl

my $a = 1;

if ($a == 1) {
    print "one\n";
}

# is equivalent to:

print "one\n" if ($a == 1);


"Okay, so normally, you need braces around blocks, but not if the block is only one statement long, except, of course, if your statement would be ambiguous in a way that would be ruled by precedence rules not like you want if you omitted the braces -- in this case, you could also imagine the use of parentheses, but that would be inconsistent, because it is a block after all -- this is of course dependent on the respective precedence of the involved operators. In any case, you don't need to put semicolons after closing braces -- it is even wrong if you end an if statement that is followed by an else statement -- except that you absolutely must put a semicolon at the end of a header file in C++ (or was it C?)."

Seriously, I am glad for every explicitness and uniformity in code.


Just guessing here, but "unblocked" loops/ifs/etc. tend to be places where subtle bugs are introduced during code maintenance, since a sloppy maintainer might try to add another line "inside the loop" without realizing that it's not really inside.

Of course, this is Perl we're talking about, so probably any argument that relies on maintainability is suspect... :)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号