skip to content

What does it mean to compose two functions in Kotlin, and how would you write an `andThen` helper that runs one function and feeds its result into another?

level: juniorimportance: must knowfreq 55%

answer

  1. andThen = receiver first; compose = receiver last
  2. Returns a new lambda { x -> g(this(x)) }
  3. Extension on a function type, marked infix
  4. Three generics A, B, C thread the intermediate type
  5. Lazy: nothing runs until you invoke the result

basics

~10 s

Composing means chaining functions so one's output becomes the next's input. An andThen helper takes function f, then g, and returns a new function that does g(f(x)) for any input x.

solid answer

~40 s

Composition combines two function values into a single new function. In Kotlin you write it as an extension on a function type, usually `infix`. `andThen` applies the receiver first, then the argument: `fun <A,B,C> ((A)->B).andThen(g:(B)->C):(A)->C = { x -> g(this(x)) }`. The returned lambda captures both functions and defers execution until called. `compose` is the mirror image: `f.compose(g)` returns `{ x -> f(g(x)) }`, running g first. The key idea is that the helpers don't run anything immediately; they build and return a brand-new `(A)->C` lambda. You then invoke it like any function: `val pipeline = parse andThen validate andThen save; pipeline(input)`. Generic type parameters thread the intermediate type B so the compiler checks the wiring.

code

kotlin · 7 lines
kotlin
infix fun <A, B, C> ((A) -> B).andThen(g: (B) -> C): (A) -> C =
    { x -> g(this(x)) }

val trim: (String) -> String = String::trim
val len: (String) -> Int = String::length
val trimmedLength = trim andThen len
println(trimmedLength("  hi  ")) // 2

go deeper

for a junior

Can state that composition chains output-to-input and write a simple andThen returning g(f(x)).

for a middle

Distinguishes andThen vs compose order, uses infix + generics, and knows it returns a lazy new lambda.

for a senior

Explains receiver-as-function, closure capture, and when a fluent pipeline beats nested calls for readability.

for a principal

Frames composition as a building block for declarative pipelines and weighs it against existing collection/sequence operators in real code.

## What composition means **Function composition** takes two functions and produces a third that, when called, runs them in sequence. If `f: (A) -> B` and `g: (B) -> C`, the composition is a function `(A) -> C` defined by `x -> g(f(x))`. The two directions have conventional names: - **`andThen`**: receiver runs **first**. `f.andThen(g)` == `{ x -> g(f(x)) }`. Reads left-to-right like a pipeline. - **`compose`**: receiver runs **last** (math convention). `g.compose(f)` == `{ x -> g(f(x)) }`. Reads right-to-left. ## Writing the helper Kotlin has no built-in `andThen` for plain function types, so you define an **extension function** on the function type. Marking it `infix` lets you write `a andThen b` without dots/parens. ```kotlin infix fun <A, B, C> ((A) -> B).andThen(g: (B) -> C): (A) -> C = { x -> g(this(x)) } infix fun <A, B, C> ((B) -> C).compose(g: (A) -> B): (A) -> C = { x -> this(g(x)) } ``` - `((A) -> B)` is the **receiver type** — the function you call the helper on. Inside the body, `this` refers to it. - The three **generic type parameters** `A, B, C` thread the types: input `A`, intermediate `B`, output `C`. The compiler infers them and rejects mismatched wiring. - The body returns a **lambda** `{ x -> g(this(x)) }`. Nothing executes yet — composition is **lazy**; the captured functions only run when you invoke the result. ## Using it ```kotlin val toLength: (String) -> Int = { it.length } val isEven: (Int) -> Boolean = { it % 2 == 0 } val lengthIsEven = toLength andThen isEven println(lengthIsEven("hello")) // 5 -> false ``` ## Key keywords - `infix` — enables `a andThen b` syntax. - extension function on a **function type** — the receiver is itself a function. - the returned **lambda captures** both functions (a closure).

  • What is the difference between `f andThen g` and `f compose g`?
    `f andThen g` runs f first then g (g(f(x))). `f compose g` runs g first then f (f(g(x))). They are mirror images of each other.
  • Does `andThen` run the functions immediately?
    No. It returns a new function and runs nothing. The composed functions only execute when you invoke the returned function with an argument.

Like an assembly line: andThen bolts the next station onto the end, so a part flows through each step in order.

saying these in an interview costs you the question

  • Says andThen executes the functions right away instead of returning a new function
  • Confuses the order: thinking compose runs the receiver first
  • Writes it as a top-level function taking two args instead of an extension on a function type
  • Forgets the generic type parameters so the intermediate type isn't threaded
  • Thinks Kotlin's standard library already provides andThen for (A)->B

context