In C++, braces are often optional, such as in:
for (Shape x : shapes)
Draw(x);
Carbon adopted this design choice by default in proposals #285, #340, and #353. But should we keep it?
We were adopting the C++ syntax primarily for easy consistency with C++. For other languages:
There is a CERT rule for when to use braces.
goto failApple had an infamous goto fail bug:
Carbon should require braces when they might otherwise be optional. We should
continue to require parentheses. This currently comes up in if/else,
while, and for.
We will allow else if as a special structure for repeated if statements due
to their frequency. For example, if (...) { ... } else if (...) { ... }
behaves identically to if (...) { ... } else { if (...) { ... } }.
Software and language evolution: Reducing parsing ambiguity of curly braces is important for expanding the syntactic options for Carbon.
Code that is easy to read, understand, and write: We have a preference
to give only one way to do things, and optional braces are inconsistent with
that. It's also easier to understand and parse code that uses braces, and
defends against the possibility of goto fail-style bugs, whether
accidental or malicious.
Interoperability with and migration from existing C++ code: While C++ does make braces optional in related situations, we believe this isn't fundamental to migration or familiarity for C++ developers, so this goal is not meaningfully impacted by this change.
We could instead keep braces optional, such as:
if (x)
return y;
Advantages:
if (!success) return error;.Disadvantages:
More complex and harder to parse.
Nested if statements can have unclear else bindings. For example:
if (x)
if (y)
DoIfY();
else
DoIfNotY();
else
DoIfNotX();
If Carbon were to reuse if and else keywords for a ternary operator,
that could omit braces in order to avoid ambiguity. For example,
int x = if y then 3 else 7;.
Developers are known to make mistakes adding statements to conditionals missing braces, keeping consistent indentation, and missing the incorrect behavior due to cognitive load. For example:
if (x)
return y;
->
if (x)
print("Returning y");
return y;
goto fail;.
Languages which make braces required can make parentheses optional, or even disallow them, such as:
if x {
return y;
}
Advantages:
{} but removing ().
{} regardless of
optionality, but all conditionals could in theory remove ().{}.Disadvantages:
elifWe could make else if a single token, such as elseif or elif.
Advantages:
Disadvantages:
else if also appears in some languages that require braces, such as
Go, Rust, and Swift.