Problems after switching to Base

Complete newbie here, I just added Base to my project but now using printf just stopped working:

 ((name hello_print)
  (libraries (base))))
open Base ;;

let pr_str_list xs =
  List.iter (Printf.printf "%s, ") xs ;;

Reading the Base documentation it seems that Printf in Base is aliased to Caml.Printf or something?

How do I need to rewrite my program above so that it works with Base?

This is because Base doesn’t include IO. You need Stdio for that, at which point, this works.

open Base
open Stdio

let pr_str_list xs =
  List.iter ~f:(printf "%s, ") xs

Thanks for the quick response @Yaron_Minsky, that solves the issue. :slight_smile:

One more thing:

Why does this work

open Base
open Stdio;;

print_endline "Parsing Transactions..."

But this doesn’t?

open Base
open Stdio

print_endline "Parsing Transactions..."

According to this Reddit thread double semicolons shouldn’t be needed outside a REPL?

You don’t need double-semis if you use a top-level binding.

open Base
open Stdio

let () = print_endline "Parsing Transactions..."
1 Like

It doesn’t seem like you want to mix modules here, but if you did you could do either:

let module S = Some_module in

S.print_endline "..." ...; (* Module's print_endline *)
print_endline "..." .. (* Std print_endline *)


lets special_print_endline = Some_module.print_endline in

special_print_endline "" ...;
print_endline "" ...

Is this a temporary issue, or a design policy for Base as opposed to Core? Will Base.Printf provide more functions, such as printf, in the future? Or will some of those functions be split out of Core.Printf? Just curiosity.

It’s a design policy of Base, and I could imagine doing the same eventually
for Core and Core_kernel. Separating out the IO into a separate library is
I think sensible, and it would be better if Core had always done that. This
is why Async has to shadow a bunch of things in Core, when really it would
be better if one had to open something separate to get IO.

For what it’s worth, the out-channel writing printf is now in Out_channel,
which is a sensible place for it anyway, as well as in the toplevel of


1 Like

Thanks @Yaron_Minsky. That makes sense. It fits with the overall design philosophy of Core, I think.