"Dissociated" ugly output with #install_printer in utop

Consider the following OCaml snippet :

type blue_int=Blue of int;;

let print_out_blue_int (dummy:Format.formatter) (Blue x)=
   (Format.open_box 0;Format.print_int(x);Format.close_box());;

#install_printer  print_out_blue_int;;

type red_int=Red of int;;

let print_out_red_int (dummy:Format.formatter) (Red x)=
   (Format.open_box 0;Format.print_int(x);Format.close_box());;

#install_printer  print_out_red_int;;

let example=List.map (fun i->(Blue i,[Red (i+30)]) ) [1;2;3;4;5;6;7];;

With utop 2.0.1 on ocaml 4.04.1, the output of the last line is the following horrible, unreadable jumble :

131232333434535636737val example : (blue_int * red_int list) list =                
[(, []); (, []); (, []); (, []); (, []); (, []); (, [])]    

With the ordinary toplevel however, one gets the correct answer

val example : (blue_int * red_int list) list =
  [(1, [31]); (2, [32]); (3, [33]); (4, [34]); (5, [35]); (6, [36]);
   (7, [37])]

Any ideas on how to fix/circumvent this ?

The first thing would be to use the Format.formatter argument in your printing functions, which could actually be a bit more readable if written like this:

let print_out_blue_int fmt (Blue x) =
  Format.fprintf fmt "@[%d@]" x

I’m not sure but it’s possible that utop actually uses a formatter different from stdout, which would explain the ugliness and dissociated printing.

What I think happens is that utop calls the list printer with a custom formatter. The list printer prints all the parentheses, brackets, etc… of the list, and uses your customs printers when it has to print the contents of the list, but unfortunately, you ignore the formatter and print on stdout instead so the output is strange.

I tried that and now I get identical outputs in ocaml and utop. Thank you