Why can't I use concatenation in Printf?

Why does:

let pr n = Printf.printf ("a 1 \n"); 1;;

work but not

let pr' n = Printf.printf ("a"^"1"^" "^"\n"); 1;;

gives error:

# let pr' n = Printf.printf ("a"^"1"^" "^"\n"); 1;;
Error: This expression has type string but an expression was expected of type
         ('a, out_channel, unit) format =
           ('a, out_channel, unit, unit, unit, unit)
           CamlinternalFormatBasics.format6

printf takes in a format string as its first argument, not a string; e.g. the following work:

let pr' n = Printf.printf "%s" ("a" ^ "1" ^ " " ^ "\n");;
let pr'' n = Printf.printf "%s%s%s%s" "a" "1" " " "\n";;

to add a little more to what mc10 wrote, the reason that printf takes a format string instead of just a string, is that this is the only way it can be compile-time-type-checked. Remember (always) that Ocaml doesn’t have any runtime type information – so a char and an int are represented the same way. The only way that we can have printf "%c" 'a' typecheck, while printf "%d" 'a' fail to typecheck (as it should), is if we can do the typechecking at compile-time. And to do that, we need for the first argument to be presented as a constant string, not an expression that evaluates at runtime.

1 Like
Printf.printf ("%d -> " ^^ " -> %d") 88 99

Use ^^ for format strings.

2 Likes