Reputation: 528
This question elaborates on OCaml syntax trap: multiple lets using separators.
In terms of programming imperative OCaml, how does one have multiple let
statements that runs before a single let ... in
without changing all declarations into expressions?
For example,
let f x = x + 1
let g x = x + 2
let h x = x + 3
compiles with no problem, but
let f x = x + 1
let g x = x + 2
let h x = x + 3 in (Printf.printf "%d \n" (f (h (g 3))) ; ())
doesn't work, because the first two are declarations whereas the last one is an expression. The same observation applies to variables. One way to correct this error is to nest change the first two let
s into expressions and nest the let...in
. However, this seems quite tedious and awkward:
let f x = x + 1 in
let g x = x + 2 in
let h x = x + 3 in (Printf.printf "%d \n" (f (h (g 3))) ; ())
Alternatively, one could envision a long OCaml source code file starting with multiple let
declarations of global variables, and a single let...in
expression in the middle. In that case, it seems like a ;;
is necessary to terminate the declarations on top so that the let... in
works, but using the ;;
is advised against by the documentation.
Is there another way to write this (more elegantly)?
Upvotes: 0
Views: 482
Reputation: 35210
It would be much easier to understand OCaml syntax if we will stick to the grammar in which a top-level item could be only a definition1 which has the form
let <patt> = <expr>
that has the following semantics -- compute expression <expr>
and apply it to the pattern <patt>
, if there is a match, then enrich the global context with the variables bound in the pattern <patt>
.
Therefore, the conventional solution to your problem would be
let f x = x + 1
let g x = x + 2
let h x = x + 3
let () =
Printf.printf "%d \n" (f (h (g 3)));
()
Due to historic reasons, OCaml allows expression such as 1
, "hello"
or let x = 1 in x + x
on the toplevel, provided that you separate them using ;;
. Mostly this is due to the compatibility with the interactive top-level system, so that you can use OCaml as a calculator. I would advise against using ;;
in real OCaml programs, that are written for the compiler consumption.
1) You call them declarations, though they are actually definitions, however for our case, it doesn't matter.
Upvotes: 3
Reputation: 85767
I don't know if it's more elegant, but
let f x = x + 1
let g x = x + 2
let _ = let h x = x + 3 in Printf.printf "%d \n" (f (h (g 3)))
compiles and runs.
Upvotes: 1