Hacker News new | ask | show | jobs
by jordwalke 4018 days 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
2 comments

This 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.
In some way, OCaml can be thought of doing this as well: 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.
So 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.

I 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 _"?
Single 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.

The 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.
> 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.

You need at least one module that does something at top-level, otherwise your program won't do anything.
For serious development, yes, but consider the people who are learning OCaml. One of the first programs is going to be some kind of side effecting hello world etc.