How does the standard-library `to` function work, and how do `until`, `downTo`, and `step` use infix to make range code read naturally?
answer
- `infix fun <A,B> A.to(that: B) = Pair(this, that)`
- `until` = end-exclusive, `downTo` = descending
- `step` sets the stride: `1..10 step 2`
- `mapOf("a" to 1)` uses Pair varargs
- `to` boxes a Pair — avoid in hot loops
basics
~20 sto is an infix extension that builds a Pair, so "a" to 1 makes Pair("a", 1). until, downTo, and step are infix functions that build ranges/progressions, letting you write 0 until n or 10 downTo 1 step 2.
solid answer
~40 s`to` is declared roughly as `infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)`. Being infix and generic, `"key" to 42` reads like prose and produces `Pair("key", 42)`, which `mapOf(...)` consumes as entries. Range builders are infix functions too: `0 until 10` gives an `IntRange` `0..9` (end-exclusive), `10 downTo 1` gives a descending `IntProgression`, and `step` adjusts the stride: `1..10 step 2` yields `1, 3, 5, 7, 9`. Because infix sits just below arithmetic/range precedence and is left-associative, `0 until list.size` and `n downTo 0 step 2` group exactly as read. These are plain library functions, not language keywords — you could write your own `to`-like infix helper. `to` boxes into a `Pair`, so in hot loops prefer destructured loops or specialized structures.
code
kotlin · 8 linesval config = mapOf(
"host" to "localhost",
"port" to 8080,
)
val (k, v) = "x" to 99 // destructuring: k="x", v=99
val evens = (0 until 10 step 2).toList() // [0, 2, 4, 6, 8]
val down = (5 downTo 1).toList() // [5, 4, 3, 2, 1]go deeper
Uses to to build map entries and until/downTo in for-loops correctly.
States to's signature returns a Pair, explains end-exclusivity of until, and step's stride role.
Explains how infix precedence makes 1..10 step 2 group correctly and notes Pair allocation tradeoffs.
Weighs to/Pair ergonomics against allocation in hot paths and guides API authors on custom infix builders.
## `to` and `Pair` The `to` function is a generic infix extension in the Kotlin standard library: ```kotlin public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that) ``` - It works on **any** receiver type because of the generic `<A, B>`. - `"a" to 1` is exactly `Pair("a", 1)`. - `mapOf` takes `vararg Pair`, so `mapOf("a" to 1, "b" to 2)` is the idiomatic map literal. - You can **destructure** a pair: `val (k, v) = "a" to 1`. ## Range / progression builders These are infix functions on `Int`/`Long`/`Char` (and friends): - **`..`** — actually the `rangeTo` operator, inclusive: `1..5` = 1,2,3,4,5 (`IntRange`). - **`until`** — infix, end-**exclusive**: `0 until 5` = 0,1,2,3,4. (`..<` is the newer operator equivalent.) - **`downTo`** — infix, descending inclusive: `5 downTo 1` = 5,4,3,2,1 (`IntProgression`). - **`step`** — infix, sets the stride on a range/progression: `1..10 step 2` = 1,3,5,7,9. ```kotlin for (i in 0 until 5) print(i) // 01234 for (i in 10 downTo 1 step 3) print(i) // 10741 val r: IntRange = 1..10 val p: IntProgression = 1..10 step 2 ``` ## Why they read naturally Infix precedence sits just **below** the range `..` and arithmetic, and infix is **left-associative**. So `1..10 step 2` parses as `(1..10) step 2` — `..` first, then `step` — which is exactly what you want. Similarly `0 until list.size` computes `list.size` (a normal property access, higher precedence) before applying `until`. The result: range expressions group the way an English reader expects without extra parentheses. ## Caveats - `to` allocates a `Pair` object (boxing for primitives). In tight numeric loops, prefer index loops or arrays. - `until` / `downTo` / `step` return ranges/progressions that are cheap and iterate without intermediate collections. - None of these are keywords — they are ordinary library functions you could re-implement, which is the whole point of infix as a readability tool.
- What is the difference between `1..5` and `1 until 5`?`1..5` (the `rangeTo` operator) is inclusive: 1,2,3,4,5. `1 until 5` is end-exclusive: 1,2,3,4. `until` has a `..<` operator equivalent.
- Is `to` a keyword?No — it is an ordinary generic infix extension function in the stdlib that returns a `Pair`. You could write an equivalent yourself.
to is the glue word in 'map a to 1' — it pairs the two sides the way 'to' joins them in speech.
saying these in an interview costs you the question
- Thinking `to`/`until`/`downTo` are language keywords
- Saying `until` is inclusive of the end value
- Claiming `to` has no allocation cost
- Not knowing `step` sets the stride
- Confusing `..` (operator) with `until` (infix function)