How do you implement partial application in Kotlin by capturing arguments in a closure, and how does it differ from currying?
answer
- Fix some args now, return a function of the rest
- Implemented via a closure capturing the fixed args
- Currying = reshape; partial = supply values
- partial(a): (B) -> R = { b -> this(a, b) }
- Default arguments are the idiomatic substitute
basics
~10 sPartial application means fixing some of a function's arguments now and getting back a new function that takes the rest. In Kotlin you do it by returning a lambda that captures the fixed arguments.
solid answer
~50 sPartial application fixes one or more arguments of an existing function and returns a new function taking the remaining ones. You implement it with a **closure**: a lambda that captures the pre-supplied arguments. Given `fun greet(greeting: String, name: String) = "$greeting, $name"`, you partially apply with `val sayHello: (String) -> String = { name -> greet("Hello", name) }`; here `"Hello"` is captured. The difference from **currying**: currying *restructures* the function so every stage takes exactly one argument (a chain of single-arg functions), whereas partial application *fixes some subset* of arguments and can leave several remaining. Currying is a transformation of shape; partial application is an act of supplying values. You can build a generic helper: `fun <A, B, R> ((A, B) -> R).partial(a: A): (B) -> R = { b -> this(a, b) }`. In idiomatic Kotlin, **default arguments** often replace the need entirely.
code
kotlin · 5 linesfun <A, B, R> ((A, B) -> R).partial(a: A): (B) -> R = { b -> this(a, b) }
val multiply: (Int, Int) -> Int = { x, y -> x * y }
val triple = multiply.partial(3) // (Int) -> Int
println(triple(7)) // 21go deeper
Can fix one argument by writing a lambda that calls the original function with a captured value.
Distinguishes partial application (supply a subset) from currying (reshape to single-arg chain) and writes a generic partial extension.
Chooses between closures, default arguments, and overloads based on call-site needs and allocation cost; knows currying makes partial application trivial but they're distinct.
Sets team conventions on when functional encodings earn their keep versus Kotlin's default-argument ergonomics, considering readability, allocation, and inlining.
## Partial application defined **Partial application** is the act of taking a function and supplying *some* of its arguments now, producing a **new function** that takes the *remaining* arguments later. The supplied arguments are baked in. ```kotlin fun greet(greeting: String, name: String): String = "$greeting, $name!" // Fix the first argument by capturing it in a closure: val sayHello: (String) -> String = { name -> greet("Hello", name) } sayHello("Ada") // "Hello, Ada!" sayHello("Linus") // "Hello, Linus!" ``` The lambda `{ name -> greet("Hello", name) }` is a **closure**: it captures the value `"Hello"` from the surrounding code and reuses it on every call. That captured value *is* the partially-applied argument. ## A reusable partial-application helper You can write a generic extension that fixes the first argument of any two-arg function: ```kotlin fun <A, B, R> ((A, B) -> R).partial(a: A): (B) -> R = { b -> this(a, b) } val add: (Int, Int) -> Int = { x, y -> x + y } val addFive = add.partial(5) // (Int) -> Int addFive(10) // 15 ``` Here `this` is the receiver function; the returned lambda closes over both `this` and `a`. ## Currying vs. partial application These are often confused: - **Currying** changes the *shape* of the function: an `(A, B, C) -> R` becomes `(A) -> (B) -> (C) -> R` — a chain where **each step takes exactly one argument**. It does not, by itself, supply any values. - **Partial application** *supplies* a subset of arguments and returns a function of the rest. It can fix one, two, or several at once, and the remaining function can still be multi-argument: `(A, B, C) -> R` partially applied on `A` gives `(B, C) -> R`. Note a curried function makes partial application trivial — calling `curried(a)` *is* a partial application — but the two concepts are distinct. ## The idiomatic Kotlin alternative Much of what partial application buys you is provided by **default arguments** and **named arguments**: ```kotlin fun greet(greeting: String = "Hello", name: String): String = "$greeting, $name!" greet(name = "Ada") // uses default greeting greet(greeting = "Hi", name = "X") ``` Default arguments cover the common "I usually want this value fixed" case without creating closures or new function objects. Reach for explicit partial application when you need to pass the resulting function around (e.g., into `map`, a callback, or a strategy slot).
- Can a partially applied function still take more than one argument?Yes. Partial application only fixes a subset; the remaining function may take several arguments — unlike currying, which forces one argument per step.
- When would you prefer default arguments over hand-rolled partial application?Whenever the fixed value is a sensible default for direct callers; default/named arguments avoid extra closures and allocations and read more clearly. Use explicit partial application when you must hand the resulting function to higher-order code.
Pre-filling part of a form and handing it to the next person to complete the remaining fields.
saying these in an interview costs you the question
- Treating currying and partial application as the same thing
- Claiming partial application always reduces the function to a single remaining argument
- Forgetting that the closure captures the fixed argument (thinking it re-reads it each call)
- Overusing closures where a default argument would be clearer and allocation-free