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.