68

Languages like C, Java, and C++ all require parenthesis around an entire expression when used in an if, while, or switch.

if (true) {
    // Do something
}

as opposed to

if true {
    // Do something
}

This seems odd to me because the parenthesis are redundant. In this example, true is a single expression on its own. The parenthesis do not transform its meaning in any way I know of. Why does this odd syntax exist and why is it so common? Is there a benefit to it I'm not aware of?

30
  • 20
    Pascal doesn't require parentheses (because it requires a THEN).
    – JimmyB
    Nov 7, 2016 at 9:16
  • 32
    Python, Ruby don't.
    – smci
    Nov 7, 2016 at 12:29
  • 33
    I believe C uses parentheses because the braces are optional for a single-statement body. Or perhaps a better way to put it is that the braces aren't part of the if statement, they just create a compound statement. Nov 7, 2016 at 14:54
  • 7
    Go, interestingly, requires braces but not parentheses.
    – Kos
    Nov 7, 2016 at 15:31
  • 25
    The question is a little bit tautological. Why are round manhole covers all round? Why are all brothers male? Why do paren-requiring-languages all require parens? Round manhole covers are round by definition; brothers are male by definition; languages which require parens require parens by definition. Nov 7, 2016 at 21:19

10 Answers 10

157

There needs to be some way of telling where the condition ends and the branch begins. There are many different ways of doing that.

In some languages, there are no conditionals at all, e.g. in Smalltalk, Self, Newspeak, Io, Ioke, Seph, and Fancy. Conditional branching is simply implemented as a normal method like any other method. The method is implemented on booleans objects and gets called on a boolean. That way, the condition is simply the receiver of the method, and the two branches are two arguments, e.g. in Smalltalk:

aBooleanExpression ifTrue: [23] ifFalse: [42].

In case, you are more familiar with Java, this is equivalent to the following:

aBooleanExpression.ifThenElse(() -> 23, () -> 42);

In the Lisp family of languages, the situation is similar: conditionals are just normal functions (actually, macros) and the first argument is the condition, the second and third argument are the branches, so they are just normal function arguments, and there is nothing special needed to delimit them:

(if aBooleanExpression 23 42)

Some languages use keywords as delimiters, e.g. Algol, Ada, BASIC, Pascal, Modula-2, Oberon, Oberon-2, Active Oberon, Component Pascal, Zonnon, Modula-3:

IF aBooleanExpression THEN RETURN 23 ELSE RETURN 42;

In Ruby, you can use either a keyword or an expression separator (semicolon or newline):

if a_boolean_expression then 23 else 42 end

if a_boolean_expression; 23 else 42 end

# non-idiomatic, the minimum amount of whitespace required syntactically
if a_boolean_expression
23 else 42 end

# idiomatic, although only the first newline is required syntactically
if a_boolean_expression
  23
else
  42
end

Go requires the branches to be blocks and doesn't allow expressions or statements, which makes the curly braces mandatory. Therefore, parentheses aren't required, although you can add them if you want; Perl6 and Rust are similar in this regard:

if aBooleanExpression { return 23 } else { return 42 }

Some languages use other non-alphanumeric characters to delimit the condition, e.g. Python:

if aBooleanExpression: return 23
else: return 42

The bottom line is: you need some way of telling where the condition ends and the branch begins. There are many ways of doing so, parentheses are just one of them.

13
  • 8
    Very good overview. Nov 7, 2016 at 10:42
  • 2
    of course in a language where either bare expressions aren't a statement (e.g. something like older BASIC where a calculated value must be either assigned to a variable or passed to some other statement) or where there are no prefix operators you should always be able to identify the end of an expression and start of a statement anyway. I could definitely see a BASIC variant managing without a delimiter at the end of an IF statement. Nov 7, 2016 at 16:28
  • 4
    Also, since C was designed in the 70's, and computation was expensive, adding a little parenthesis would probably make the parser a little bit easier to write.
    – Machado
    Nov 7, 2016 at 17:33
  • 4
    Re: Lisp: "actually, macros". In practice IF is a special form in Scheme and CL (just for completeness).
    – coredump
    Nov 7, 2016 at 18:09
  • 1
    @Leushenko: And, e.g. in MISC, which is lazy-by-default, all of the conditional forms are just normal functions, neither macros nor special forms. (Indeed, AFAIR, MISC has zero special forms?) Nov 7, 2016 at 20:11
69

The parenthesis are only unnecessary if you use braces.

if true ++ x;

For example becomes ambiguous without them.

