Missing ocamlc warning flag for printf

Hi, I am new in this forum, and learning OCaml.

Problem:

The following code compiles and runs without warnings with ocamlc 4.07.0 (even with “-w +A”) but it doesn’t work (no output). Actually, it should yield an error message.

let seq = [“Hi”; “you”] in
printf “Test = %s\n”, seq ;;

The following code rightly yields an error message:

let seq = [“Hi”; “you”] in
printf “Test = %s\n” seq ;;

The problem is that the first printf code is written in typical C manner which is wrong in OCaml. How can I tell the compiler to warn me of such bugs?

Thanks for answers, and kind regards

The problem here is that this code:

let seq = ["Hi"; "you"] in
Printf.printf "Test = %s\n", seq ;;

is perfectly valid OCaml code which is printed as

- : (string → unit) * string list = (⟨fun⟩, [“Hi”; “you”])

in the REPL.

It is true that for a beginner, the relatively complex type of the expression means that this is probably an error. However, outside of a learning context, this is a perfectly sensible type and there is no reason to emit a warning here.

If you want to avoid thus kind of issues, an idiomatic solution is to use let () = ... when you are computing a side-effect only expression. For instance,

let () = 
  let seq = ["Hi"; "you"] in
  Printf.printf "Test = %s\n", seq

yields the following error

Error: This expression has type 'a * 'b but an expression was expected of type
unit

More theoretically, I imagine that it could be possible to write a beginner-friendly gate-keeping compiler plugin that raise an error when complex types arise in exercises but that would require some effort.

2 Likes

This helps a lot, thank you!

When I was learning, I found being very strict about doing the

let () = ...

thing was a good idea. I’ve always done it since.

1 Like