Jakob
10/24/2025, 2:48 PMdata class TimeRange(
val from: Instant,
val to: Instant?,
) {
fun isOpenEnded(): Boolean {
return this.to == null
}
}
Optimally, I'd like to be able to use this helper and have the compiler still correctly infer whether to is null or not.
If I now add a method to check if a TimeRange ends later than another, it might look like this (it's logically incorrect but nevermind that for the sake of the example)
fun endsLaterThan(other: Timerange): Boolean {
return this.isOpenEnded() || (!other.isOpenEnded() && (this.to > other.to))
}
However, this code does not work as-is, the compiler gives me trouble about nullability. To my human eyes and brain it's clear that the final statement (<http://this.to|this.to> > <http://other.to|other.to>) is only reachable if neither <http://this.to|this.to> or <http://other.to|other.to> is null, since that would short circuit the boolean operations. The compiler does not infer this, so I thought I might be able to help it along using contracts!
I have tried to add something like this, but it does not seem to work since I'm using implies to say something about a member of the receiver and not just the receiver itself?
fun isOpenEnded(): Boolean {
contract {
returns(true) implies this.to == null
returns(false) implies this.to != null
}
return this.to == null
}
If there's a way to make this work, I'd love to know! Links to reading material about contracts in general is also appreciated 👍dmitriy.novozhilov
10/24/2025, 2:54 PM