Vulama
01/13/2025, 8:52 AMVulama
01/13/2025, 8:53 AMfun main() {
val p1: Request? = Request("a")
val p2: Request? = null
val p3: Request? = Request("b")
if (validate(p1, p2)) {
println(p1.arg)
println(p2.arg)
}
if (validate(p1, p3)) {
println(p1.arg)
println(p3.arg)
}
}
data class Request(val arg: String)
@OptIn(ExperimentalContracts::class)
private fun validate(p1: Request?, p2: Request?) : Boolean {
contract {
returns() implies (p1 != null && p2 != null)
}
return p1 != null && p2 != null
}
Vulama
01/13/2025, 8:54 AMfun main() {
val p1: Request? = Request("a")
val p2: Request? = null
validate(p1, p2)
println(p1.arg)
println(p2.arg)
}
This piece of code would also make a smart cast, but would fail in runtime since p2 is null, that makes it dangerous.Vulama
01/13/2025, 8:57 AM@OptIn(ExperimentalContracts::class)
private fun <T1, T2> validate(p1: T1?, p2: T2?, block: () -> Unit) : Boolean {
contract {
executes(block) implies (p1 is Number && p2 != null)
}
}
That would mean that this would work as expected:
fun main() {
val p1: Int? = 10
val p2: String? = "string"
validate(p1, p2) {
println(p1) // p1 is smart casted
println(p2) // p2 is smart casted
}
println(p1) // p1 is not smart casted
println(p2) // p2 is not smart casted
}
gmz
01/13/2025, 10:00 AMreturns(true) implies (p1 != null && p2 != null)
gmz
01/13/2025, 10:03 AMVulama
01/13/2025, 11:27 AMgmz
01/13/2025, 11:30 AMif (validate(p1, p2)) {
println(p1) // p1 is smart casted
println(p2) // p2 is smart casted
}
versus
validate(p1, p2) {
println(p1) // p1 is smart casted
println(p2) // p2 is smart casted
}
It feels unnecessary, but that's my opinion. You could achieve something similar with a function such as this one:
@OptIn(ExperimentalContracts::class)
private inline fun <T1 : Any, T2 : Any> validate(p1: T1?, p2: T2?, block: (p1: T1, p2: T2) -> Unit) {
if (p1 != null && p2 != null) {
block(p1, p2)
}
}
I said similar because the usage changes a bit:
validate(p1, p2) { p1, p2 ->
println(p1) // p1 is smart casted
println(p2) // p2 is smart casted
}
Vulama
01/13/2025, 11:36 AMgmz
01/13/2025, 12:51 PMephemient
01/13/2025, 4:12 PMgmz
01/13/2025, 4:29 PMInvocationKind
when I specify the wrong type. It would be cool to have even more validations and errors instead of warnings. That would make contracts a lot safer.