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%2F20260117%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260117T134440Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=9c080b92cb94a89656c4c51165fce6ab7c829d3082f95408b5276018105451eb986c0b74e15cb9ac3aec8627813cfdf1e3a86500215bec6bc9d1acf3ab4475fddb8866b8cb0e8367e4c5087a224d123392f1287fa4f366460bde57c2fcc42f3c8116772ec2576b17166e1dce9e25bb4e1cb5ec548dd2928c5c96b4a7fc59ddb3f01dac253531c218b6cb15b1dfec32b9c0439c545d86b98e2eac58d1a4c908b2a7e0c1c38d7cd55baf343f054946b470dea8326cbaf132f7b8b2ab0f8e2422b17abb8e88c0453e40e27792a537317e6a8ea30b3e02ad95e23c944de6aa45b437b1c998d9c35f9d5db6e8fe444450ae72cad68fcdcb57bd763971a342fda98936

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%2F20260117%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260117T134440Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=3cb1909af590a97a2a339379dcf643d98f0fac784be8cb45c86d3594860112c505478eaa44cc0ba334d4ac9370d44e8f9e1cb9d53670f8c706b55729dd7d719c535fb3babaec6208583320aa713f32d516f03e545e8cb58a1a1a77ca97fb7d54f8293042d2c200eef470681d126b2d4066da978c765e86388eab162cd8ee9ce46107f21f48a43e84b6dfe1ff0a2a3280e20eb1341b736731167e8a7a1a48e60279a54093360575f023683023d6c7944a1e9208c51aa20174978e873f6596868925d860aea68cd76518cda15979b73a9fe53754ea589070a97a10932a0b6c9fcb8492d7ef734d19fd8a72dc8a063f0a959a2671d25b98c0f1f50024bb1989a68a

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%2F20260117%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260117T134440Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=55bb3dd472b12ed1ed3a1364a1dbb5233f828cbf016facbbbc5d4fd1f4d8d3d14c56f8b79d246f5cf63f86bdf1789bdd7cd0af3f04d530e60d2c01e13f050f6c8c8139b3c67604c689d169432f21d50dd1c51f8d723e2783e66de98b68ec94add46ecbe4433585d4f71968ed6184232bbc195f73f5fda242406a98f18d28bf83855991be3f9703ee4306b4c2bf6a32b68592bb27daf4ea203e28f0b8497cac6e8d43c92f2ab21800d0431543dd5b9dc33e864d3a8ed8220bd291c9e79cababc04f069fd63789752ac95155f20c820a8b727513ae5f1404906e6fe49eccc2ceb94a793fb5fe8095781d7097b15327f976f5d546df7fa25b1f7df7c99f7ab37b97

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