34.6 Parentheses and brackets

Braces for single-statement blocks

Single-statement blocks can be rendered in several ways. The preferred style is fully bracketed with the statement appearing on its own line, as follows.

for (n in 1:N) {
  y[n] ~ normal(mu,1);
}

The use of loops and conditionals without brackets can be dangerous.
For instance, consider this program.

for (n in 1:N)
  z[n] ~ normal(nu,1);
  y[n] ~ normal(mu,1);

Because Stan ignores whitespace and the parser completes a statement as eagerly as possible (just as in C++), the previous program is equivalent to the following program.

for (n in 1:N) {
  z[n] ~ normal(nu,1);
}
y[n] ~ normal(mu,1);

Therefore, one should prefer to use braces. The only exception is when nesting if-else clauses, where the else branch contains exactly one conditional. Then, it is preferred to place the following if on the same line, as in the following.

if (x) {
  // ...
} else if (y) {
  // ...
} else {
  // ...
}

Parentheses in nested operator expressions

The preferred style for operators minimizes parentheses. This reduces clutter in code that can actually make it harder to read expressions. For example, the expression a + b * c is preferred to the equivalent a + (b * c) or (a + (b * c)). The operator precedences and associativities follow those of pretty much every programming language including Fortran, C++, R, and Python; full details are provided in the reference manual.

Similarly, comparison operators can usually be written with minimal bracketing, with the form y[n] > 0 || x[n] != 0 preferred to the bracketed form (y[n] > 0) || (x[n] != 0).

No open brackets on own line

Vertical space is valuable as it controls how much of a program you can see. The preferred Stan style is with the opening brace appearing at the end of a line.

for (n in 1:N) {
  y[n] ~ normal(mu,1);
}

This also goes for parameters blocks, transformed data blocks, which should look as follows.

transformed parameters {
  real sigma;
  // ...
}

The exception to this rule is local blocks which only exist for scoping reasons. The opening brace of these blocks is not associated with any control flow or block structure, so it should appear on its own line.