<!--wodoc:header-->

# Lwt in 5 minutes

<!--wodoc:end-->

## Principles

The Lwt library implements cooperative threads for OCaml. Cooperative threads are an alternative to preemptive threads (used in many languages and in OCaml's `Thread` module) that solve most common issues with preemptive threads: with Lwt, there is very limited risk of deadlocks and very limited need for locks. Lwt threads are even usable in programs compiled to JavaScript using Js\_of\_ocaml.

Lwt is based on the fact that most programs spend most of their time waiting for inputs, e.g., keys, data coming from sockets, and mouse events. Instead of relying on a preemptive scheduler that switches between threads at arbitrary moments, Lwt uses these waiting times as *cooperation points*. This means that instead of blocking (for example on a `read`), Lwt resumes another waiting thread, if there is one that is ready to continue. All you have to do is to use the cooperative version of each blocking function, for example `Lwt_unix.sleep` instead of `Unix.sleep` and `Lwt_unix.read` instead of `Unix.read`. If one of your computations takes a lot of time, it is also possible to manually insert cooperation points using the function `Lwt_main.yield`.


## Promises

Lwt defines a type `'a Lwt.t`, which is the type of promises. For example, the function:

```ocaml
val f : unit -> int Lwt.t
```
immediately returns a promise of `int`, that is, something that will eventually become an integer once the computation is finished.

The following code will launch the computation of `f ()` (asynchronously). If the code reaches a cooperation point (for example when the integer is requested via the network), it will continue the program (print "hello") and resume at a subsequent cooperation point, when the data is available.

```ocaml
let g1 () =
  let p = f () in
  print_endline "hello"
```

## Bind: Using the value of promises

It is possible to tell Lwt to execute a function once a promise is completed, by using the function:

```ocaml
Lwt.bind : 'a Lwt.t -> ('a -> 'b Lwt.t) -> 'b Lwt.t
```
For instance `Lwt.bind p h` will call the function `h` with the return value of the promise `p` as soon as the value is known. The expression `(Lwt.bind p h)` is also a promise (it may take time to complete). Function `h` must return a promise.

To create a (terminated) promise from a value, use `Lwt.return`.

Example:

```ocaml
let g2 () =
  let p = f () in
  Lwt.bind p (fun i -> print_int i; Lwt.return ())
```
Function `g2` calls function `f` to create a promise. Then it waits (in a cooperative manner) for the result, and prints the result. The expression `g2 ()` has type `unit Lwt.t`.


## Syntax extension

A PPX (and also camlp4) syntax extension is available.

```ocaml
let%lwt i = f () in
...
```
is equivalent to

```ocaml
Lwt.bind (f ()) (fun i -> ...)
```

## Examples


### A function that prints "tic" every second forever, without blocking the rest of the program

```ocaml
let rec tic () =
    print_endline "tic";
    let%lwt () = Lwt_unix.sleep 1.0 in
    tic ()
```
Replace `Lwt_unix.sleep` by `Lwt_js.sleep` if your program is running in a browser.


### Launching concurrent threads and waiting for their results

Suppose you have two cooperative functions:

```ocaml
val f : unit -> unit Lwt.t
val g : unit -> unit Lwt.t
```
The following code runs `f ()` and `g ()` sequentially:

```ocaml
let%lwt () = f () in
let%lwt () = g () in
...
```
The following code launches `f ()` and `g ()` concurrently, then waits for both to terminate before continuing:

```ocaml
let p1 = f () in
let p2 = g () in
let%lwt () = p1 in
let%lwt () = p2 in
...
```
To detach a thread, it is recommended to use

```ocaml
Lwt.async (fun () -> f ())
```
instead of

```ocaml
ignore (f ())
```
to catch exceptions properly.


### Serial and concurrent map on lists

The following map function runs all computation concurrently on all list elements:

```ocaml
let rec map f l =
  match l with
  | [] -> Lwt.return []
  | v :: r ->
      let t = f v in
      let rt = map f r in
      let%lwt v' = t in
      let%lwt l' = rt in
      Lwt.return (v' :: l')
```
whereas the following one waits for the one to complete before launching the next one:

```ocaml
let rec map_serial f l =
  match l with
  | [] -> return []
  | v :: r ->
      let%lwt v' = f v in
      let%lwt l' = map_serial f r in
      Lwt.return (v' :: l')
```

## More documentation

Have a look at `Lwt's manual` for more details about Lwt. You will learn how to handle exceptions (using `Lwt.fail` and `Lwt.catch` or `try%lwt`). You will also learn for example how to create a thread that waits until it is awaken (using `Lwt.wait` and `Lwt.wakeup`).
