Oliver Eisenbarth
05/14/2022, 4:36 PMeffect
? Please explain it to me like I'm five. 🙂phldavies
05/14/2022, 4:58 PMOliver Eisenbarth
05/14/2022, 6:02 PMeffect
and chose if it's accumulating errors or short-circuit depending on the use-case?bloder
05/15/2022, 7:42 AMEffect
type we introduce a new way to interrupt a continuation, we can interrupt it not only with throwables but also with custom error types, also we have in hands an effect system solution that we can encode our side-effects as pure values since the continuation is only created when you fold that effect, that means we can provide a pure environment to our impure functions just by calling it from an effect scope and we can assign it to whathever value that we want because we know we're not gonna break its purity. Also we have those benefits that you said, we can fold an effect into other types like Either, Validated, Ior or Option.
With these benefits we can not only build computations and side effects in a "safer zone" but we have in hands literally an entire effect system to try new solutions and concepts like a different way to handle effect errors or other cool stuff.bloder
05/15/2022, 7:45 AMPavel
05/15/2022, 8:44 AMOnly when fold is called it will create a Continuation and run the computation, this means Effect can encode side-effects as pure values.My understanding is that the
Effect
type represents a non-evaluated suspend function (i.e. something like a Future
that is not started) and only when fold
or toEither
(toIor
, …) is called on the Effect
then the suspend function “underneath” it runs. But what continuation
has to do with fold
from the above citation is perplexing to me.
EDIT: I looked at Effect
and it overrides fold
and does some black magic stuff with`continuation` inside it, maybe it would be good to elaborate how it works so ppl know what to expect from Effect
APIraulraja
05/15/2022, 10:26 AMsuccessful
value A
or a shifted
value E
. Internally it uses a try/catch and a controlled throwable.
fun program(): Effect<E, A>
Since Effect<E, A>
holds a suspend function it can model exit values for A
, E
and Throwable
all potential valid results of folding program
Oliver Eisenbarth
05/15/2022, 3:32 PMPavel
05/15/2022, 3:36 PMOliver Eisenbarth
05/15/2022, 4:06 PMsimon.vergauwen
05/16/2022, 6:46 AMBut it's definitely cursed.😭 The goal of Arrow is to make FP simple, and idiomatic to Kotlin. So if we're doing something wrong, please help us improve it 🙏 TL;DR
effect
is useful for many things, but if you're current use-cases are fulfilled with Either
and Validated
then you can ignore it completely without missing out.
Perhaps in the back of your head, it's interesting to know that either { }
comes from effect { }.toEither()
.
Besides that, it can also be used to model lazy computations, as one might do with IO
. Since passing around Effect<E, A>
is likely nicer than passing around suspend () -> Either<E, A>
.simon.vergauwen
05/16/2022, 6:48 AMCould I traverse stuff withNo, you cannot.and chose if it's accumulating errors or short-circuit depending on the use-case?effect
effect
models short-circuit
behavior like Either
such that the following results in the first Error
encountered in listOfValues
.
effect<Error, Int> {
listOfValues.map { it.bind() }
}
If you want Validated
behavior then nothing changes with Effect
.Oliver Eisenbarth
05/16/2022, 10:46 AMsuspend () -> A
instead of *`IO<A>`*" ) and https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core.continuations/-effect/.
At least that was the gap I was trying to close by asking here...
"Why effect
instead of *`suspend () -> A`*" can't be answered by "If you find yourself passing around suspend () -> Either<E, A>
a lot of times, you might want to use *`effect`*" because that sounds like effect
was just a typealias and by the notion I got from all the answers here, there's a lot more to it than that.
Maybe I'll be able to ask better questions re-reading @bloder’s answer a few more times. Need to let it sink in for now.
👋simon.vergauwen
05/16/2022, 11:44 AM"If you find yourself passing around100% valid. In reality that is already the short version since actually, it would bea lot of times, you might want to use *`effect`*" because that sounds likesuspend () -> Either<E, A>
was just a typealias and by the notion I got from all the answers here, there's a lot more to it than that.effect
suspend EffectScope<E>.() -> Either<E, A>
but that information seems useless to me if you're trying to understand Effect
. So within Arrow, there are always 2 parts at play. The DSL EffectScope<E>
which allows you to call bind
, ensure
, ensureNotNull
etc inside effect { }
, either { }
, etc and the return type Effect<E, A>
, Either<E, A>
, etc.
I think that is also never explained anywhere in Arrow but is not something that is explained in Kotlin in general I believe and this technique of building DSLs is super common in Kotlin Std, KotlinX Coroutines, KotlinX HTML, Gradle Kotlin Script, etc.