Sigh, this is out of date. This was probably written before we split
async into three parts: the core, the unix-dependent bits, and
"extra", everything else.
So one might imagine that reading each of
async/{core,unix,extra}/
std.ml might be a good idea. But it turns out
they're basically commentless.
I didn't realise quite how bad the state of our documentation was --
I'll try to find some time to work on it.
There is some stuff in examples/, but sadly some of that is out of
date as well. It's not worthless though, especially if you consider a
couple of points that might help modernise the code:
1. Prefer pipes over streams -- they have different semantics, but
Pipe's are nicer, and it can be pretty easy to make mistakes with
Streams.
2. Prefer >>= over upon/>>>. There is a pretty simple translation:
foo
>>> fun a ->
bar
>>> fun b ->
baz
>>> fun c ->
quux
->
foo
>>= fun a ->
bar
>>= fun b ->
baz
>>| fun c ->
quux
This gives the whole block a deferred result type. For library
functions, this is only really a good thing, since your callers can
bind on the result, or can throw it away with [whenever] if they don't
want to wait for your function to finish (whenever is soon to be
renamed don't_wait_for).
For blocks at the top-level of your code, there isn't as much benefit
(you don't have any callers), but it's still nice to do it for
consistency.
[A bit more background for the interested:
It used to be the case that recursive loops written with bind, e.g.:
let loop () =
if predicate then Deferred.unit else
Clock.after (sec 1.)
>>= fun () ->
loop ()
would take space proportional to the depth of recursion. So one would
have to write using upon, where
let loop () =
if predicate then () else
Clock.after (sec 1.)
>>> fun () ->
loop ()
and you had no way of telling when the loop was done -- if you wanted
to do that, you had to create the deferred explicitly:
Deferred.create (fun ivar ->
let loop () =
if predicate then Ivar.fill ivar () else
Clock.after (sec 1.)
>>> fun () ->
loop ()))
But this is no longer necessary, and the bind loop should be
considered the best style in almost all circumstances. The reason is a
really neat trick, but this email is already too long -- I'll try to
write a blog post about it.
]