There’s a new operator in Kotlin!

The introduction of Open Ended Ranges

Nishant Aanjaney Jalan
CodeX
3 min readDec 1, 2022

--

You might have a few questions by looking at the title, such as:

  1. What is this new operator?
  2. Why do we need a new operator?
  3. How can I use this new operator?

#1 — What is this new operator?

Kotlin has introduced a new operator function called rangeUntil. These are open-ended ranges where the start is inclusive while the end is exclusive. As you have seen in the photo, the operator is ..<. This is a range where you stop right before the end element but not the end element itself.

#2 — Why do we need a new operator?

So with integers, you can create ranges in the ways as follows:

fun main() {
val myRange = 0..10

println(0 in myRange) // true
println(10 in myRange) // true
println(11 in myRange) // false
}

Nothing so problematic about that, right? Now instead, let us consider the infix function until.

fun main() {
val myRange = 0 until 10

println(0 in myRange) // true
println(10 in myRange) // false
println(11 in myRange) // false
}

Nothing fancy about this either. You are absolutely right but stick with me. Let’s try this same approach, but with Doubles.

fun main() {
val myRange = 0.0..10.0

println(0.0 in myRange) // true
println(10.0 in myRange) // true
println(11.0 in myRange) // false
}

All is well and good. But now I wish to exclude the 10.0 from this range.

fun main() {
val myRange = 0.0 until 10.0 // 💣 Compilation 💣 Error 💣

println(0.0 in myRange)
println(10.0 in myRange)
println(11.0 in myRange)
}

Kotlin drops a bombshell at you when you try to use until with Floating point integers. You want a range where every real number is included between 0 and 10, except for 10. What can you do?

Do I code myRange = 0.0..9.9? myRange = 0.0..9.999? myRange = 0.0..9.9999999? You don’t really know. One might argue I could use the nextDown function, but even then you have some approximation error.

import kotlin.math.nextDown

fun main() {
println(0.0..10.0.nextDown())
// 0.0..9.999999999999998

println(0.0..0.5.nextDown())
// 0.0..0.49999999999999994
}

Would you like to work with this inconsistency? Not.

Therefore, the Kotlin developers introduced the rangeUntil operator function (..<) to deal with ranges where the ending element is exclusive.

#3— How can I use this operator?

This is still an experimental feature, so we require slight configuration changes before we get to the actual code. In your build.gradle file, add this line:

kotlinOptions.languageVersion = "1.8"

We can use the operator by Opting in for the experimental API

@OptIn(ExperimentalStdlibApi::class)
fun main() {
val myRange = 0.0..<10.0

println(0.0 in myRange) // true
println(9.9999 in myRange) // true
println(10.0 in myRange) // false
}

Is that all this operator can do? Nope, it works on multiple classes as well.

fun main() {
val dayOf2022 = LocalDate.of(2022, 1, 1)
val dayOf2023 = LocalDate.of(2023, 1, 1)

println(dayOf2022..<dayOf2023)
// 2022-01-01..<2023-01-01
}

This range follows the same behaviour as Floating literals. You cannot specify if the end date or time is a second before the end, a millisecond or a microsecond. But how is this working?

operator fun <T : Comparable<T>> T.rangeUntil(
that: T
): OpenEndRange<T>

Any class that implements the Comparable Interface can use the ..< operator without explicitly defining its function.

Kotlin is a fast-changing growing language where regular updates help developers adapt more easily and use complex language features in their applications. Check out my other articles in my reading list Everything Kotlin where I write on advanced programming in Kotlin.

Everything Kotlin

22 stories
If you wish to read every article from me, consider joining the Medium 
program with this referral link.

Want to connect?

My GitHub profile.
My Portfolio website.

--

--

Nishant Aanjaney Jalan
CodeX
Editor for

Undergraduate Student | CS and Math Teacher | Android & Full-Stack Developer | Oracle Certified Java Programmer | https://cybercoder-naj.github.io