Skip to main content
The ..< operator is the open-ended range operator in Kotlin, used to construct a range of values that includes the lower bound but strictly excludes the upper bound. It provides a mathematically intuitive representation of half-open intervals [a,b)[a, b) and serves as the native syntactic replacement for the until infix function.

Syntax and Compilation

The operator is placed between the start and end bounds:
During compilation, the Kotlin compiler desugars the ..< operator into a method call to the rangeUntil operator function. The above syntax is strictly equivalent to:

Type System Integration

The behavior and return type of the ..< operator depend on the operand types:
  1. Integral Types (Int, Long, Short, Byte, Char): For discrete integral types, the operator returns a standard Iterable progression (e.g., IntRange, LongRange). The standard library implementation of rangeUntil for these types explicitly guards against integer underflow. Rather than blindly calculating end - 1 to find an inclusive upper bound, the function checks the exclusive bound against the type’s minimum value (e.g., if (to <= Int.MIN_VALUE) return IntRange.EMPTY). This ensures that an expression like 0 ..< Int.MIN_VALUE safely returns an empty range instead of underflowing to Int.MAX_VALUE.
val intRange: IntRange = 0 ..< 10 val emptyRange: IntRange = 0 ..< Int.MIN_VALUE // Safely returns IntRange.EMPTY

Operator Overloading and Custom Types

Any class that implements the Comparable<T> interface automatically supports the ..< operator without requiring a manual implementation of the rangeUntil member function. The standard library provides the extension operator fun <T : Comparable<T>> T.rangeUntil(that: T): OpenEndRange<T>, which handles the boundary evaluation.
Explicit implementation of the rangeUntil operator function is only required for non-comparable types, or when a custom type needs to return a specialized discrete progression (such as a custom Iterable range) rather than the default continuous OpenEndRange<T>.

Behavioral Characteristics

  • Ascending Order Only: The ..< operator strictly creates ascending ranges. If the left operand is greater than or equal to the right operand, the resulting range is empty (isEmpty() returns true).
  • Step Size: For integral progressions, the default step size is 1.
  • Interface Hierarchy: The OpenEndRange<T> interface is distinct from ClosedRange<T> (which is generated by the .. operator). OpenEndRange exposes an endExclusive property, whereas ClosedRange exposes an endInclusive property.
Tired of Poor Kotlin Skills? Fix That With Deep Grasping!Learn More