Stylianos Gakis
05/09/2022, 12:27 PMfun getLoginResult(): Success|WrongPassword|NetworkError
Would you map this to Either<NetworkError,Success|WrongPassword>
or Either<NetworkError|WrongPassword,Success>
?
I also understand that both can work, technically one could flip Right and Left too, but we’re trying to see what the “convention” is to try and conform to whatever feels more standard.
Feel free to respond here or there, either works for us, but probably here so that other people can benefit in the future.stojan
05/09/2022, 12:30 PMRight
is used for success. The reason for that is because operations like map
, flatMap
, the either
computation block etc operate on the Right
value and short circuit if there is a Left
so in this scenario Either<NetworkError|WrongPassword,Success>
makes sense.
note: I didn't read the full discussion from the linkphldavies
05/09/2022, 12:37 PMgetLoginResult
) I would see “wrong password” being a valid login result (the result of the login was “incorrect password”). If it was fun login(): Either<…>
I would think otherwise.Stylianos Gakis
05/09/2022, 12:51 PMfun login(): Either<NetworkError|WrongPassword, Success>
fun getLoginResult(): Either<NetworkError, WrongPassword|Success>
The reason that our discussion is becoming a bit more nuanced I think is because we’re using that one Either
there as a form of controlling the flow and not as a return type. We’re then mapping that to the return type that was already there that we want to preserve. The SelfChangeEligibilityResult
type, which is basically a mapping of the Success|WrongPassword|NetworkError
in the example I posted above. And then we take that either (which could be either way) and turn it into this type.
That’s why I think I’d like to hear if conceptually people prefer/avoid to do one of the two approaches in general. Not so much for the login case or some other specific case.stojan
05/09/2022, 12:57 PMEither.Left
e.g.
I validate a form on the client, then submit it to the backend
an invalid form (e.g. invalid email/phone/whatever) is a known error, but if the form is invalid I don't wanna do the API call, it's gonna fail anywaytginiotis
05/09/2022, 1:01 PMLeft
, any response is a Right
• If it is the general business logic layer -> all errors from above (network) are still Left
+ business logic errors are Left
, while a non-nuanced business logic completion is a Right
• If it is a specific logic layer (form submission) -> all errors from above (network, gen. business) are still Left
+ specific logic errors are Left
(e.g. form has invalid fields), while a successful pass means Right
(e.g. form completes successfully)
So what is up to interpretation is what number of layers your app has or what are the actual scopes of your functions. Are your function scopes not too large, i.e. handling too much in a single function?stojan
05/09/2022, 1:03 PMsuspend fun blah(): Either<ErrorBody, SuccessBody>
so it can automatically convert error status codes to ErrorBody
phldavies
05/09/2022, 1:04 PMeffect {
login().bind() // short-circuit on wrong password)
// do stuff expecting to be logged in
}
vs
effect {
val loginResult = getLoginResult().bind()
if (loginResult == Success) // do something
else // do something else ;)
}
Stylianos Gakis
05/09/2022, 1:50 PMtginiotis
05/09/2022, 2:24 PMgetLoginResult
does read like it is looking for a login attempt result, so any result - be it "successful" or not, would be Right
if the result retrieval process completes (process completion is the happy path in this context). Then passing the Right<WrongPassword>
to a function concerning itself with not the result retrieval, but the act of doing the login itself specifically e.g. a doLogin()
function I imagine that would return with a Left
for an unsuccessful login.
So depends on what is happy for the particular context/function. And then a granular enough separation of concerns for the functions/contextsPavel
05/09/2022, 6:11 PMfun getLoginResult(): Either<NetworkError, WrongPassword|Success>
The Left
side is for cases when there is no result of the computation i.e. you can't continue in any meaningful way. In case of WrongPassword
there might be legitimate business logic tied to this outcome like temporarily banning the user. WrongPassword
is a valid return value of getLoginResult()
and thus should be Right
derek
05/10/2022, 10:54 AM