https://kotlinlang.org logo
#arrow
Title
# arrow
c

CLOVIS

03/25/2024, 9:53 PM
Is there a reason `Raise.zipOrAccumulate`doesn't have a variant which returns a tuple instead of having a combination lambda? I find myself writing
Copy code
fun logIn(username: String, password: String) = either {
    val (validUsername, validPassword) = zipOrAccumulate(
        { withError(LogInFailure::InvalidUsername) { usernameOf(username) } },
        { withError(LogInFailure::InvalidPassword) { passwordOf(password) } },
    ) { u, p -> u to p }

    …further processing…
}
and this overall pattern is quite verbose 😕
k

Kev

03/26/2024, 2:35 AM
You should be able to use something like if I’m not mistaken.
Copy code
fun logIn(username: String, password: String) = either {
    val (validUsername, validPassword) = zipOrAccumulate(
        { withError(LogInFailure::InvalidUsername) { usernameOf(username) } },
        { withError(LogInFailure::InvalidPassword) { passwordOf(password) } },
    ::Pair)

    …further processing…
}
👍 1
s

simon.vergauwen

03/26/2024, 8:15 AM
@CLOVIS the problem is resolution.. The compiler cannot distinct between
(A, B, (A,B) -> C) -> C
and
(A, B, C) -> Triple
signature. It confuses these two, and they don't resolve without explicitly "selecting" with like explicit param names, or something. So since it cannot be naturally overloaded we decided not to add
zipOrAccumulateTuple
in favor of
::Triple
.
a

Alejandro Serrano.Mena

03/26/2024, 9:05 AM
in general, resolution by return type of a function should be avoided as much as possible. Kotlin has a specific
@OverloadByReturnLambda
annotation for this, but in my experience it fails quite often. We considered having versions like
zipOrAccumulatePair
, but at the end of the day these are not more characters than
zipOrAccumulate(...., ..., ::Pair)
s

simon.vergauwen

03/26/2024, 9:07 AM
@Alejandro Serrano.Mena I think one of the biggest problems currently is that
::Triple
doesn't "fit" into
suspend CoroutineScope.(A, B, C) -> D
. (
parMap
, etc. Don't think it's an issue here). It should fit, but an unused extension receivers is currently not automatically ignored. Would that be fixed with
context(CoroutineScope)
? And does that refactor break the binary signature? 🤔 (Sorry, some of these questions only come up naturally 😅) Also, don't think this is about
@OverloadByReturnLambda
since Kotlin cannot understand the difference between
C
and
(A, B) -> C
. Should be unrelated to the lambda return type, right? 🤔
a

Alejandro Serrano.Mena

03/26/2024, 9:08 AM
we're doing some research in the Kotlin team about how we could make better conversions for callable references, but at this point it seems that everything we do to make something better breaks something elsewhere
s

simon.vergauwen

03/26/2024, 9:11 AM
Awesome to hear! Yes, I have no problem believing that is the case 😰 I'm quite happy with the status quo, and if
context
can be "ignored" than it solves my problem TBH. It fixes it 100% if
context
won't break the binary compat (same ordering of of params), because then it kind-of makes sense that an explicit receiver is not ignored but an "implicit" (?) one can be ignored. Similar train of thought as scope pollution of
buidList
.
c

CLOVIS

03/26/2024, 9:41 AM
I wonder if something like this could work:
Copy code
fun logIn(username: String, password: String) = either {
    val (validUsername, validPassword) = Accumulate
        .withError(LogInFailure::InvalidUsername) { usernameOf(username) }
        .withError(LogInFailure::InvalidPassword) { passwordOf(password) }
        .bind()
}
This would be much more convenient to work with for end users because auto-complete would be much less a mess (understanding the signature of the dozen variants of
zipOrAccumulate
is… a challenge). The main downside is it requires creating
n
intermediary result types to have type-safety for the return values 😕 Or maybe
TupleXX
can be reused.
k

Kev

03/26/2024, 10:35 AM
What are you trying to accomplish? Less verbosity but with more descriptiveness?
c

CLOVIS

03/26/2024, 10:36 AM
Less verbosity, better dev UX with auto-complete