OCaml pattern-match syntax error without double semi colon

Viewed 126

I am quite new to OCaml, so apologies if this is a silly question. I have this OCaml file:

type tree =
  | Node of int * tree * tree
  | Leaf of int

let t = Node (3, Node (4, Leaf 1, Node (3, Leaf 5, Leaf 2)), Leaf 1)

let rec height t =
  match t with
  | Node (n, t1, t2) -> 1 + max (height t1) (height t2)
  | Leaf n -> 0

let _ = print_string (string_of_int (height t))

If I compile the file with ocamlc -o out my_file.ml, it compiles and runs as expected. However, if I try to run the file with ocaml < my_file.ml, I get a syntax error in the definition of my height function.

Placing a double semi colon after my height function as such:

let rec height t =
  match t with
  | Node (n, t1, t2) -> 1 + max (height t1) (height t2)
  | Leaf n -> 0
;;

Fixes the issue.

My questions are:

  1. Does OCaml require the double semi colons after a pattern-match only in interactive mode? That seems to be where the issue is coming from.
  2. Does ocamlformat know this? When I run ocamlformat on the file, it automatically places a double semi colon after my height function. I was confused as to why it was doing that until I got the syntax error.

Thanks in advance for the info! I've looked for answers to these questions but have been unsuccessful. I did find this blog which claimed the double semi colon is never necessary.

1 Answers

The usual way to run an OCaml file as a script is like this:

$ ocaml myfile.ml

If you run without a filename, as you are doing, ocaml enters an interactive mode in which it expects a person to be typing input with ;; indicating times when evaluation should occur. It does treat EOF as a syntax error in this mode since you have some unprocessed input at that point.

If you try the above command (without the < redirection) you should see the behavior you expect.

Here are my answers to your questions:

  1. OCaml doesn't actually require double semicolons anywhere. They are just a method to tell the interpreter (the REPL, also known as toplevel) that it should evaluate what you have typed most recently. This is one way to allow multi-line input.

  2. When I run ocamlformat I don't see any double semicolons in the output. I can't reproduce this observation of yours.

Here is what I see for the usual way of running a script:

$ ocaml myfile.ml
3$ 

Here is what I see when I run ocamlformat:

$ ocamlformat --enable-outside-detected-project myfile.ml
type tree = Node of int * tree * tree | Leaf of int

let t = Node (3, Node (4, Leaf 1, Node (3, Leaf 5, Leaf 2)), Leaf 1)

let rec height t =
  match t with
  | Node (n, t1, t2) -> 1 + max (height t1) (height t2)
  | Leaf n -> 0

let _ = print_string (string_of_int (height t))
Related