simonmar / monad-par

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Offer a version of put that can run multiple times

treeowl opened this issue · comments

There are some pretty reasonable situations where it makes sense to allow multiple threads to race to fill the same IVar. Currently, that programming model is prohibited. The lvish package provides limited support by using == to test for equality on a second put. I think this seems an eminently reasonable thing to do. I also think it would also make sense to offer an "unsafe" version that simply does nothing when the IVar is full. I think implementation probably shouldn't be too terrible; one way would be to change the Put constructor to

           | forall a . Put (IVar a) a (Bool -> Trace)

This informs the continuation of whether the IVar was already full.

Do you have an example where this would be useful? It would be unsafe in the sense that you could write non-deterministic things using it.

Yes. I actually considered something a bit like this in unordered-containers (for alterF), but rejected it for domain-specific performance reasons. It can happen that several different "pure" computations are each capable of capturing information that will be useful for the others. It's possible to take advantage of this by using unsafeDupablePerformIO to write that information to a reference the other computations can access. But if multiple-put is absolutely prohibited, this won't work.

Ok, it seems like you might want two versions - unsafeTryPut that doesn't overwrite and unsafeWrite that overwrites. I'd be happiest if this could be done without affecting the performance of code that doesn't use these, and the documentation should make it clear which guarantees are lost by using these.