Arun Pandian M

Arun Pandian M

Android Dev | Full-Stack & AI Learner

The Power of Composition: Building Big from Small

It’s not the pieces themselves that make something great — it’s how you put them together.” — Anonymous (and every LEGO master ever)

If there’s one concept that captures the heart of Functional Programming, it’s composition. Think of it like connecting small, reusable building blocks to form something powerful and beautiful. Whether you’re combining simple functions to form complex logic, or merging reusable UI components, composition is the art of building big things from small, pure parts.

Why Composition Matters

In an imperative world, we often think step-by-step:

val numbers = listOf(1, 2, 3)

var doubled = mutableListOf<Int>()

for (n in numbers) {
    doubled.add(n * 2)
}

val result = doubled.filter { it > 3 }

You’re telling how to do it — manually instructing every move.

In a functional world, we describe what to do:

val result = listOf(1, 2, 3)
    .map { it * 2 }
    .filter { it > 3 }

You’re composing transformations, like chaining mini-machines that work together.

https://storage.googleapis.com/lambdabricks-cd393.firebasestorage.app/compose_func.svg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=firebase-adminsdk-fbsvc%40lambdabricks-cd393.iam.gserviceaccount.com%2F20260303%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260303T155620Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=11c3b4008651584bd4e478fcbe6d90a2f72310677365703033b475fdd56803d6857035d2926662282d52d64fd355aff719cc12d5b1719946f07cfa960e0ab51c5471d070a46f9b309c2977a220d91a327dddb69d461e05f2feb226cd0f1b5cfc8252b26904573e9d1dc5b163e7077899641404e3563558aafc0d6c5fa2aae68f428b71e15929072b06b87452d15f40208f1862566214aeb5f7e5906aff1af14352894bae9887bde884dfb494d46b5e57e8da42e858920f7b169712612447294e41f58a0842e9bc1fd61b9b11f7ead571d5ff19ed1289121114f91b338966d20a95840e4dc4a841b129571cd637ee266ae25f380a1760b0d584e8e8a5b69d0e17

Real-Life Analogy: The Coffee Bar

Imagine a coffee bar.

The barista doesn’t reinvent the recipe every time.Instead, they compose a drink by combining small steps — grinding beans, brewing coffee, adding milk. Each step is reusable, predictable, and can be rearranged to make different drinks.

That’s function composition — combine existing, reliable parts instead of writing new code from scratch.

Composition in Kotlin

fun f(x: Int) = x + 1
fun g(x: Int) = x * 2

// Compose manually
val result = f(g(3))  // (3 * 2) + 1 = 7

Or create a reusable compose helper:

fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C = { x -> f(g(x)) }

val composed = compose(::f, ::g)
println(composed(3)) // 7

Composition — Building Big from Small

The Laws of Composition

Composition isn’t just about connecting things — it also follows powerful mathematical laws that make reasoning about code much easier.

Let’s meet our two heroes: Associative and Identity.

Associative Law — Order of Grouping Doesn’t Matter

“Whether you stack bricks from the left or the right, the wall still stands strong.”
https://storage.googleapis.com/lambdabricks-cd393.firebasestorage.app/associative_law.svg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=firebase-adminsdk-fbsvc%40lambdabricks-cd393.iam.gserviceaccount.com%2F20260303%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260303T155620Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=26915e3752e390f7acf8312fc0db535ecaf2b01ab2dc1bbf01df512d5a1cddc62cb6ff3c05b768f7225f3a60e751fa34c04704a85807008e4f954d3402a6f895fa2c5feaf92272798303364b90be7f38fe13ed372e32bc6a70770295ab522c45683e78e55ea1558193a17cfaffd8ca59d267413a69f0bec0cd9244f3e082c36142ef847644fb47a75058dacb4ed78a90d1889d55a85689d1bf79f1b1264743e37e0dd80958520b6d3edf2a636ea50b3ee6556892431353ab82285ecd5b6d2c1ffe20840d186debdcf1026ce53df8c08615694d668865cfd83b46754c2a685d3ce26aeecd0d92bb39f280b0d0e2a7bebb5798fead4e40f25c22593b2054a0ac80

In Kotlin:

val f: (Int) -> Int = { it + 1 }
val g: (Int) -> Int = { it * 2 }
val h: (Int) -> Int = { it - 3 }

val left = f(g(h(5)))   // f ∘ (g ∘ h)
val right = f(g(h(5)))  // (f ∘ g) ∘ h

println(left == right) //  true — associative

This means composition is predictable and reorder-safe.

Just like applying filters in a photo editing app — whether you group brightness before contrast or after, the pipeline behaves consistently.

Identity Law — Doing Nothing Still Works!

“Sometimes doing nothing is the best thing you can do.” — Lao Tzu (and every functional programmer ever)
https://storage.googleapis.com/lambdabricks-cd393.firebasestorage.app/identity_law.svg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=firebase-adminsdk-fbsvc%40lambdabricks-cd393.iam.gserviceaccount.com%2F20260303%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260303T155620Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=9fb176965bd6535e2f7901038b8d8e74c54219e01acd6b5a7e2a28f86661008dac20090e719f8923824049691683a2da72db5068d545954e00d28120acda134487213e9ab2f2667056062ab4cbe6928f214e1c463343a7abf4bf79eae4865d5e6bb9b7195ba4db299598aa1ffcce002023d63afd77f18e577bf21da624da48efcf50b1c8fadfe2311e0598c4902454644fa70659c394c0b24f16a1c50516d46ca2a193afb797ac807357bfb36472a8cc49cdca7334f1236890b191a8f934af983c105d39ddb752297fb598937893eba9fc72f070aa38d8474818dc7e82ec504eb4405a4c74101886b46c034e98e3787f3c7349d0e0a070830e66831e6b01eba4

In code, the identity function is simply:

val id: (String) -> String = { it }
val f: (String) -> String = { it.uppercase() }

println(f(id("hello")))  // HELLO
println(id(f("hello")))  // HELLO

Whether you apply id before or after f, the result is the same.

It’s like looking into a mirror — you see exactly what’s in front of it. No change, no distortion — just reflection.

The Core Idea

Composition gives your code clarity, reuse, and elegance.

You build functions like Lego blocks — modular, replaceable, and easy to test.

And because of laws like Associativity and Identity, you can reason about your code with confidence — just like solving math equations.

“Good design is not when there’s nothing more to add, but when there’s nothing left to take away.” — Antoine de Saint-Exupéry

Now that we’ve seen how composition lets us build big ideas from small pieces, it’s time to explore the real heroes behind it — Higher-Order Functions, where functions themselves become the building blocks of logic.

#kotlin_fp#kotlin_programming#higher_order_functions#functional_programming#function_composition#clean_code_principles#software_design#composition_over_inheritance#functional_thinking#fp_laws