Compiler tip

Consider the following trivial bit of OCaml:

open Printf
let _ =
  let array_max arr =
    let arr' = Array.copy arr; 
    Array.sort (fun a b -> b - a) arr';
    arr'.(0) in
  printf "max=%d\n" (array_max [|1;2;3;4;5|])

To me as a beginner this looks quite plausible, since I wrote something much like it, of course it should actually be:

   let arr' = Array.copy arr in

But the error from the compiler is strange:

make -k 
ocamlc -g -c
File "", line 9, characters 0-0:
Error: Syntax error
make: *** [testcase.cmo] Error 2
make: Target `testcase' not remade because of errors

That is actually one character beyond the end of my file!

So my top tip for today is, mysteriously vague error messages like this are probably a ; instead of an in somewhere. Emacs to the rescue:

M-x replace-regexp RET \(let.*\); RET \1 in RET

Hah! Now if only I could think of a way to invoke that automagically when I get 0-0 after C-c C-c

About Gaius

Jus' a good ol' boy, never meanin' no harm
This entry was posted in Emacs, Ocaml. Bookmark the permalink.

5 Responses to Compiler tip

  1. ruediger says:

    I hate it, too. The error messages of the ocaml compiler are often not very helpful. Another common error that produce confusing error messages is a “;” at the end of a function (instead of ‘;;’ or no semicolon at all)
    Another annoying thing is that the compiler always stops at the first error. Other compilers can show further error messages in the same run,…

    btw array_max without copying and more generic:

    let array_max arr = Array.fold_left max arr.(0) arr

    or better something like:

    let array_max = function
    | [||] -> raise (Invalid_argument "array_max")
    | arr -> Array.fold_left max arr.(0) arr

    • Gaius says:

      Cool, thanks for the tip! I think I actually did it with Array.to_list then sorted it and did hd but I needed an example for the error.

      I have to say, the Haskell compiler is much more helpful, tho’ in its own way it can be just as obscure sometimes šŸ™‚

  2. ygrek says:

    -pp camlp4o yields a more useful error message. Also better use let () = instead of let _ = in this case.

    • Gaius says:

      Ah, that is much nicer:

      make -k
      ocamlc -g -custom -annot -pp camlp4o -o test
      File "", line 8, characters 44-45:
      Parse error: "in" expected after [binding] (in [expr])

      I shall certainly add this to my standard Makefile template, thanks!

      What’s the difference between let _ = and let () = ? Do they both not mean, discard the results of this computation, I just want the side effects?

  3. ygrek says:

    # let f x = let _ = x in ();;
    val f : 'a -> unit =
    # let f x = let () = x in ();;
    val f : unit -> unit =

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s