Skip to content
This repository has been archived by the owner on Feb 24, 2021. It is now read-only.

Monad Comprehensions without coroutine #12

Closed
kalistace opened this issue Aug 20, 2019 · 3 comments
Closed

Monad Comprehensions without coroutine #12

kalistace opened this issue Aug 20, 2019 · 3 comments

Comments

@kalistace
Copy link

Hi,

As far as I understand, each binding steps in a monad comprehension will leverage kotkin suspended function feature, this great for IO, or very intensive task, but what if I just want to use it as syntactic sugar to avoid nested flatmap structures ? For instance to compute simple Task.

To illustrate, let's take an snippet from the documentation :

binding {
  val a = Try { "3".toInt() }.bind()
  val b = Try { "4".toInt() }.bind()
  val c = Try { "5".toInt() }.bind()
  a + b + c
}
// Success(value=12)

In the example, am I correct to think the runtime overhead of maintaining suspended functions will be greater than what it brings me ?

Although, this is an overly simplified example, in real applications such computation does happen, top of head, for instance to validate user input before sending it to a service or a IO function.

Is there a way to have binding steps running normally on the main thread ? The current workaround I can think of is to use nested flatmaps but it quickly gets unreadable.

Thanks

@raulraja
Copy link
Member

@kalistace we agree and this is coming up for all data types that provide Monad around October https://github.com/47deg/arrow-meta-prototype/blob/rr-typeclasses-plugin/compiler-plugin/src/main/kotlin/arrow/meta/comprehensions/ComprehensionsPlugin.kt we are already working in a prototype that rewrites binds as flatMap because that is leaner than suspension. It will still use suspension for the code as it is today but will rewrite it to a nested flatMap

@kalistace
Copy link
Author

Thanks for the answer ! Very happy to hear it is on the roadmap :) Looking forward to seeing it being rolled out. Great work.

@kalistace kalistace reopened this Aug 22, 2019
@rachelcarmena rachelcarmena transferred this issue from arrow-kt/arrow Feb 20, 2020
@nomisRev
Copy link
Member

nomisRev commented May 21, 2020

Hey @kalistace,

The overhead is neglectable of using suspend with the new planned encoding. It's a similar penalty as using a simple handwritten DSL, the compiler is leveraged to wire nested fold code together, and uses a cheap ControlThrowable to break out of the suspension.

(See Roman's example on using suspend for stack safe functions or the sequence builder for similar low-cost implementations for suspend.)

This also works in a suspended way by leveraging a small state-machine to keep track of the internal state, which can be done by simple Int flags. #112

You're correct that the current encoding in 0.10.x and before it is more expensive, but this will be changed with the new encoding. And can later be solved in a generic way with the compiler plugin.

I hope that answers your questions, and what the current state is :)
I'm going to close this issue since it can be tracked in #115 & #116.

Thanks for the feedback! And if you have any questions feel free to ask questions here or on the Kotlin Slack in the #arrow channel ;)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants