awaitEval in Concurrent Haskell

Colin Runciman
Thu, 06 Feb 2003 17:52:28 +0000


>Next idea is to have a function
>	await :: a -> b -> b
>which is rather like 'seq' except that it waits for its first argument
>to be evaluated, whereas 'seq' evaluates it.  Then you could write a new
>version of 'length' which used await before every case expression. Is
>that what you had in mind?  A bit fragile, isn't it?
Something like await would  be enough I think.  It would not be 
necessary to write new
versions of all the functions to be data driven, just a single 
(overloaded) function
to convert a demanding function into a data-driven one. Something like this:

asEvaluated xs = await xs (case xs of
                                           (x:xs) -> asEvaluated x : 
asEvaluated xs
                                           []  -> [])

dataDriven f = f . asEvaluated

assert p xs = thread (... dataDriven p xs ...) xs

>How to implement 'await'.  We thought of three ways:
>1.  Implement a primitive checkEval :: a -> Bool, which tells whether
>something is evaluated; if not, it yields to other threads, as well as
>returning False.  So now you can have a busy-wait version of await thus:
>	await x y = case checkEval x of
>			True -> y
>                              False -> await x y
>2.  Implement await directly, by putting the thread in a pool of threads
>that the scheduler checks at regular intervals. They each just "watch" a
>thunk.  Still a busy-waiting solution.
>3.  Do the "right thing": implement 'await' by copying the thunk,
>replacing it by a "smart indirection" which also points to the
>non-suspended thread. When the indirection is evaluated, it just puts
>the suspended thread in the runnable pool before entering the thunk.
>Actually, this is probably no harder than (2).
I agree that 2 seems the most straightfoward, and not quite so busy as 1.
Unless I am misunderstanding 3 it could lead to problems if scheduling
can occur before evaluation of the thunk reaches a normal form.

>Now, it's true that it would take Simon or I less time to implement one
>of these than it would take your student to do, but we have so *many*
>things to implement, and each takes time.  And you will probably change
>your mind several times about what the right design should be (that's
>what research is like).  So there's a lot to be said for the wading in
The formula for implementation time is roughly
    initiationRites + inherentDifficulty / skillLevel
and I am pretty sure we could get by with just the await primitive.
So if there is any way you could find an early slot to do a
basic implementation of await, it would be much appreciated.

>What I can promise is that we'd turn around questions rapidly.
If we do end up trying to define await for ourselves, which source
files should we expect to modify and are there any likely pitfalls
in the subsequent rebuilding?

Colin R