Arrow: Async and Concurrent Fx blocks aren't lazy

Created on 24 Jan 2020  路  8Comments  路  Source: arrow-kt/arrow

Similarly as for #1976, Async and Concurrent suffer from the same issue, which can potentially be avoided by deferring the coroutine evaluation.

This would also allow removing specific defers on each instance for each data type as fixed in #1663

bug

All 8 comments

Aren't they eager up to the first suspension point? IIRC it's always been intentional.

@pakoito I just moved the defer from the specific instances to the async and concurrent roots so in case we add new types at a later point we don't need to remember to apply that fix again. Is there a reason why instances shouldn't be lazy if they support defer?

IO { } and effect are lazy constructors. fx opens a block with special syntax. Otherwise we could make effect and fx be the same.

This is the current behaviour of IO at the moment.

In any case I wouldn't expect as a dev that the fx block runs eagerly, although the test shows that this might probably be a misusage of if since that code should be wrapped in effect in the first place. I remember tho that this fix was intended also to solve a problem with the thread in which the first suspensions within the fx block runs according to this

@arrow-kt/maintainers any thoughts?

In theory this should never be a problem because the eager evaluated code is assumed pure (otherwise it'd have to be wrapped in F anyway). However this behavior may still surprise people who don't adhere to this strictly. I kind of think my idea that I listed in the other issue, binding a unit at the start of each fx block may just be simpler until meta comes around, especially because that works over any monad and thus also mtl. Either way I am for solving this, or if not at least documenting this somewhere visible

I don't remember if I was for or against unifying fx and effect 馃榿 (I said later before, I meant effect). I do remember the conversation and that there was a limitation. Maybe it was this differentiation of eager and lazy?

cc @raulraja do you remember? was this about the Fink primitives?

The difference between fx is that fx enables special syntax for binding ! and syntax.
And the difference between ! and suspend() is that with ! you don't leave flatMap and benefit from all benefits of flatMap while with suspend() you run the IO in a pure suspend context.
We do want it to run lazily for all capable monads, at least that's how I remember the conversation.

was this about the Fink primitives?

I think I missed this completely tho

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Northburns picture Northburns  路  4Comments

jmfayard picture jmfayard  路  4Comments

raulraja picture raulraja  路  4Comments

JLLeitschuh picture JLLeitschuh  路  4Comments

JorgeCastilloPrz picture JorgeCastilloPrz  路  5Comments