Version française
Home     About     Download     Resources     Contact us    
Browse thread
Printf and "%a"
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Aaron Bohannon <bohannon@c...>
Subject: Printf and "%a"
The behavior of the "%a" format string in the Printf module does not 
seem to match the documentation.

# Printf.printf "%a" ;;
- : (out_channel -> '_a -> unit) -> '_a -> unit = <fun>
# Printf.sprintf "%a" ;;
- : (unit -> '_a -> string) -> '_a -> string = <fun>

The first type exactly matches the one that would be expected based 
upon reading the documentation.  The second type surprised me because 
the only documentation for sprintf is:  "Same as Printf.fprintf, but 
instead of printing on an output channel, return a string containing 
the result of formatting the arguments."

On an intuitive level, I can understand that it makes some sense to 
require a user-defined printer that returns a string in the case of 
sprintf.  However, the need for the function to first take a unit 
argument is not intuitive at all to me, and it seems to hinder the 
usefulness of the mechanism because it is not likely that one would 
have already defined a printer function that has that type and can 
simply be plugged in.  So I guess one will generally have to write:

   let s = Printf.sprintf "...%a..." (fun () -> thing_to_string) thing ;;

Then there's kprintf:

# fun k -> Printf.kprintf k "%a" ;;
- : (string -> 'a) -> (unit -> 'b -> string) -> 'b -> 'a = <fun>

It appears to follow the behavior of sprintf, but I read a comment in 
the newsgroup archives that indicated there was more complexity with 
the interaction of kprintf and "%a" format strings.  Does this 
interaction ever change the type of the user-defined printer that is 
expected by kprintf?  Again, the documentation misleadingly silent 
about "%a" patterns used with kprintf.

--
Aaron Bohannon
http://www.cis.upenn.edu/~bohannon/