OCaml Syntax Error fixed by double semicolon

北慕城南 提交于 2019-12-08 11:28:19

问题


I'm sorry for asking such a basic question here, but I'm getting a syntax error when trying to compile the following code,

let sum_of_squares_of_two_largest x y z =
    let a :: b :: _ = List.sort (fun x y -> -(compare x y)) [x; y; z] in
    a * a + b * b;

let rec factorial n =
    if n = 0 then 1 else n * factorial (n - 1);

let e_term n = 1.0 /. float_of_int (factorial n);

let rec e_approximation n =
    if n = 0 then (e_term 0) else (e_term n) +. (e_approximation (n - 1));

let rec is_even x = if x = 0 then true else is_odd (x - 1);
    and is_odd  x = not (is_even x);

let rec f_rec n =
    if n < 3 then n else f_rec(n - 1) + 2 * f_rec(n - 2) + 3 * f_rec(n - 3);

The uninformative compiler tells me there is syntax error on line 19, which is the last line of the file.

File "source.ml", line 19, characters 0-0:
Error: Syntax error

That is, line 19 is a blank line, only with a new-line character.

I can "fix" this syntax error by adding ;; at the end of each function definition instead of the ;.

Am I missing a semicolon somewhere?


回答1:


As has been pointed out in the comments, ; is not a statement terminator like in many other (Algol-inspired) languages, but a sequence operator. It takes two values, throws away the first (but warns if it is not unit) and returns the second. a; b is therefore roughly equivalent to let _ = a in b.

You say you would have expected the error to say something like ';' is missing the second operand., but the thing is: it doesn't. Not until it reaches the end of the file (at which point the error message certainly could have been more intelligent, but probably not very accurate anyway).

What follows each ; in your code looks like a perfectly valid expression that might yield a value. For example, if let rec factorial n = ...; had been let rec factorial n = ... in 2 The value of the expression would have been 2. The problem here, from the compiler's point of view, is that it runs out of file before the expression is finished.

As you've also found out, ;; actually is a statement terminator. Or perhaps a toplevel definition terminator is a better term (I don't know if it even has an official name). It's used in the REPL to terminate input, but isn't needed in normal OCaml code unless you mix toplevel definitions and expressions, which you never should.

;; can still be useful for beginners as a "bulkhead", however. If you put just one ;; in place of a ; in the middle of your file, you'll find the compiler now points the error location there. That's because ;; terminates the definition without the preceding expression being complete. So you now know there's an error before that. (Actually in the preceding expression, but since your entire file is one single expression, "before that" is really the best we can do).



来源:https://stackoverflow.com/questions/48045645/ocaml-syntax-error-fixed-by-double-semicolon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!