Give a concrete scenario where you MUST use `noinline`, and explain why the compiler forces it.
answer
- Inlined lambda = no object to use
- store / return / pass-to-non-inline => noinline
- Error: 'Illegal usage of inline-parameter'
- Invoking is fine without noinline
- Pass to another inline fn is also fine
basics
~20 sYou need noinline when you want to keep the lambda as a value — for example to return it, store it in a list, or hand it to another function that isn't inline. The compiler refuses to compile those uses on an inlined lambda because there's no object to use.
solid answer
~40 sAn inlined lambda has no runtime object — its body is spliced into the call site — so any operation that treats it as a value is impossible. The compiler emits an error like "Illegal usage of inline-parameter" ("can't be inlined") when you try to: assign the lambda to a variable, return it, put it in a collection, or pass it to a non-inline function. Marking the parameter `noinline` materializes it as a `FunctionN` object so those uses become legal. Classic case: a higher-order helper that runs one callback now and defers another for later execution. The deferred one must be `noinline` because it is stored/returned. The immediately-invoked one can stay inlined for zero allocation.
code
kotlin · 7 linesinline fun runAndRemember(
immediate: () -> Unit,
noinline deferred: () -> Unit
): () -> Unit {
immediate()
return deferred // legal only because deferred is noinline
}go deeper
Recognizes you need noinline to keep a lambda as a value you can store or return.
Lists the exact operations that require it and gives a working deferred-callback example.
Explains the no-object codegen reason, the chaining-through-inline exception, and the allocation cost saved by inlining the rest.
Weighs whether the deferred-callback design should be inline at all, vs. exposing a plain function, based on call-site allocation profiles.
## Why the compiler forces it When the compiler inlines a lambda, it literally pastes the lambda body at each place you call `param()` inside the inline function. There is **no `FunctionN` instance** representing that lambda. So the moment you do anything that needs the object — not just call it — the compiler has nothing to give you and reports an error such as `Illegal usage of inline-parameter` / `Inline parameter cannot be used as a value`. Operations that need the object form (and thus require `noinline`): - assigning it: `val f = param` - returning it: `return param` - storing it: `list.add(param)` - passing it to a **non-inline** function: `register(param)` Operations that are fine on an inlined lambda: - invoking it: `param()` - passing it to **another inline** function as an inline argument ## Concrete scenario — deferred callback ```kotlin private val pending = mutableListOf<() -> Unit>() inline fun schedule( runNow: () -> Unit, // inlined: invoked immediately noinline runLater: () -> Unit // must be noinline: stored for later ) { runNow() pending.add(runLater) // needs a real object -> noinline required } ``` Without `noinline` on `runLater`, `pending.add(runLater)` fails to compile because `runLater` is not a value. `runNow` stays inlined, so calling `schedule` allocates only the single `runLater` object instead of two. ## Passing to a non-inline function ```kotlin fun consume(block: () -> Unit) = block() // NOT inline inline fun forward(noinline block: () -> Unit) { consume(block) // needs the object; noinline makes it legal } ``` ## Mental model Ask: "Do I only **call** this lambda, or do I treat it as a **thing**?" Calling => leave it inlined. Treating it as a thing (store/return/pass to non-inline) => mark it `noinline`.
- Why is passing an inlined lambda to ANOTHER inline function allowed without noinline?Because the receiving function also inlines it, so it never needs an object form — the inlining chains through. Only a non-inline receiver forces a real object.
- What error message hints you need noinline?An 'Illegal usage of inline-parameter' / 'inline parameter cannot be used as a value' compile error at the spot where you store, return, or pass the lambda.
saying these in an interview costs you the question
- Claiming you can store/return an inlined lambda without noinline
- Saying passing to any other function works (it must be inline)
- Not knowing the compiler hard-errors, not just warns
- Marking every lambda noinline 'to be safe', losing inline benefits