skip to content

TODO & repeat

TODO returns Nothing, so an unfinished branch still type-checks while failing loudly at runtime, and repeat is the inline fixed-count loop. Interviewers appreciate TODO in a live-coding session for exactly that reason.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

6

What does repeat(n) { } do in Kotlin, and what argument does its lambda receive?

level: juniorimportance: must knowfreq 55%

answer

  1. inline fun repeat(times, action: (Int) -> Unit)
  2. Index is zero-based: 0..times-1
  3. Lambda param is 'it' by default
  4. times <= 0 -> body never runs, no error
  5. Returns Unit; for side effects only

basics

~10 s

repeat(n) runs the block of code n times. Each run, the block gets the current count, starting at 0, so you know which iteration you're on.

solid answer

~30 s

repeat is an inline stdlib function: `inline fun repeat(times: Int, action: (Int) -> Unit)`. It executes `action` exactly `times` times, passing the zero-based iteration index (0, 1, ..., times-1) into the lambda. It's a concise replacement for `for (i in 0 until n)` when you need a fixed count and the index. If `times` is 0 or negative, the body never runs. Because it's inline, the lambda is inlined at the call site, so there's no lambda-allocation or call overhead versus a manual loop. The lambda returns Unit, so it's for side effects (printing, mutating, building) rather than producing a value.

code

kotlin · 7 lines
kotlin
repeat(4) { i ->
    println("attempt #${i + 1}")
}
// attempt #1
// attempt #2
// attempt #3
// attempt #4

go deeper

for a junior

Knows repeat(n) runs a block n times and provides a zero-based index.

for a middle

States the exact signature, that it returns Unit, and the empty-range behaviour for non-positive counts.

for a senior

Explains inlining (no lambda allocation / call overhead) and when to choose List(n){} over repeat for value production.

for a principal

Frames repeat as a readability/intent tool, weighs it against for-loops and functional builders, and considers non-local returns enabled by inlining.

## Signature ```kotlin public inline fun repeat(times: Int, action: (Int) -> Unit) { for (index in 0 until times) { action(index) } } ``` `repeat` is a top-level standard-library function in package `kotlin`. It runs `action` `times` times. ## The index parameter The lambda receives a single `Int`: the **zero-based** iteration index. Inside a single-parameter lambda you can use the implicit name `it`, or name it explicitly: ```kotlin repeat(3) { println(it) } // prints 0, 1, 2 repeat(3) { index -> println(index) } // same ``` So `repeat(n)` yields indices `0, 1, ..., n - 1`. ## Edge cases - `repeat(0) { ... }` — body never executes. - `repeat(-5) { ... }` — also never executes, because `0 until times` is an empty range when `times <= 0`. No exception is thrown. ## When to use it Use `repeat` for **fixed-count, side-effecting** loops where you don't need to iterate over a collection: ```kotlin repeat(5) { print("*") } // ***** val sb = StringBuilder() repeat(3) { i -> sb.append("row $i\n") } ``` It reads more clearly than `for (i in 0 until n)` for pure counting. ## Inline performance Because `repeat` is `inline`, the compiler inlines both the function and the lambda body into the call site. There is **no function-call overhead and no lambda object allocated** — it compiles down to essentially the same bytecode as a hand-written `for` loop. That's why it's free to use in hot paths. ## What it is not for The lambda returns `Unit`; `repeat` itself returns `Unit`. It does not collect results. To build a list of computed values, prefer `List(n) { i -> ... }` or `(0 until n).map { ... }` instead.

  • What index is passed on the first iteration of repeat(n)?
    0. The index is zero-based and runs from 0 to n-1.
  • What happens with repeat(0) {} or a negative count?
    The body never runs and no exception is thrown, since the underlying range 0 until times is empty.

Like a metronome ticking a set number of beats, announcing the beat number each tick.

saying these in an interview costs you the question

  • Saying the index starts at 1
  • Claiming a negative count throws an exception
  • Thinking repeat returns the collected results
  • Confusing repeat with the String.repeat(n) extension that builds a repeated string
  • Believing the lambda receives no argument

context

open as a page

What does the Kotlin standard-library function TODO("...") do, and what happens at runtime if execution reaches it?

level: juniorimportance: must knowfreq 60%

basics

~10 s

TODO marks code you haven't written yet. If the program runs that line, it crashes by throwing an error, reminding you to finish it.

open as a page

Since repeat is inline, what does this enable inside its lambda — for example, can you `return` from the enclosing function within repeat { }? Contrast it with break/continue.

level: middleimportance: should knowfreq 30%

basics

~10 s

Because repeat's body is inlined, a plain return inside it actually returns from the surrounding function. But break and continue don't work like in a normal loop; you simulate continue with return@repeat.

open as a page

How does TODO()'s Nothing return type interact with control-flow analysis, such as when used in a branch of a when or as a default elvis fallback?

level: middleimportance: should knowfreq 35%

basics

~10 s

Because TODO() never returns normally, the compiler knows code after it can't run. So you can drop it into a branch that needs a value, or after ?:, and the types still line up.

open as a page

How does TODO() differ from error(), check()/require(), and an empty stub body? When would you choose each, and what are the design implications of shipping TODO() to production?

level: seniorimportance: should knowfreq 25%

basics

~20 s

TODO() means 'not built yet' and crashes if hit. error() means 'this should never happen'. require/check validate inputs/state. An empty body silently does nothing. Pick based on intent; never leave a live TODO() for users.

open as a page

When should you reach for repeat(n) versus a for-loop or value builders like List(n) { } / (0 until n).map { }? Discuss intent, value production, and performance.

level: seniorimportance: nice to knowfreq 18%

basics

~20 s

Use repeat for a fixed number of side-effecting passes when you don't need to collect results. If you need a list of computed values, use List(n) { }. If you need to break early or complex stepping, use a for-loop.

open as a page