Earlier quoted context omitted.
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 _"?
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.
>
> 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.