if a > 0 then
print_endline "a > 0" ;
match a with
| 0 -> print_endline "impossible"
| 2 ->
match b with
| 0 -> print_endline "2, 0"
| _ -> print_endline "2, not 0"
| 3 -> print_endline "3, something"
| _ -> print_endline "something, something"
;
print_endline "done"> Any decent programming editor will be able to indent that properly and you will see the problem.
This seems like a weak excuse. In particular, I could turn it around and say, "any decent programming language should be writable without an editor". Also, the issue isn't just reading, it's writing too - it's much harder to foresee/plan all the `begin`/`end`, while you're writing a line of code, that will make the lines that follow work as intended.
Fair enough, but for the ';', as others explained meanwhile, I think it's pretty simple to understand, it's just that we are not used to it because of C syntax.
EDIT: actually, you are right about ';', it is confusing when I think about it: it does not have the same behavior in a branch of a `match` and in the branch of an `if`… I wonder how I never had problem with that before.
The correct indentation of the above code is:
if a > 0 then
print_endline "a > 0" ;
match a with
| 0 -> print_endline "impossible"
| 2 ->
match b with
| 0 -> print_endline "2, 0"
| _ -> print_endline "2, not 0"
| 3 -> print_endline "3, something"
| _ -> print_endline "something, something"
;
print_endline "done"
To have the same meaning as the indentation implies, you would need to add `(...)` or `begin ... end` at the appropriate places.The second one is that in OCaml, semicolon is a separator, and not a terminator. In contrast, in C/C++, semicolon is a terminator. If you have an expression, you end it with a ";" just because.
This is not the case for OCaml. In OCaml, semicolon is used to separate two sequential expressions where only one expression is expected. Thus,
<expr1>;<expr2>
is evaluated in sequence, and can be used in a place where only one is expected. For example, if statements have the following syntax: if <expr1> then <expr2> else <expr3>
Now if you wanted to do two things (instead of one) in the "then" block, you would simply write if <expr1> then <expr2.1>;<expr2.2> else <expr3>
Notice that under these rules if <expr1> then <expr2>; else <expr3>
makes no sense. Separators are not terminators. We are used to thinking of ";" as terminators because of C/C++. if <expr1> then <expr2.1>;<expr2.2> else <expr3>
Actually, this will not work, I was also confused by it. # if true then (); 1 else 2;;
Error: Parse error: [str_item] or ";;" expected (in [top_phrase])
# if true then begin (); 1 end else 2;;
- : int = 1
# if true then ((); 1) else 2;;
- : int = 1
The confusion comes from the fact that it doesn't behave the same way in match expressions: # match true with | true -> (); 1 | false -> 2;;
- : int = 1