Missing comments?

Showing 1-3 of 3 messages
Missing comments? Rudi Grinberg 9/19/12 11:52 PM
The dummies guide to async says: "Start by looking at
async/lib/std.ml, which has comments that should guide you through
reading the rest of it."

However, looking at:
 I don't see anything.

Is this the wrong file? I can't find the comments anywhere else either.
Re: Missing comments? David House 9/20/12 12:22 AM
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

2. Prefer >>= over upon/>>>. There is a pretty simple translation:

>>> fun a ->
>>> fun b ->
>>> fun c ->


>>= fun a ->
>>= fun b ->
>>| fun c ->

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

[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.
Re: Missing comments? Rudi Grinberg 9/20/12 2:46 PM
Thanks for the quick and informative reply David. The examples seems
very useful for now and the examples that I've tried
seem to compile and work as well. So it's not totally outdated. A blog
post about Async would be very welcome!