1
votes

I am trying to teach myself OCaml. I've been going nuts over this one syntax trap. I'm told that you can string expressions together in sequence using ";" ie, expr1 ; expr2 executes the first expr, then the second, as expected. For some reason, I cannot get the interpreter to agree with the following input

let x = 5 ; let y = 7;;

Bizarrely if ONLY the first expr is a let, it works. So

let x = 5 ; 7;;

Passes, and evaluates to 7. Even worse, if I attempt to use parens to compose multiple sequences of statements where the let comes first, it still does not work. I.E.:

let x = 5 ; (let y = 7 ; 9);;

Is an error, even though it consists only of sequences where lets are the first expression. Can someone explain how to get this to work?

1

1 Answers

3
votes

One way to look at the problem is that let x = 5 isn't an expression. It's a top-level declaration; i.e., it declares a name x with a value 5.

The ; operator works for combining expressions, but not for declarations.

You don't need to string declarations together with ;. You can just put one after the other:

# let x = 5 let y = 7;;
val x : int = 5
val y : int = 7
# 

There is a completely different use of let in OCaml that is part of an expression. In that case it's followed by in:

# (let x = 4 in x + 1);;
- : int = 5

Since this is an expression, you can string several of them together with ;:

# (let x = 4 in x + 1); (let y = 6 in y + 1);;
Warning 10: this expression should have type unit.
- : int = 7

However, as the compiler is warning you, it's not idiomatic to string together arbitrary expressions. Normally you use ; with imperative code. With functional code it doesn't make sense. So the compiler expects all but the last expression to have type unit (which is used for imperative code that does something useful but doesn't return a useful value).