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.
answer
- inline -> body copied to call site
- Bare return = non-local, exits enclosing fun
- return@repeat = continue (this iteration only)
- No break/continue keywords in repeat
- Need 'break'? use a for-loop or non-local return
basics
~10 sBecause 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.
solid answer
~40 srepeat is `inline`, so its lambda body is copied into the call site. That permits **non-local returns**: a bare `return` inside `repeat { }` returns from the **enclosing function**, not just the lambda. To return only from the current iteration (a 'continue'), use the labeled `return@repeat`. You **cannot** use `break`/`continue` directly, because repeat is a function call, not a language loop — there's no loop label to break. To stop early ('break'), you must restructure: use a real `for` loop with `break`, or guard with a flag, or use `(0 until n).forEach` (same limitation) — typically people switch to a `for` loop or `firstOrNull`/`any` style when early exit is needed. Non-local return is exactly why inline matters here.
code
kotlin · 7 linesfun indexOfFirstNegative(xs: IntArray): Int {
repeat(xs.size) { i ->
if (xs[i] < 0) return i // non-local: leaves indexOfFirstNegative
if (xs[i] == 0) return@repeat // 'continue': skip zeros
}
return -1
}go deeper
Knows return@repeat exists to skip an iteration and that repeat takes a lambda.
Explains non-local return enabled by inline and the lack of break/continue keywords, with the continue equivalent.
Articulates the inline mechanics (no allocation, body copied), early-exit strategies, and when to drop repeat for a for-loop.
Weighs readability/perf trade-offs of repeat vs for vs short-circuiting ops and reasons about crossinline/noinline implications generally.
## Inlining recap Marking a function `inline` tells the compiler to copy both the function and its lambda argument into the call site, eliminating the lambda object and call overhead. `repeat` is `inline`, so the body you pass becomes part of the calling function's bytecode. ## Non-local return Because the lambda is inlined, a bare `return` inside it is a **non-local return**: it returns from the **function that contains the `repeat` call**, not merely from the lambda. This is only allowed for lambdas passed to inline functions. ```kotlin fun firstNonEmpty(rows: List<String>): String? { repeat(rows.size) { i -> if (rows[i].isNotEmpty()) return rows[i] // returns from firstNonEmpty } return null } ``` ## Local (labeled) return = 'continue' To skip just the current iteration, return to the `repeat` label: ```kotlin repeat(5) { i -> if (i % 2 == 0) return@repeat // acts like 'continue' println(i) // prints 1, 3 } ``` `return@repeat` returns from the **lambda only**, ending the current iteration — the loop continues. ## Why `break`/`continue` keywords don't apply `break` and `continue` are control-flow for **language loops** (`for`, `while`, `do/while`). `repeat` is a normal function call taking a lambda; there is no loop construct for those keywords to target, so `break`/`continue` are **not** valid inside `repeat { }`. The lambda-level equivalent of `continue` is `return@repeat`. There is **no** lambda equivalent of `break` that only exits `repeat`. ## Early exit ('break') If you need to stop iterating early, you have options: ```kotlin // Option A: a real for-loop for (i in 0 until n) { if (done) break } // Option B: non-local return out of the whole function fun scan(n: Int) { repeat(n) { i -> if (found(i)) return } } // Option C: switch to a sequence/collection op that short-circuits (0 until n).firstOrNull { matches(it) } ``` ## Takeaway - `return` -> exits the enclosing function (non-local, thanks to inline). - `return@repeat` -> 'continue' (next iteration). - No `break`/`continue` keywords; restructure for early exit.
- What does a bare `return` inside repeat { } return from?From the enclosing function, because repeat is inline and the lambda is inlined — this is a non-local return.
- How do you emulate continue inside repeat?Use return@repeat, which ends only the current iteration's lambda invocation and lets the loop proceed.
- Can you write break inside repeat to stop early?No. break targets language loops; repeat is a function call. Use a real for-loop, a non-local return, or a short-circuiting collection operation.
return@repeat is skipping the rest of one lap; a bare return is walking off the whole track.
saying these in an interview costs you the question
- Saying break/continue keywords work inside repeat
- Thinking a bare return only exits the lambda
- Confusing return@repeat with breaking out of the loop
- Believing repeat allocates a lambda object every call
- Claiming non-local return works for non-inline higher-order functions