26
  • 29
    @RobertHarvey - The parenthesis are required by pretty much every language I'm aware of. Certainly C and its kin. The OP is asking why they are required - and it's because the language would become ambiguous otherwise.
    – Telastyn
    Nov 7, 2016 at 3:05
  • 25
    Just off the top of my head, parenthesis are not required for if in: basic, assembly, python, bash/zsh, tcl, batch, brainfuck, or machine code. Lacking parenthesis only makes an if ambiguous if the language has been designed to depend on them. Nov 7, 2016 at 6:42
  • 12
    Im astonished that nobody mentioned the most logical and readable version - in Pascal (incl. Delphi) it's if Condition then .... Nov 7, 2016 at 7:52
  • 18
    Go is a good example of doing the opposite. It makes braces {} compulsory and therefore does not require parens around the expression. Not only is parens not required but if I remember correctly adding parens would cause a compilation error - they're forbidden
    – slebetman
    Nov 7, 2016 at 9:14
  • 10
    @Eiko Let me rephrase. The example in the answer is syntactically ambiguous, even though it's semantically unambiguous (as you noted). But since the parsing phase happens before semantic analysis, the parser will encounter the ambiguity -- and it must either make an uninformed guess, or fail. If (for any reason) the parser chooses not to fail, the semantic analyzer will work with the resulting tree, whatever that is. I haven't seen a compiler where the semantic analyzer is willing to ask the parser to reparse the subtree and make a different choice at the syntactically ambiguous construct. Nov 7, 2016 at 12:06
22

Parentheses in an if statement do not have the same meaning as parentheses used within an arithmetic expression. Parentheses in an arithmetic expression are used to group expressions together. Parentheses in an if statement are used to delimit the boolean expression; that is, to differentiate the boolean expression from the rest of the if statement.

In an if statement, parentheses do not perform a grouping function (though, within the if statement, you can still use parentheses to group arithmetic expressions. The outer set of parentheses then serves to delimit the entire boolean expression). Making them required simplifies the compiler, since the compiler can rely on those parentheses always being there.

