[E-Lang] stl-0.8.9k: Multi-vow when-catch

Mark S. Miller markm@caplet.com
Fri, 19 Jan 2001 23:23:20 -0800


As a result of reviewing earlier drafts of MarcS's E in a Walnut, and going 
through the examples, I was distressed to see a surprisingly large amount of 
devoted to explaining how to postpone an action until several promises 
resolve.  Unfortunately, as the simple examples made clear to me, this was 
all well motivated, and was something that would indeed need to be explained 
early to the concurrent E programmer.

At some point it became clear to us that the multi-promise-resolution 
abstraction MarcS had invented could be packaged up into a natural extension 
of the when-catch sugar we already had, resulting in the multi-vow 
when-catch http://www.skyhunter.com/marcs/ewalnut.html#SEC39 .  From the 
user's point of view, there is only one case:

    when (args...) -> funcname(params...) {
        ...body...
    } catch problem {
        ...handler...
    }

The number of args must match the number of parameters.  When this number is 
one, then we simply have our old when-catch, which packages everything 
starting from funcname on into a closure (named, not surprisingly, 
funcname), and uses the whenResolved message to arrange for this closure to 
get invoked when the argument has resolved.

When there are more arguments, then it expands to a single vow when-catch as 
follows:

    when (aPromise, bPromise) -> done (a, b) {...

expands to

    when (promiseAllFulfilled([aPromise, bPromise])) -> done ([a, b]) { ...

which then expands further in the conventional fashion.  
promiseAllFulfilled, like MarcS's promiseAllResolved 
http://www.skyhunter.com/marcs/ewalnut.html#SEC58 , takes a list of possibly 
unresolved values, and return a promise for a corresponding list of resolved 
values.  Should all the element become fulfilled, the returned promise 
resolves to the list of fulfilled elements.  Should any of the elements 
resolve to broken, the returned promise resolves to one of these broken 
promises.

They differ regarding when they fulfill the returned promise, should one of 
the elements resolve to broken.

promiseAllResolved, as its name implies, resolves its returned promise only 
once all the element promises have been resolved, regardless of how they 
resolve.

promiseAllFulfilled, since it is promising a fulfilled list, as soon as any 
element promise is broken, it knows it can't keep its promise, and so it 
resolves its returned promise to broken without waiting for the other 
elements to resolve.  This is the right behavior for multi-vow when catch, 
as a broken element would cause the catch clause to be invoked in any case, 
so there's no reason to wait (possibly forever) for the other elements to 
resolve.


        Cheers,
        --MarkM