Oliver Eisenbarth
04/04/2023, 9:08 AMsimon.vergauwen
04/04/2023, 9:18 AMeagerEffect
and effect
you still need to differentiate between the two starting from 1.2.0-RC.simon.vergauwen
04/04/2023, 9:25 AMeither.eager { }
and either { }
is no longer needed.
EagerEffect
and Effect
are now Raise<E>.() -> A
and suspend Raise<E>.() -> A
.
And they don't share a common ancestor, even though EagerEffect
fits into the shape of Effect
but not vice-versa.
Ideally with context receivers you can completely avoid this and don't have to work with Effect
or EagerEffect
at all and just write.
context(Raise<E>)
/* suspend */ fun myCode(): Int = 1
This gives much more natural interopt, and allows horizontal composition as well.
context(Raise<String>, Raise<Error>)
/* suspend */ fun myCode(): Int = 1
You practically never have to return Effect
unless you need to explicitly pass or cache lambdas. You can just recover
, fold
, either
to calculate a terminal value.
context(Raise<String>)
/* suspend */ fun myCode(): Int = 1
val either: Either<String, Int> =
either { myCode() }
val recovered: Int =
recover({ myCode() }) { -1 }
simon.vergauwen
04/04/2023, 9:31 AMsuspend
and thus in some of the builders such as either
, option
, and nullable
you don't have to distinct between the two anymore.
That also allowed us to remove some other duplicated APIs etc from Arrow.
https://arrow-kt.io/learn/quickstart/migration/Oliver Eisenbarth
04/04/2023, 9:44 AMPavel
04/04/2023, 10:48 AMsimon.vergauwen
04/04/2023, 10:57 AMcontext(Raise<E>) () -> A
and Raise<E>.() -> A
are almost the same.
This comment also touches upon it, https://kotlinlang.slack.com/archives/C0B9K7EP2/p1680600833107529?thread_ts=1680388003.721149&cid=C0B9K7EP2
We also mention them already in a couple of sections of the documentation, since people that are opt-ing to the experimental support can benefit from all goodies in combination with Arrow.
I really hope we get a more concrete idea of the timeline @ KotlinConf, and it won't be a couple years ðŸ˜
If you had some specific APIs are improvements in mind I'd love to hear it.
I guess the biggest loss is that currently option
and result
have a different receiver/context type rather than just Raise<None>
and Raise<Throwable>
to project the DSL but that could be overcome with a tiny context receiver external library. Or could be overcome with a couple extension functions in a local project. That is something we could expose from arrow-kt.Pavel
04/04/2023, 11:37 AMsimon.vergauwen
04/04/2023, 11:55 AMAre there bogus random runtime errors? Incorrect or undefined behaviour?No, the only thing I've encountered and others in this channel is that sometimes code unexpectedly doesn't compile. IDEA inserts an incorrect space in front of
context
keyword.
But all code that is compiled works correctly as expected, since it's basically just a parameters so, similar to extension functions:
context(TypeA)
fun example()
becomes
public void example(TypeA context1)
Just like
fun TypeA.example()
becomes
public void example(TypeA receiver)
So there is nothing that can actually go wrong at runtime once it's compiled, and tested. I have some example projects where I have a context receiver branch:
https://github.com/nomisRev/ktor-arrow-example/pull/35
https://github.com/47deg/gh-alerts-subscriptions-kotlin/pull/18 (need to merge main, and fix conflicts)
And it all works fine, and passes the test-suite. I personally would dare to use them on a "production" project, but for a library I cannot because it forces downstream users to also opt-in.
Hopefully we get good news at KotlinConf in terms of K2, and future roadmap/timeline and get this sooner than we expect 🤞 🤞