4 ms·
As someone without too much OCaml experience, how do you disambiguate this?
by tel 12y ago
As someone without too much OCaml experience, how do you disambiguate this?
- tomp 12y ago1) Ignore indentation (I intentionally wrote it to deceive, but similar examples could easily appear in real code). 2) `match` cases always bind to the innermost `match` statement. 3) Statement separators (`;`) are tricky. 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.
- tel 12y agoI figured the indentation was a lie, but didn't realize you would have to introduce something like begin...end to make it work the way it appears.
- mercurial 12y agoWhat would be the corresponding SML? I see how the way SML binds ';' would help here, but would it change anything about the last two badly indented matching? And it seems to provide you with the equivalent footgun if you attempt to do multiple side-effect operations in a match branch, which in my experience you want to do more often than you need to separate matches with ';'.
- deleted 12y ago[deleted]
- tomp 12y agoNot in my version of OCaml (OCamlWinPlus v1.9RC4, OCaml version 4.01.0): # if false then print_endline "false" ; match () with () -> print_endline "match";; match - : unit = ()
- p4bl0 12y agoSorry I realized my mistake and deleted my comment before I saw yours. FTR, I was saying that the ";" in the `then` clause of the if statement didn't end it, but it actually does. I see that arjunnarayan got this wrong too in his comment here: https://news.ycombinator.com/item?id=8498187 https://news.ycombinator.com/item?id=8498187.
- arjunnarayan 12y agoThere are two things to remember. The first is the match binding thing that tomp mentions in his reply. 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++.
- mercurial 12y agoI'll add that you need ';'-as-separator (you also use ';' in other places, such as when separating items in a list) only when calling functions which return 'unit', which is typically functions which perform side-effects (eg, close a file). That's usually a small portion of your program.
- p4bl0 12y agoif <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