Norbi
03/07/2023, 11:54 AMraise()
and I thought that I would like x.ensureNotNull { ... }
better than ensureNotNull(x) {}
.
But then I've run into some compilation errors, see the code in my next message.
1. Maybe do you know if the internal compiler error in the first example is already reported? (I use Kotlin 1.8.0 and Arrow 1.1.6-alpha.36 but I have also tried with Kotlin 1.8.10 and 1.8.20-Beta)
2. How can I specify the "context" in the second example?
Thanks.import arrow.core.raise.Raise
import arrow.core.raise.RaiseDSL
import arrow.core.raise.ensureNotNull
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
context(Raise<R>)
@OptIn(ExperimentalContracts::class)
@RaiseDSL
public inline fun <R, B : Any> B?.ensureNotNull(raise: () -> R): B {
contract {
callsInPlace(raise, InvocationKind.AT_MOST_ONCE)
returns() implies (this@ensureNotNull != null)
}
return this ?: raise(raise())
}
object E1
object E2
context(Raise<E1>, Raise<E2>)
fun f() {
// Using arrow's ensureNotNull()
ensureNotNull(1) { E1 } // 1: Internal error occurred while analyzing this expression: "IllegalStateException: Arguments and parameters size mismatch: arguments.size = 2, parameters.size = 3"
// Using my ensureNotNull()
1.ensureNotNull { E1 } // 2: How to workaround the compilation error "Multiple arguments applicable for context receiver"?
}
Alejandro Serrano Mena
03/07/2023, 12:25 PMcontext(r1@Raise<E1>, r2@Raise<E2>)
and then use the labels when calling the different thingsNorbi
03/07/2023, 12:32 PMcontext(r1@Raise<E1>, r2@Raise<E2>)
fun f() {
// Using arrow's ensureNotNull()
with(this@r1) {
ensureNotNull(1) { E1 }
}
// Using my ensureNotNull()
with(this@r2) {
1.ensureNotNull { E2 }
}
}
simon.vergauwen
03/07/2023, 12:38 PMcontext(r1@Raise<E1>, r2@Raise<E2>)
fun f() {
// Using arrow's ensureNotNull()
r1.ensureNotNull(1) { E1 }
}
CLOVIS
03/07/2023, 12:59 PMr1@
syntax in the KEEP, where is it documented?Norbi
03/07/2023, 1:14 PMcontext(r1@Raise<E1>, r2@Raise<E2>)
fun f() {
with(this@r1) {
ensureNotNull(1) { E1 }
}
r1.ensureNotNull(1) { E1 } // Compile error: "Unresolved reference: r1
}
simon.vergauwen
03/07/2023, 1:16 PMthis@r1.ensureNotNull(1) { E1 }
?
@CLOVIS I remember seeing a discussion somewhere š¤ but I cannot seem to find it anymore. It was about specific things like this so I guess it's not fully implemented yet.CLOVIS
03/07/2023, 1:18 PMcontext(name: Type)
, from what I remember Roman Elizarov explained that adding labels was not in line with their goals. I'm surprised they added syntax to do it, in the end.Norbi
03/07/2023, 1:20 PMThis works :)this@r1.ensureNotNull(1) { E1 }
simon.vergauwen
03/07/2023, 1:21 PMlabel@
is much more in line with what we already have in the language comaared to name: Type
Norbi
03/07/2023, 1:23 PMname: Type
decision because then we would not need to always write the this@
prefix - but that's just my opinion :)CLOVIS
03/07/2023, 1:26 PMthis@Raise
).
I liked the parameter name because they are a kind of parameter, but Roman brought very good arguments against that. I'm sure that discussion was part of the decision for that label syntax.
@Norbi I think your probably happens because it's not stable yet, and when it is you won't need to explicitly label receivers in your examplesNorbi
03/07/2023, 2:06 PMI think your probably happens because it's not stable yet, and when it is you won't need to explicitly label receivers in your examplesLet's hope so š I've reported it just to be sure: https://youtrack.jetbrains.com/issue/KT-57176/Internal-compiler-error-when-using-multiple-context-receivers
With K2:
With implicit context receiver, call is ambiguous. Specify the receiver explicitly
CLOVIS
03/07/2023, 2:40 PM