Missing comments?

24 views
Skip to first unread message

Rudi Grinberg

unread,
Sep 20, 2012, 2:52:00 AM9/20/12
to ocaml...@googlegroups.com
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:
https://bitbucket.org/yminsky/ocaml-core/raw/8808e3a2571f/base/async/lib/std.ml
I don't see anything.

Is this the wrong file? I can't find the comments anywhere else either.

David House

unread,
Sep 20, 2012, 3:22:18 AM9/20/12
to ocaml...@googlegroups.com
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.
]

Rudi Grinberg

unread,
Sep 20, 2012, 5:46:14 PM9/20/12
to ocaml...@googlegroups.com
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!
Reply all
Reply to author
Forward
0 new messages