I'm learning OCaml and I'm struggling with this snippet:
let found = ref false
let () =
while not (Queue.is_empty q) && not !found do
let next = Queue.pop q
let () = found := (next.subtotal == total)
done
The second let inside the while body doesn't compile, the error says 'suggested in'. Indeed, when I add a 'in' after the first let, and I remove the 'let' from the second line, it compiles.
But I don't understand why this is needed? Doesn't Ocaml normally interpret a new 'let' as if there were an 'in' after the last line? E.g. when I move those two lets outside of the while block, they compile fine.
OCaml makes the distinction between local definitions and module-level definitions. In a local definition like
let g x =
let y = 2 in (...)
the name y
is only defined to be 2
inside the (...)
subexpression.
In particular, this means that the name is only a temporary name and accessing it later will be an error
let g x =
let y = 3 in
x + y
let error = y (* the name y is unknown in this scope *)
Contrarily, module-level definitions like
module N = struct
let x = 0
let y = 1
end
let ok = N.x (* [x] is a valid field of the module [N] *)
defines new field of the current (sub)module, which will be always be here (even if they are shadowed later).