Off the top of my head, I can think of at least two other situations where punctuation matters:
1) Whenever you have nested match cases:
match left with
| Some left ->
match right with
| Some right -> Some (left, right)
| None -> None
| None -> None
The compiler does not use indentation to figure out scoping, so the above gets treated as: match left with
| Some left ->
match right with
| Some right -> Some (left, right)
| None -> None
| None -> None
So you need to surround the inner match with parens match left with
| Some left ->
(
match right with
| Some right -> Some (left, right)
| None -> None
)
| None -> None
2) If you are doing imperative things inside an if statement:Consider the following function:
let cache_file file =
if not (file_exists file) then
printf "downloading file\n";
download file
else
printf "file already exists\n"
The problem here is that OCaml allows one to create an if statement with no else clause. And since the compiler doesn't use indentation to figure out scoping, then the code is essentially treated like the following: let cache_file file =
(if not (file_exists file) then printf "downloading file\n");
download file;
else (printf "file already exists\n");
Which is just totally wrong. So in order to do multiple imperative actions within an if block, you should use either parens, or begin/end delimiters (which are treated exactly the same as parens) let cache_file file =
if not (file_exists file) then begin
printf "downloading file\n";
download file
end else
printf "file already exists\n"