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=20260117T151424Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=5a20669231e446cea9e678cf1e5f8080b43d6dcd7a9b04f7aa98d193177c3dfdf54e0e740d9b5c0fe5207d143fec20429a278b61d50ae7b02800dc1491c8cd6f5c1798a76aa3950b633add87998c91a87d3834c15d9c1645bde06e2796aca4cc9b3fa5d4edd8d8ce022b55d173c43ad16252a4790cfdc19443329ea31433a7d530790a1ba0f78cfc84011334172a4e575a090dd9d4185aa813732c16cf24d714f31a5684ce0cc6bf6b6ba2706ed2999eac330cb1deedbb0eb30cf9421d890ac3edcd83354d8c3a1348145b06279ea62c4cba0b3e764a81a463cf0ef8bbae5c071d79dd637c37207be6a44b63f06a70607a7a05acd77e6b7f19084e1c0497afb8

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=20260117T151424Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=9970b6113ff061ffd6cb70e958c4059d944c9733f2093864c386aa176175688d5becbe81f9bbd5337a7e10b3b9e30bcb2c1d9f391c164e6a0174bf4976b4fc9ddb439c507a3f6fa254bdf58be6ac6981ecba2772339f1a507b7078e3b9a57c99b9120c8d09657a90b9490d27bb64d9242fe2741ec26cce27bd43f53dd75c51ec871732771b640ffbb4df390cbe0fb6241ca5b8839a4a973b50bdf0b5696d6d680810d351de3757a869489127f87c904ef503928534a1b6a63d6183a3fa46d4754b0c9b697f711c504b191fb5469d59fd2539887f8d971c4ff8962e009125fc67583fe4761ed952cbdaf8afefa712d1cf34578540b69f18551c076d60045275a0

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=20260117T151424Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&X-Goog-Signature=aae7cc14993b8674c4c9e048c3a44e96af8f1d4d5f186c936eb446e12992e7d7c8a2e7c022c037d6e9595871928464b1ef30a3e80420fc7d3fec42dba478d70614be9241e066f376afba28a8a657f72d51e027a99c4f5da2f2f36e5a2541b2ce158a57049e7a527a35b4f4a71d3332b34733611ed7a3671d84c124ad059acdb588ce1c6e703642190afd3389b63212f57afd8a74c71813e3c3d4f50c22b0e1d057f91fa38c957632b6be43424fdeac28e0a5d741c72b093ff2ba85db48331a53ade793af925b0d27a5ca02150d41e394abd76b668b007fbd1c28848b3c1b1dbb8e19aaa6502efee4ae7c6c2e9583b7c34b3cb428423dab951d36f1a78a12d7ac

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