Why it does’t work:
let a = 3 in let c = 2 + a;;
Why it does’t work:
let a = 3 in let c = 2 + a;;
let a = ... is the start of a definition for a variable a. If what you want is to define a binding for c only, you should start with let c =, for instance:
let c =
let a = 3 in
a + 2
(* here c = 5 and a is not bound *)
As to why it doesn’t work: the body after in is just a bare let definition, which can’t be evaluated as an expression (definitions create bindings but have no value themselves). You could have added a bit more and gotten something intelligible to the compiler:
let a = 3 in let c = 2 + a in a * c;;
(* neither a nor c is bound *)
This has no effect on the bindings of the program. It could be useful for side-effects, although it’s common to write let () = ... for top-level expressions used for side effects e.g.
let () = let a = 3 in let c = a + 2 in print_int c