Skip to main content

Command Palette

Search for a command to run...

Programming Paradigms: Not Tribes to Join, Just Different Ways of Thinking

Imperative, declarative, OO, functional — the label matters less than knowing which lens fits the problem.

Updated
3 min readView as Markdown
Programming Paradigms: Not Tribes to Join, Just Different Ways of Thinking
I
Welcome to Bits8Byte! I’m Ish, an AI Engineer with 11+ years of experience across software engineering, automation, cloud, and AI-driven systems. This blog is where I share practical insights, technical deep dives, and real-world lessons from building modern software and exploring the fast-moving world of AI. My background spans Java, Spring Boot, Python, FastAPI, AWS, Docker, Kubernetes, DevOps, observability, and automation. Today, my work is increasingly focused on AI engineering, including LLM applications, AI agents, production-grade microservices, and scalable cloud-native architectures. Here, you’ll find thoughtful writing on AI trends, engineering best practices, software architecture, and the mindset required to adapt and grow in the age of AI. My aim is not just to explain technology, but to make it useful, practical, and grounded in real implementation experience. Thanks for stopping by. I hope this space helps you learn something valuable, think more deeply, and stay ahead in a rapidly evolving industry.

Early on, programming paradigms sound like factions you're supposed to pick a side in — object-oriented people over here, functional people over there, everyone slightly suspicious of the others. After enough years you realise that's mostly noise. A paradigm isn't a team. It's a way of thinking about a problem, and the useful skill is knowing which way of thinking fits what's in front of you.

Here's the honest version of the fundamentals, from someone who learned to think in one paradigm and had to pick up the others the slow way.

Imperative: tell the computer how

The most basic split is imperative versus declarative. Imperative code is a list of instructions: do this, then this, then update that. You're spelling out the how, step by step — loops, variables changing, state moving forward. It's how most of us first learn to code, and it maps closely to how the machine actually runs. The upside is control and clarity about exactly what happens. The downside is that as programs grow, tracking all that changing state becomes the thing that quietly eats your afternoons.

Declarative: tell the computer what

Declarative code flips it. You describe the result you want and let something else work out the how. You've used this even if the word is new: SQL is declarative — you say what data you want, not how to scan the tables. So is HTML — you describe the page, you don't script its construction. When it fits, declarative code is shorter and harder to get subtly wrong, because you're not micromanaging steps that could each go astray. When it doesn't fit, you end up fighting the abstraction.

Object-oriented: organise around things

Object-oriented programming — the one I grew up on in Java — organises code around objects: bundles of state and the behaviour that acts on that state. The pitch is that it mirrors how we think about the world (a user, an order, an account) and keeps related data and logic together. It's genuinely good at modelling systems with clear entities. Its failure mode, which anyone who's maintained a large OO codebase knows in their bones, is ceremony and sprawling hierarchies — abstraction added because you could, not because you should.

Functional: organise around transformations

Functional programming leans the other way: build behaviour out of pure functions — same input, same output, nothing hidden changed on the side. Favour immutability; compose small functions into bigger ones. The whole appeal is that code with no hidden state is far easier to reason about and test, because nothing surprises you from a distance. The cost is that some problems genuinely are about changing state over time, and pretending otherwise gets awkward fast.

Why this matters more now, not less

Here's the part the paradigm wars miss. Modern languages stopped picking sides. Scala, Kotlin, even C++ are proudly multi-paradigm, and the mainstream ones have absorbed each other's best ideas — Java grew lambdas and streams; Python has been multi-paradigm from the start. The industry quietly settled the argument: you use the paradigm that fits the task, sometimes several in the same file.

So the goal was never to become a functional purist or an OO loyalist. It's to hold several of these lenses at once and know which one makes the problem in front of you simpler. Part 2 gets into how they combine in real code. For now, the mental shift worth making is small but real: stop asking which paradigm is best, and start asking which one this problem is asking for.