Module Async.Std

module Std: sig .. end
The common definitions for Async. Async programs typically only open Async.Std, the modules within Async.Std are typically referred to explicitly.


Blocking functions


module Deferred: sig .. end

'a Deferred.t is the most important type in the Async library. An 'a Deferred.t represents a value that will become determined when an asynchronous computation completes.

A deferred can be "undetermined" or "determined". A deferred that is undetermined may at some point become determined with value v, and will henceforth always be determined with value v.

Any Async function that needs to wait for something to happen (i.e. "block") will return a Deferred.t. The function itself will return immediately, allowing the calling program to continue to do other tasks. Thus blocking functions should have the type 'a -> 'b Deferred.t.

val (>>=) : 'a Deferred.t ->
('a -> 'b Deferred.t) -> 'b Deferred.t
>>= is used to chain blocking functions together. x >>= g will cause g to be run after x is determined, with the value of x as input. The deferred returned by (>>=) will become determined when g completes.

There are two common stylistic idioms used when using >>=. The first is that many functions can be joined together with >>= without parentheses. For example, if one wants to wait for x to be determined, and then run f on the result, and then run the blocking function g on the output of f, and then run the blocking function h on the result of f, one would write the following:

    x >>= f >>= g >>= h
    
When splitting these invocations on multiple lines, one typically writes
    x
    >>= f
    >>= g
    >>= h
    

The second idiom is that anonymous function definitions are typically written inline and without parentheses. For example, in the above sequence, if we wanted to print the value that is passed from f to g, we would write:

    x >>= f >>= fun y ->
    print_endline y;
    g y >>= h
    
This is the same as
 x >>= (f >>= (fun y -> print_endline y; (g y >>= h))) 
but the way it is written looks more like imperative code: first run f on x and call the result y. Then print y. Then run g on y and pass the result to h.

It is helpful to think of the pattern

    f x >>= fun y ->
    
as being analogous to
    let y = f x in
    
This is why (>>=) is also called "bind".
val (>>|) : 'a Deferred.t -> ('a -> 'b) -> 'b Deferred.t
>>| is similar to >>=, but it is used for non-blocking functions. It can be mixed to chains of functions joined by >>=. For example, the provided function WordCount.App.Make.main is implemented as follows:
    Deferred.List.map Reader.file_lines filename
    >>| List.flatten
    >>= map_reduce
    >>= output
    

filenames is a list of file names: ["foo.txt"; "bar.txt"]. Deferred.List.map is like List.map except that it works with blocking functions like Reader.file_lines.

The output of this line is a list containing a list of lines of "foo.txt" and a list of lines of "bar.txt". We want to combine these into a single list, so we pass them through the List.flatten function. Since List.flatten is non-blocking, we use >>|. We then pass the combined list of lines to the map_reduce function (using >>= since map_reduce is a blocking function), and finally pass the results of map_reduce to the (blocking) output function.

Be aware that >>| does not play as nicely with anonymous functions as >>= does. The following code does not work:

    f x >>| fun y ->
    print_endline y;
    g y >>= h
    
A good test of your understanding of the >>= and >>| syntax would be to explain why.
val return : 'a -> 'a Deferred.t
return is used to create a Deferred.t that is immediately determined with the provided value. It is often used to designate the return value of a function implemented using a chain of >>= expressions. For example:
    let run_fgh x =
      f x >>= fun y ->
      g y >>= fun z ->
      h z >>= fun _ ->
      return (y,z)
    
will first run f on x; when that completes it will run g, and then h. The result of the deferred created by run_fgh will be the pair (y,z).

Combining Deferred.ts


val don't_wait_for : unit Deferred.t -> unit
a convenience function for ignoring a deferred value
val never : unit -> 'a Deferred.t
a deferred that is never determined

See also Deferred.both, Deferred.any and Deferred.all.

Deferred data structures and communication


module Ivar: sig .. end
Ivars are like write-once refs.
module Pipe: sig .. end
A Pipe is a first-in first-out communication channel.

The Deferred.List contains blocking versions of many familiar List module functions.

Time and timeouts



Note: Use the function Core.Std.sec to create Core.Std.Time.Span.ts. It takes in a float t and produces a Time.Span.t representing t seconds.
val after : Core.Std.Time.Span.t -> unit Deferred.t
a deferred that becomes determined after the given amount of time
val with_timeout : Core.Std.Time.Span.t ->
'a Deferred.t -> [ `Result of 'a | `Timeout ] Deferred.t
with_timeout t x will become determined with `Result v if x becomes determined with v within the timespan t. Otherwise, the value will be `Timeout.
val every : ?start:unit Deferred.t ->
?stop:unit Deferred.t ->
Core.Std.Time.Span.t -> (unit -> unit) -> unit
every t f schedules f to be executed every t seconds. If the arguments ?start or ?finish are supplied, f will not be scheduled before start becomes determined or after finish does.

Input and output in Async


val printf : ('a, unit, string, unit) format4 -> 'a
This function is an Async-friendly version of Printf.printf, which is very useful for debugging.
module Reader: sig .. end
The Reader module (not to be confused with Pipe.Reader) is for doing network and file input.
module Writer: sig .. end
The Writer module (not to be confused with Pipe.Writer) is for doing network and file output.
module Socket: sig .. end
The socket module contains types necessary for working with the Tcp module.
module Tcp: sig .. end
Functions for connecting to remote hosts over the network.

Error handling


val try_with : (unit -> 'a Deferred.t) ->
('a, exn) Core.Std.Result.t Deferred.t
try_with f runs the blocking function f, and returns Core.Std.Ok x if f () returns x. If f () raises the exception e, then try_with f returns Core.Std.Error e.