BearAqua
BearAqua

Reputation: 528

Separating multiple `let` declarations followed by a single `let in`expression in OCaml

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 lets 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

Answers (2)

ivg
ivg

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

melpomene
melpomene

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

Related Questions