You would typically write your main loop as a recursive function, which evaluates to a thread, then pass that thread once to Lwt_main.run
. Here is a small example:
let () =
let rec echo_loop () =
let%lwt line = Lwt_io.(read_line stdin) in
if line = "exit" then
Lwt.return_unit
else
let%lwt () = Lwt_io.(write_line stdout line) in
echo_loop ()
in
Lwt_main.run (echo_loop ())
This can be compiled and run with:
ocamlfind opt -linkpkg -package lwt.unix -package lwt.ppx code.ml && ./a.out
In rough terms, this is what happens in the above code:
echo_loop ()
is applied in the argument of Lwt_main.run
. This immediately begins evaluating Lwt_io.(read_line stdin)
, but the rest of the code (starting with the if
expression) is put into a closure to be run once the read_line
completes. echo_loop ()
then evaluates to this combination of an ongoing read_line
operation followed by the closure.
Lwt_main.run
forces your process to wait until all that completes. However, once the read_line
completes, if the line is not exit
, the closure triggers a write_line
operation, followed by another closure, which calls echo_loop ()
recursively, which starts another read_line
, and this can go on indefinitely.