Homomorphic static analysis
Hey @marcosh,
great post, thank you. Due to the posts by you and others I have recently looked more into category/arrow based programming. Now I have a question on which I’d like to pick your brain (or anyone elses in the community.)
I really like the concept of Alternative and Parallel like you used them and how you drew the diagram. This strongly suggested to me that strong profunctors (/arrows) are a way to express parallelism. But I hit a problem with that:
I assume your implementation of f &&& g is something like lmap dup (first' f >>> second g').
Here morally first' f and second' g are “parallel”, you drew it like that in your diagram and that makes sense because f and g have no data dependency.
But now assume that we run this in a profunctor which has observable side effects. e.g. a newtype around Kleisli IO where we would want &&& or *** to use concurrently.
Now we have two choices
either we implement
***so thatf *** g /= first' f >>> second' gbecause we implement***truly parallel whilefirst' f >>> second' gexecutesfandgsequentially. This is unsatisfying because it a) breaks the intuition implied by your diagrams and b) seems at least dubious for Arrows where***is defined asfirst f >>> arr swap >>> first g >>> arr swapand it says “you may implement a more efficient version”. Which is not documented as a law but to me implies that we should have a law thatf *** g == first f >>> second g.we find an implementation of our profunctor which truly fuses
first' f >>> second' gand runsfandgconcurrently. I tried that and it is possible. However what I couldn’t manage to do was to achieve fusion in a way thatfirst' f >>> second' g /= first' f >>> lmap id (second' g)It seems impossible to me because there is now way to detect whetherlmap fintroduces a data dependency betweenfandg. Now that is a problem becauseProfunctordocuments the lawlmap id == id.
(I looked into this and my impression is that 2. is only really possible for “Causal Commutative Arrows”, which is quite restrictive.)
So my take away is, that observably parallel arrows cannot do anything interesting when their Profunctor instance is not trivial (like in your static analysis which has a phantom parameter.) So profunctor based programming seems to be fundamentally sequential to me.
What do you think?
Discussion in the ATmosphere