Why are braces used by default to enclose the function body instead of parentheses?
The body of a function can be any compound command. This is typically { list; }
, but three other forms of compound commands are technically allowed: (list)
, ((expression))
, and [[ expression ]]
.
C and languages in the C family like C++, Java, C#, and JavaScript all use curly braces to delimit function bodies. Curly braces are the most natural syntax for programmers familiar with those languages.
Are there other major downsides (*) to using parentheses instead of braces (which might explain why braces seem to be preferred)?
Yes. There are numerous things you can’t do from a sub-shell, including:
- Change global variables. Variables changes will not propagate to the parent shell.
- Exit the script. An
exit
statement will exit only the sub-shell.
Starting a sub-shell can also be a serious performance hit. You’re launching a new process each time you call the function.
You might also get weird behavior if your script is killed. The signals the parent and child shells receive will change. It’s a subtle effect but if you have trap
handlers or you kill
your script those parts not work the way you want.
When shall I use curly braces to enclose the function body, and when is it advisable to switch to parentheses?
I would advise you to always use curly braces. If you want an explicit sub-shell, then add a set of parentheses inside the curly braces. Using just parentheses is highly unusual syntax and would confuse many people reading your script.
foo() {
(
subshell commands;
)
}