Sequence and parallel combinators
I've been re-reading the Lambda, the ultimate... papers again for my podcast. These papers show how functions and function calls can model many of the imperative constructs in programming languages. One practical application of that is to build a compiler whose main construct is the function call, which is a common way to implement Scheme.
In this challenge, we'd like to make constructs for two kinds of execution: sequential and parallel.
Imagine we had actions a
and b
, which are functions which depend on when they are called. If we want them to run in order, meaning a
completes before b
begins, we can create a new action a>b
, like so:
(def a>b (sequential a b))
We can then call (a>b)
to run them in the right order.
If we want them to run in parallel, we can similarly write:
(def a-b (parallel a b))
Then when we call (a-b)
, they will run "at the same time".
Your task is to write sequential
and parallel
, using threads (or some other construct) if needed.
Bonus: devise a way to have return values that you can block on. sequential
should act like do
and return the return value of the last argument. parallel
should return both return values.
Please submit your solutions as comments on this gist.
Struggled with this one, problem is slightly harder than it looks. Issue is that if we're ordering tasks like this, we really need to be thinking about side-effects. And if people haven't hit the issue yet: Laziness and side-effects do not mix well.
Worth thinking about:
pcalls
, you're getting a lazy-seq of values. The calls aren't going to start until they're needed (except the first). At least conceptually you expect work for the calls to either be done when you deref the future, or the work to be ongoing and your program to block at that point (at least in cases I can think of). You need something likedoall
to force side-effects.pcalls
, how does that play with chunking?