Eio 0.1 - effects-based direct-style IO for OCaml 5

To get in the direction of concrete examples I know about: one design pattern that isn’t being served well today is on-demand initialization of library/program constants. (I think I’ve discussed this in the past with @dbuenzli and his work also uses this.) With Sequential OCaml, libraries or programs can privately define something like

let my_config =
  let config = lazy (Config.parse Config.config_file_path) in
  fun () -> Lazy.force config

(* several library functions do this *)
let some_function ... =
  if (my_config ()).foo then ... else ...

(Note: maybe people use a different style where Config.config_file_path is passed around as a context parameter, etc, in fact this line may be sitting within a functor parametrized on Config or what have you. I think the underlying idiom remains similar if this is not a toplevel declaration, but a configuration value explicitly passed around.)

I don’t know how to do this well in a way that works with Multicore OCaml today.

Using lazy in this style is now invalid (a programming mistake) as soon as the library code that reads the configuration may run in several domains. (And the library author doesn’t know if it will, the client may or may not use Parmap around this library, etc.)

Some ways to do this not well with the stdlib currently are to do:

(* repeats computation on races,
    what if configuration gets mutated between calls? *)
let my_config =
  let r = Atomic.create None in
  fun () -> match Atomic.get r with
  | Some config -> config
  | None ->
    let config = Config.parse Config.config_file_path in
    Atomic.set r config; config

(* blocks a complete domain, not what we want *)
let my_config () =
  let m = Mutex.create () in
  let thunk = lazy (Config.parse Config.config_file_path) in
  fun () ->
    Mutex.lock m;
    let@ () = Fun.protect ~finally:(fun () -> Mutex.unlock m) in
    Lazy.force thunk

We need a common abstraction to do something like the second version, but will work well with user-defined concurrency libraries.

2 Likes