> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kotlin Range

The `..` operator in Kotlin is a binary operator used to construct a mathematically closed range, meaning it includes both the defined starting and ending bounds. At compile time, the `..` operator is resolved as syntactic sugar for the `rangeTo()` operator function.

## Under the Hood: `rangeTo` and `ClosedRange`

When the Kotlin compiler encounters the `..` operator, it translates the expression into a method call to `rangeTo()`.

```kotlin theme={"dark"}
val a = 1
val b = 10
val range1 = a..b

// The compiler translates the above to:
val range2 = a.rangeTo(b)
```

The `rangeTo()` function returns an instance of the `ClosedRange<T>` interface. This interface defines the mathematical boundaries of the range and requires the underlying type `T` to be `Comparable<T>`.

The `ClosedRange<T>` interface exposes two properties and two methods:

* `start: T` – The lower bound.
* `endInclusive: T` – The upper bound.
* `operator fun contains(value: T): Boolean` – Evaluates whether a given value falls between the bounds. The interface provides a default implementation for this method (`value >= start && value <= endInclusive`).
* `fun isEmpty(): Boolean` – Evaluates whether the range is empty. The interface provides a default implementation for this method (`start > endInclusive`).

## Type System and Standard Library Implementation

By default, the Kotlin standard library provides an extension function for any type that implements the `Comparable<T>` interface. This means the `..` operator is automatically available for any comparable custom type without requiring explicit operator overloading.

```kotlin theme={"dark"}
// Conceptual representation of the standard library extension
public operator fun <T : Comparable<T>> T.rangeTo(that: T): ClosedRange<T> = 
    ComparableRange(this, that)

internal class ComparableRange<T : Comparable<T>>(
    override val start: T,
    override val endInclusive: T
) : ClosedRange<T> {
    override fun equals(other: Any?): Boolean { /* ... */ }
    override fun hashCode(): Int { /* ... */ }
    override fun toString(): String { /* ... */ }
}
```

Unlike a simple anonymous object, the standard library implementation returns a concrete `ComparableRange` instance. This ensures that standard functions like `equals()`, `hashCode()`, and `toString()` are properly implemented, preventing unexpected behavior when ranges are compared for equality or hashed in collections.

## Primitive Specializations

For core integral types (`Int`, `Long`, and `Char`), Kotlin provides highly optimized, specialized range classes: `IntRange`, `LongRange`, and `CharRange`.

When the `..` operator is used on these primitives, the compiler bypasses the generic `ClosedRange<T>` allocation and instead instantiates the corresponding specialized class.

```kotlin theme={"dark"}
val intRange: IntRange = 1..10
val charRange: CharRange = 'a'..'z'
```

These specialized classes implement both `ClosedRange<T>` and `Iterable<T>` (specifically, they inherit from progression classes like `IntProgression`). This dual implementation allows the range to be iterated over sequentially at the JVM bytecode level using primitive operations, entirely avoiding the memory overhead of boxing and unboxing wrapper types.

## Custom Operator Overloading

If a custom type requires a specialized range implementation (for example, a range that is also iterable, similar to `IntRange`), the `..` operator can be explicitly overloaded by defining an `operator fun rangeTo` member or extension function.

```kotlin theme={"dark"}
class CustomType(val value: Int) : Comparable<CustomType> {
    override fun compareTo(other: CustomType): Int = this.value.compareTo(other.value)
    
    // Shadows the default Comparable<T>.rangeTo extension function
    operator fun rangeTo(other: CustomType): CustomRange {
        return CustomRange(this, other)
    }
}

class CustomRange(
    override val start: CustomType,
    override val endInclusive: CustomType
) : ClosedRange<CustomType>, Iterable<CustomType> {
    
    // ClosedRange provides default implementations for contains() and isEmpty().
    // Only iterator() is strictly required to satisfy Iterable<T>.
    override fun iterator(): Iterator<CustomType> = object : Iterator<CustomType> {
        private var current = start.value
        
        override fun hasNext(): Boolean = current <= endInclusive.value
        
        override fun next(): CustomType {
            if (!hasNext()) throw NoSuchElementException()
            return CustomType(current++)
        }
    }
}
```

## Floating-Point Behavior

When using the `..` operator with floating-point types (`Float` and `Double`), the resulting `ClosedRange` does *not* implement `Iterable`. Due to the continuous nature of floating-point numbers, stepping through them sequentially is mathematically undefined without an explicit step value. Therefore, `1.0..2.0` generates a `ClosedRange<Double>` strictly for boundary checking, not for iteration.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Kotlin Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
