result4k icon indicating copy to clipboard operation
result4k copied to clipboard

Add monad comprehension style syntax

Open Munzey opened this issue 4 years ago • 2 comments

Saw your talk at kotlin conf on exception handling. Had been playing around with arrow up to then but when you mentioned benchmarking and how poor the monad comprehensions performed it made me think maybe just adopting result4k might just suit my needs!

But i come from a scala background so I really missed having for comprehensions 😢 So I dug through arrow's code base, and created a stripped back monad comprehension just for result type using coroutine continuations. When I benchmarked that against arrow's Either comprehension and plain ol flatmapping using Result4k, on my machine the benchmark looked something like this:

Lib Success Flow Failure Flow
arrow's Either 600 ops/ms 700 ops/ms
AwaitableResult (coroutines) 20000 ops/ms 33000 ops/ms
Result4k flatmap 447000 ops/ms 452000 ops/ms

I then realised I cold rewrite my AwaitableResult implementation without coroutines to get this output:

Lib Success Flow Failure Flow
AwaitableResult (no coroutines) 86000 ops/ms 141000 ops/ms
Result4k flatmap 447000 ops/ms 452000 ops/ms

still not that close to just flatmapping, but I thought it seemed reasonable to consider adding this functionality for those who want to use it! I can push to a repo the small becnhmark test I created using jmh if you want to see how I reached those numbers.

Included tests that should serve as document on how to use (its pretty much identical to how arrow for comps work). Also not tied to the syntax naming, if you have suggestions over .await() I'm open to changing it 😄

Munzey avatar Mar 17 '20 12:03 Munzey

@npryce @npryce-springer hello! wondering if you've gotten a chance to see this. After some thought, decided better to stick with bind as the keyword. I also switched the calls to inline. Reading more into how inline works I think the performance benefits from using it are justified - but maybe someone can prove me wrong. Running the benchmarks, I now get:

Lib Success Flow Failure Flow
ResultBinding 174000 ops/ms 295000 ops/ms
Result4k flatmap 447000 ops/ms 452000 ops/ms

I think those figures look slightly better (of course just a metric from what is most likely a contrived benchmarking 😅 )

hope you are keeping well through these strange times.

Munzey avatar Apr 27 '20 19:04 Munzey

For those who stumble across this pr, I ended up contributing to another result library instead, see commit: https://github.com/michaelbull/kotlin-result/commit/9bcaa974ca03b9f518a1e84717f79272f4d090c2

Munzey avatar May 11 '20 11:05 Munzey