4
  • I don't see how it simplifies the compiler. The rule ` IF '(' expression ')' statement` is no simpler than IF primary_expression statement. Notice that the latter is equally unambiguous.
    – user58697
    Nov 8, 2016 at 23:31
  • @user58697: No, only the latter has the ambiguity where a postfix operator on primary_expression cannot be distinguished from a prefix operator on an expression-statement. To copy Telastyn's answer, if true ++ x;. Also, if empty statements exist, if a & f; can be either an empty statement and binary & inside the condition, or a unary & at the start of the statement. But when matching parentheses, there's exactly one match for the opening (
    – MSalters
    Nov 9, 2016 at 0:08
  • @MSalters A postfix operator does not parse as a primary. A primary expression is one of IDENTIFIER, CONSTANT, STRING_LITERAL and '(' expression ')'.
    – user58697
    Nov 9, 2016 at 2:06
  • @user58697: You seem to have a particular language in mind. And it appears to have a rule that parentheses are not needed if and only if the conditions is an "IDENTIFIER, CONSTANT or STRING_LITERAL". I'm not sure that makes things easier.
    – MSalters
    Nov 9, 2016 at 8:27
16

As other have already partially pointed out this is due to the fact that expressions are also valid statements, and in the case of a block with just one statement you can drop braces. This means that the following is ambiguous:

if true
    +x;

Because it could be interpreted as:

if (true + x) {}

instead of:

if (true) {+x;}

A number of languages (e.g. Python) allow you to avoid the parenthesis but still have an end-condition marker:

if True: +x

However you are right that we could define a language where the parenthesis are never required: a language where an expression is not a valid statement will not have this problem.

Unfortunately this means that things like:

 ++x;
 functionCall(1,2,3);

would not be valid statements, so you'd have to introduce some weird syntax to be able to perform such actions without creating expressions. A simple way to do this is to simply prepend the expression by a marker like [statement]:

[statement] ++x;
[statement] functionCall(1,2,3);

Now the ambiguity disappears since you'd have to write:

if true
    [statement] ++x;

But as you can see I don't see such a language be widespread since putting the parenthesis around an if-condition (or a : at its end) is much better then putting such a marker for every expression statement.


Note: the use of a [statement] marker is just the simplest syntax I could think of. However you could have two completely distinct syntaxes for expressions and statements with no ambiguity between them which would not require such a marker. The problem is: the language would be extremely weird since to do the same things in an expression or a statement you'd have to use a completely different syntax.

One thing that comes to mind to have two separate syntaxes without such an explicit marker would be, for example: force statements to use unicode symbols (so instead of for you'd use some unicode variation of the letters f, o and r), while expressions to be ASCII only.

5
  • 2
    A language actually exists that uses such a expression statement marker: If you want to evaluate an expression for its side effects, you need to explicitly discard its value in Nim. However, that's just done for type safety, not for syntactic reasons.
    – amon
    Nov 7, 2016 at 10:10
  • @amon Nice, I didn't know about that. Anyway, as I said the marker isn't really needed it's just a simple way to achieve that distinction without inventing unintuitive syntaxes.
    – Bakuriu
    Nov 7, 2016 at 10:21
  • 1
    @amon - many BASIC variants also have a strict separation between expressions and statements. Expressions are only allowed in places where the value will actually be used (e.g. variable assignments, statements like PRINT that perform an action, and so on). Procedures that aren't used to calculate a value are invoked by a keyword (typically "CALL", although at least one variant I'm aware of uses "PROC") that prefixes their name. And so on. BASIC usually delimits the end of the expression in an IF statement with "THEN", but I can see no technical reason that requirement couldn't be dropped. Nov 7, 2016 at 16:37
  • 1
    There is a language very popular in the 80s that have blocks without parens, braces, colons or another marker and accept expressions as statements everywhere and some statements act like expressions (compound operators like += and ++). It´s worsrt, there is a dumb pre- processor before compiler (? simbol in example in fact is a function after PP). There is no ;. Sure, it need a marker for continuation line, but this is discouraged. harbour.github.io/doc/clc53.html#if-cmd. The compiler is fast and simple (created with Bison/Flex).
    – Maniero
    Feb 25, 2017 at 18:22
  • @bigown They achieve that by using a separate syntax for logical-conditions, so, basically, the conditions for if, while ecc are limited compared to generic expressions used in other languages. Sure: if you have more than two syntactical categories (like statement, expression, logical-expression, coffee-making-expression, ...) you can trade some freedom.
    – Bakuriu
    Feb 25, 2017 at 19:44
10

It is common for C-family languages to require these parentheses, but not universal.

One of Perl 6's more noticeable syntactic changes is that they modified the grammar so that you don't have to give the parentheses around if, for and similar statements' conditions. So something like this is perfectly valid in Perl 6:

if $x == 4 {
    ...
}

as is

while $queue.pop {
    ...
}

However, because they're just expressions you can put parentheses around them if you want, in which case they are just ordinary grouping ones instead of a required part of the syntax as they are in C, C#, Java etc.

Rust has similar syntax to Perl 6 in this department:

if x == 4 {
    ...
}

It seems to me like a feature of more modern C-inspired languages is to look at things like this and wonder about removing them.

3
  • While your answer provides some insight into other languages, it does not answer "Why does this odd syntax exist and why is it so common?"
    – user22815
    Nov 7, 2016 at 15:17
  • You're quite correct. I was really looking to add context to the question, which is not something easy to do in this platform. I guess ultimately if I do provide an answer to the question it's "just because, as there's no technical reason the grammar couldn't have accommodated not having them". But that's not a very useful answer. Nov 8, 2016 at 11:02
  • In Perl 5 there is both. For a normal if or loop constructs with BLOCKs, the parens are required, e.g. in if ( $x == 4 ) { ... } or foreach my $foo ( @bar ) { ... }. When postfix notation is used the parens are optional, as in return unless $foo; or ++$x while s/foo/bar/g;.
    – simbabque
    Nov 8, 2016 at 12:35
6

There is one aspect which I am surprised that none of the existing answers have brought up.

C, and many C derivatives and look-alikes, has a peculiarity in that the value of an assignment is the assigned value. A consequence of this is that an assignment can be used where a value is expected.

This allows you to write things like

if (x = getValue() == 42) { ... }

or

if (x == y = 47) { ... }

or

unsigned int n = 0 /* given m == SOME_VALUE */;
while (n < m && *p1++ = *p2++) { n++; }

(which is implicitly treated as while (n < m && *p1++ = *p2++ != 0) { n++; } because C treats non-zero as true; incidentally, I think that's just about strncpy() in the C standard library)

or even

if (x = 17);

and it is all valid. Not all syntactically valid combinations are necessarily useful (and modern compilers specifically warn about assignments inside conditionals, because it is a common error), but some of it actually is useful.

Parsing such statements would likely be far more difficult if there was not some unambiguous way to determine where the conditional expression begins and ends.

Parenthesis were already used to delimit function names from function arguments, so I guess they seemed like a natural choice also to delimit keywords from keyword arguments.

Sure, alternative syntaxes could be defined to do the same thing. But doing so would increase complexity, particularly in the parser which would then need to deal with two different sets of syntax for largely the same thing. Back when C was being designed, computing power (both in terms of number-crunching ability, working memory, and storage capacity) were extremely limited; anything that reduced complexity at little or no cost to readability was almost certainly a welcome change.

Using parenthesis might seem slightly archaic today, but it's not like that given someone with some familiarity with the language, it impairs readability compared to some other syntax that is capable of expressing the same things.

5

The reason is mostly history.

At the time that the first C compiler was written, computers have very limited ram, cpu and compilers where written “by hand” with few tools to help compiler writers. Therefore complex rules were costly to implement in a compiler. C++, C#, Java, etc were all designed to be easy for C programmers to learn, hence there was no “unnecessary” changes made.

In ‘c like' languages conditionals (if, while, etc) do not require an explicit block off code, you can just use a simple statement.

if (a == d) doIt()

or you can combine statements together into a compound statement by putting them with in {}

We like the compiler to find error we make and to give as an error message we can understand.

3

Java and C++ both were developed after C had become a very popular programming language. One consideration in the design of each of those languages was that it would appeal to C programmers and woo those programmers to use the new language. (I was one of the C programmers they wooed successfully.) C++ additionally was designed to be (almost) interchangeable with C code. In order to support these goals, both C++ and Java adopted much of C's syntax, including the parentheses around the conditions of if, while, and switch statements.

Hence the reason why all these languages require parentheses around the conditions of those statements is because C does, and the question is really just why C requires those parentheses.

The origins of the C language are described in this article by Dennis Ritchie, one of the principal authors of its development (some might even say the principal author of its development). As told in that article, C was originally developed in the early 1970s as a system programming language for computers with extremely limited space in main memory. It was desired to have a language that was higher-level than assembly language, but given the resources available to work with, the ease of parsing the language was also important. Requiring the parentheses would make it relatively easy to identify the conditional code.

One might also infer that the ability to write programs using fewer characters was considered an advantage, and two parentheses take less space than the keyword THEN that was used in FORTRAN and other high-level languages at that time; in fact, since the parentheses could also replace spaces as delimiters of symbols, if(a==b) was four whole characters shorter than IF a==b THEN.

In any event, some balance had to be struck between how easily human beings would be able to read, write, and understand programs written in C, how easily a compiler could parse and compile programs written in C, and how many kilobytes (!) would be required both for the program source and the compiler itself. And parentheses around the conditions of if, while, and switch statements was how people chose to strike that balance in the design of C.

As evidenced in several other answers, once you take away the particular circumstances under which C was developed, all kinds of alternative forms of syntax have been used for the conditionals of various programming languages. So the parentheses really just come down to a design decision that was made by a few people under certain constraints at a certain time in history.

3
  • I'm not sure it's fair to say that C++ was designed the way it was "in order to woo those programmers to use a new language". Remember C with classes?
    – user
    Nov 9, 2016 at 9:25
  • @MichaelKjörling Admittedly, the Java developers were much more explicit about the "wooing." But note that the linked article cites, as one reason why Stroustrup chose to start with C as the basis of his language, that C was widely used. One way in which this provided a motivation to stay close to C was because existing code could easily be adapted (as I already stated)--but also existing coders could easily adapt.
    – David K
    Nov 9, 2016 at 14:39
  • @MichaelKjörling I suppose the original wording of my answer suggested that the "wooing" was a greater factor in the language design than it actually was. I've edited the answer to try to clarify that it was merely one thing that factored into the language design.
    – David K
    Nov 9, 2016 at 14:49
3

Many here reason that without the parentheses the syntax would be ambiguous and imply silently that this would be somehow bad or even an impossible situation.

In fact, languages have lots of ways to deal with ambiguities. Operator precedence is just one instance of this topic.

No, ambiguity isn't the reason for the parentheses. I guess one could simply create a version of C which does not require the parentheses around the condition (thus making them optional) and which still creates valid code in all cases. The example of if a ++ b; could be interpreted as being equivalent to if (a) ++b; or if (a++) b;, whatever seems more appropriate.

The question of why Dennis Ritchie chose to make the () mandatory (and thus coining this meme for lots of derived languages) is rather a linguistic one. I guess the notion of stating clearly that the condition is an expression rather than a command was the father of the thought.

And in fact, C was designed to be a parseable using a one-pass parser. Using a syntax with mandatory parentheses around the condition supports this aspect.

2
  • I see a downvote on my answer. Please be so kind to explain in a comment what you didn't like about it. Maybe I can improve it then.
    – Alfe
    Nov 10, 2016 at 8:52
  • In a Swift-like language “if x ++ y” would be illegal because a unary operator must be attached to what it opersted on. Either “if x++ y” or “if x ++y”. Binary operator must have space on both sides, or on neither side so “if x ++ y” or “if x++y” would be both binary operators.
    – gnasher729
    Oct 24, 2023 at 20:07
0

Parentheses around if conditions are not required in Fortran, Cobol, PL/1, Algol, Algo-68, Pascal, Modula, XPL, PL/M, MPL, ... or any other language that has a then keyword. then serves to delimit the condition from the following statement.

The closing parenthesis in C etc. functions as then, and the opening one is formally redundant.

Above remarks apply to traditionally-parsed languages.

1
  • Fortran does require parentheses in all versions of its IF, including structural one.
    – Netch
    Nov 10, 2016 at 7:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.