5 ms·
This is also great cheat sheet for someone still getting used to the OCaml syntax. I usually advise people to pretend that double semicolons don't exist for an
by jordwalke 11y ago
This is also great cheat sheet for someone still getting used to the OCaml syntax.
I usually advise people to pretend that double semicolons don't exist for anything but the interactive top level. In source files, you can forget about double semis entirely as long as you just remember to always assign the result of an imperative statement to the dummy "_" name.
let _ = print_string "hi"
Then you can think of ;;<enter> as merely a fancy way of hitting the return key in the interactive REPL. There's also a way to use a different key mapping (control+enter) instead of ;; in utop, so there would be no reason to even acknowledge the existence of double semis.
https://github.com/diml/utop/issues/131 https://github.com/diml/utop/issues/131
- snuxoll 11y agoThis is one thing I'm on the fence about F# doing "better", double semis are replaced by requiring you do something with your result, either assigning the result of piping it to the "ignore" builtin.
- jordwalke 11y agoSo in this case, you can just imagine you are using F# then you should be happy with OCaml. (Configure utop as I suggested for the full effect). That should at least clear up a small distraction for you so that you can make your decision based on fundamental strengths/weaknesses instead of aesthetics made inconsequential by configuration.
- LeonidasXIV 11y agoIn some way, OCaml can be thought of doing this as well: https://xivilization.net/~marek/blog/2014/12/28/reinventing-the-semicolon-operator/ https://xivilization.net/~marek/blog/2014/12/28/reinventing-... You can consider the ; operator as a binary operator evaluating the left side, throwing away the result and then avaluating the right side and returning that result.
- mercurial 11y agoI never use double semi colons for anything, but you'd use a simple semi colon after that statement: let msg = "hi" in print_string msg; What's better about using "let _"?
- smosher_ 11y agoThe idea is you can write this: let _ = print_string "foo" let _ = print_string "bar" at the top level. Of course you can write let msg = "foo" in print_string msg let msg = "bar" in print_string msg (which isn't at issue, except no semicolons are needed.) But you can't write print_string "foo" print_string "bar" without semicolons.
- mercurial 11y ago> The idea is you can write this: > > let _ = print_string "foo" > let _ = print_string "bar" > > at the top level. Ah. Well, the solution is not use "let _" or ";;", the solution is to avoid sociopathic code like that. Module definition with built-in, unavoidable side effects are evil.
- jordwalke 11y agoSingle semicolons simply evaluates several expressions and returns the last one, but if you use them in a module definition (like every file is by default), you'll be coerced into using double semis. The advantage over your version (with the single semicolon) is that in your version, you cannot now create a standard exported module value binding after that single semicolon, because the parser interprets that next let binding as a continuation of the single semicolon expression, so your only hope is to use double semis to escape back to normal module body parser context. Function bodies (or any other expression really) don't have that same issue, but I might suggest avoiding single semicolons even in that case so that you have fewer edge cases to memorize. Here is the simplest possible convention I can think of that requires the smallest amount of memorization: - Forget about all semicolons, single or double (just think of ;; as a way to press enter in the top interactive REPL). - Module bodies (like every file by default) are just exporting a series of bindings. If you want to evaluate an imperative command inside a module body, export its result to "_". - Function bodies are expressions. If you want to evaluate an imperative command inside a function body (or any other expression), use `let in` like you would for any other temporary variable, but use the variable name "_" and simply don't use it.