Concurrency: Lwt and Eio
Key functions: Lwt.return, Lwt.bind / >>=, Lwt.map / >|=, Lwt.join, Lwt.all, Lwt.pick, Lwt.choose, Lwt.catch, Lwt_list.map_p, Lwt_stream, Lwt_mvar.
37.1 Lwt — monadic cooperative concurrency (mature, widely used)
Key functions: Lwt.return, Lwt.bind / >>=, Lwt.map / >|=, Lwt.join, Lwt.all, Lwt.pick, Lwt.choose, Lwt.catch, Lwt_list.map_p, Lwt_stream, Lwt_mvar.
open Lwt.Syntax
let fetch_both () =
let* () = Lwt_io.printl "starting" in
let a = Lwt_unix.sleep 1.0 |> Lwt.map (fun () -> "a") in
let b = Lwt_unix.sleep 1.0 |> Lwt.map (fun () -> "b") in
let* ra = a and* rb = b in (* concurrent: ~1s total *)
Lwt_io.printlf "%s %s" ra rb
let () = Lwt_main.run (fetch_both ())37.2 Eio — direct-style, effects-based I/O (OCaml 5)
Structured concurrency with Eio.Switch — fibers cannot outlive their switch.
Capabilities: access to network/fs/clock passed explicitly via env.
Eio.Fiber.fork, Fiber.all, Fiber.any, Eio.Promise, Eio.Stream, Eio.Mutex.
Parallelism: Eio.Domain_manager.run, Eio.Executor_pool.
Backends: io_uring on Linux, posix, Windows.
let main env =
let clock = Eio.Stdenv.clock env in
Eio.Fiber.both
(fun () -> Eio.Time.sleep clock 1.0; Eio.traceln "fiber A")
(fun () -> Eio.Time.sleep clock 1.0; Eio.traceln "fiber B")
let () = Eio_main.run main(* Eio TCP echo server *)
let handle flow _addr = Eio.Flow.copy flow flow
let () = Eio_main.run @@ fun env ->
Eio.Switch.run @@ fun sw ->
let net = Eio.Stdenv.net env in
let sock = Eio.Net.listen net ~sw ~backlog:5 ~reuse_addr:true (`Tcp (Eio.Net.Ipaddr.V4.loopback, 8080)) in
Eio.Net.run_server sock handle ~on_error:(fun e -> Eio.traceln "error: %a" Fmt.exn e)37.3 Async (Jane Street)
Deferred.t monad, similar to Lwt; used with Core.
37.4 Choosing
huge ecosystem, OCaml 4 & 5, js_of_ocaml Jane Street stack direct-style (effects) new OCaml 5 projects, structured concurrency lightweight alternative scheduler