While we covered programming paradigms in a previous article, the most common way to differentiate between imperative and declarative programming is as follows: imperative programming instructs the computer on how to perform tasks, while declarative programming focuses on specifying what the desired outcome is.
Declarative vs imperative programming: 5 key differences
Imperative and declarative programming are two of the most popular programming paradigms in software development. Programming paradigms are approaches used to categorize or classify programming languages based on techniques and features they support.
When you’re starting to learn to code, you often begin by mastering constructs such as loops, functions, keywords, etc. While these are vital to learn, beginners will sometimes see less emphasis placed on applying these constructs to coding solutions and structuring them in ways that can help you with real-world problem-solving. Learning about programming paradigms can help bridge that gap.
Today we’ll go over declarative and imperative programming and their differences. By the end, you should have a solid foundational grasp of both paradigms, supported by a couple of code examples.
Let’s get started!
We’ll cover:
Get hands-on with declarative programming today.
The ability to work SQL is becoming an increasingly in-demand skill, both for software developers and people in less technical roles. If you’re interested in learning SQL and have no prior experience with it, then this course will be your light in a dark tunnel. You’ll start by covering the basics of SQL such as how to create a database, how to insert, query, and update data. You’ll also learn fundamental concepts that developers and data scientists use everyday such as multi-table operations, nested queries, and how to set up views. Throughout, you’ll get to execute SQL queries in your browser and see results in real-time - you won’t need to worry about set-up. At the end of this course, you’ll also get some hands-on practice with common SQL interview questions, so when the time comes, you’ll be ready and confident to answer any question that comes your way. Let’s get started!
What is imperative programming?#
Imperative programming is the oldest and most basic programming approach. Within the imperative paradigm, code describes a step-by-step process for a program’s execution. Because of this, beginners often find it easier to reason with imperative code by following along with the steps in the process.
The step-by-step process contains individual statements, instructions, or function calls. In the programming world, this process is called the control flow.
In other words, you’re interested in how the program runs, and you give it explicit instructions. Let’s illustrate this with a pseudocode example.
Say you want to build an app that returns the current weather and forecast for a given location. At a high level, you might design the app to work something like this when using an imperative approach:
Begin
Accept location from user input of either location name or ZIP code.
Call OpenWeather's Geocoding API to convert location data into geographic coordinates.
Call OpenWeather's Current Weather Data API.
Send geographic coordinates to OpenWeather.
Call OpenWeather's Daily Forecast 16 Days API.
Resend geographic coordinates.
Parse JSON returned by the APIs to extract current weather and forecast data.
Return current weather and forecast.
Display current weather and forecast to user.
End
In this simple example, imperative instructions dictate what the app should do, when to do it, and how to do it. This pseudocode is comparable to imperative programming, with which you create the logic of the program by making looping statements, calling functions, etc., all in a particular order.
Examples of imperative programming languages include:
- Java
- C
- Pascal
- Python
- Ruby
- Fortran
- PHP
Supporting both paradigms#
You can actually use Python in both declarative and imperative programming. Over the years, some other imperative languages have also received updates allowing them to support declarative-style programming. These include JavaScript, C++, and C#.
C++ in particular has seen several improvements in recent years, many of which make C++ more declarative. For example, newer versions of C++ have the Standard Template Library (STL), which provides four components: algorithms, containers, functions, and iterators.
Among these components are several built-in functions or operations that were previously performed manually, such as std::sort and std::list. Now you can easily use std::sort and continue coding without having to develop an imperative sorting algorithm.
The following code example demonstrates this feature at work:
What is declarative programming?#
In contrast with imperative programming, declarative programming describes what you want the program to achieve rather than how it should run.
In other words, within the declarative paradigm, you define the results you want a program to accomplish without describing its control flow. Ultimately, it’s up to the programming language’s implementation and the compiler to determine how to achieve the results. This places emphasis not on the execution process, but on the results and their ties to your overall goal. In other words, writing declarative code forces you to ask first what you want out of your program. Defining this helps you develop more expressive and explicit code.
Returning to our weather app example, the pseudocode might look something like this in the declarative paradigm:
Begin
Location submitted by user is location name or ZIP code.
Location is converted into geographic coordinates.
Weather data is retrieved for geographic coordinates.
Weather data is displayed for user.
End
As shown, the pseudocode is descriptive but lacks in detail. Only the result, displaying the weather data, matters to you without regard for the process.
Examples of declarative programming languages include:
- SQL
- Miranda
- Prolog
- Lisp
- Many markup languages (e.g., HTML)
Declarative vs imperative programming: 5 key differences#
Let’s expand on the differences between the two programming paradigms we’re discussing, using the following table for comparisons.
Imperative Programming | Declarative Programming |
1. Computation | |
You describe the step-by-step instructions for how an executed program achieves the desired results. | You set the conditions that trigger the program execution to produce the desired results. |
2. Readability and complexity | |
With the emphasis on the control flow, you can often follow the step-by-step process fairly easily. However, as you add more features and code to your program, it can become longer and more complex, making it increasingly confusing and time-consuming to read. | Step-by-step processes are eschewed. You’ll discover that this paradigm is less complex and requires less code, making it easier to read. |
3. Customization | |
A straightforward way to customize and edit code and structure is offered. You have complete control and can easily adapt the structure of your program to your needs. However, because you might have to deal with more code, you're more likely to run into editing errors than with declarative programming. | Customizing the source code is more difficult because of complicated syntax and the paradigm’s dependence on implementing a pre-configured algorithm. Some declarative programming programs may require more specificity to execute complex algorithms and functions |
4. Optimization | |
Adding extensions and making upgrades are supported, but doing so is significantly more challenging than with declarative programming, making it harder to optimize. This owes to the step-by-step structure of the paradigm and the fact that simple tasks require more code to process. The longer the code, the more likely you will run into errors. | You can easily optimize code because an algorithm controls the implementation. Furthermore, you can add extensions and make upgrades. |
5. Structure | |
The code structure can be long and complex. The code itself specifies how it should run and in what order. Due to the increased complexity, the code can sometimes be confusing because it may perform more than one task. | The code structure is concise and precise, and it lacks detail. Not only does this paradigm vastly limit the complexity of your code, but the code is more efficient. |
Pros and cons of declarative vs imperative programming#
Imperative and declarative programming both solve problems effectively, but they optimize for different things. Imperative programming gives you direct control over execution, while declarative programming focuses on readability and abstraction.
In real-world software engineering, the best choice often depends on the type of system you’re building and how much control you need.
Paradigm | Advantages | Disadvantages | Best use cases |
Imperative programming | Fine-grained control, easier low-level optimization, flexible execution flow, strong performance tuning capabilities | More boilerplate code, harder to maintain at scale, increased complexity in large systems | Operating systems, game engines, embedded systems, performance-critical algorithms |
Declarative programming | Cleaner and more readable code, less boilerplate, faster development, easier maintenance and scalability | Less execution control, harder to debug internal optimizations, hidden performance costs, sometimes less flexible | SQL queries, React UI development, infrastructure-as-code, data transformations, configuration management |
When does imperative programming work best?#
Imperative programming is usually the better choice when you need precise control over execution and performance.
Common examples include:
Operating systems
Game engines
Embedded systems
Real-time applications
Performance-critical algorithms
For example, game engines often require direct memory management and precise rendering control. Declarative abstractions may hide too much detail in those scenarios.
Imperative code also makes sense when:
You need low-level hardware access
Performance tuning is critical
Execution order matters heavily
When does declarative programming work best?#
Declarative programming shines when readability, scalability, and developer productivity matter more than low-level execution details.
Common examples include:
SQL queries
React UI development
Infrastructure-as-code (Terraform)
Data transformation pipelines
Kubernetes configuration files
Instead of manually controlling every step, developers describe the desired result while frameworks and engines handle the implementation details internally.
This reduces boilerplate and makes large systems easier to maintain.
Which paradigm should you use?#
Most modern applications combine both paradigms rather than choosing only one.
For example:
React uses declarative UI rendering
JavaScript event handling often remains imperative
SQL queries are declarative, while backend business logic may be imperative
Declarative programming improves productivity and maintainability because developers can work at a higher level of abstraction. Imperative programming remains valuable when precise control, optimization, or low-level system behavior matters.
In practice, choosing the right paradigm is really about choosing the right level of abstraction for the problem you’re solving.
This trade-off also appears in System Design decisions, where scalability, maintainability, performance, and developer productivity all need to be balanced carefully.
Imperative vs declarative programming: Side-by-side code examples#
Imperative and declarative programming often solve the same problems—but in very different ways. Imperative code focuses on how to perform each step, while declarative code focuses more on what result you want.
The easiest way to understand the difference is by comparing the same task side by side.
Example 1: Summing numbers in a list#
Task#
Calculate the total sum of all numbers in a list.
Imperative style | Declarative style |
```python | |
numbers = [1, 2, 3, 4, 5] |
total = 0
for num in numbers:
total += num
print(total)|python
numbers = [1, 2, 3, 4, 5]
total = sum(numbers)
print(total)
In the imperative version, you explicitly control every step using a loop and accumulator variable. In the declarative version, you simply describe the goal (`sum(numbers)`) and Python handles the implementation internally.Declarative code is shorter and easier to read, while imperative code gives you more control over the process.---## Example 2: Filtering even numbers### TaskCreate a new list containing only even numbers.| Imperative style | Declarative style ||---|---|| ```pythonnumbers = [1, 2, 3, 4, 5, 6]evens = []for num in numbers:if num % 2 == 0:evens.append(num)print(evens)``` | ```pythonnumbers = [1, 2, 3, 4, 5, 6]evens = list(filter(lambda x: x % 2 == 0, numbers))print(evens)``` |You can also write the declarative version using a list comprehension:```python id="bljv0s"numbers = [1, 2, 3, 4, 5, 6]evens = [x for x in numbers if x % 2 == 0]print(evens)
The imperative approach shows each step clearly: loop, check condition, append result. The declarative version focuses on the filtering logic itself instead of the mechanics of iteration.
This reduces boilerplate and often improves readability.
Example 3: Transforming data#
Task#
Double every number in a list.
```python | |
numbers = [1, 2, 3, 4] |
doubled = []
for num in numbers:
doubled.append(num * 2)
print(doubled)|python
numbers = [1, 2, 3, 4]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled)
In the imperative version, you manually control how values are transformed and stored. In the declarative version, you describe the transformation rule (`x * 2`) and let `map()` apply it automatically.Declarative code tends to be more compact, while imperative code can sometimes feel easier to debug step by step.---## Modern declarative examplesDeclarative programming is extremely common in modern software development.### SQL (declarative)```sqlSELECT nameFROM usersWHERE age > 18;
You describe what data you want—not how the database should retrieve it.
React JSX (declarative UI)#
function App() {return <h1>Hello, world!</h1>;}
You describe what the UI should look like, and React handles updating the DOM behind the scenes.
Which style should you use?#
Declarative programming is usually easier to read, maintain, and scale because it reduces repetitive boilerplate code. That’s why modern frameworks and APIs often lean heavily toward declarative patterns.
Imperative programming is still extremely useful when you need:
Detailed control over execution
Complex state management
Performance optimizations
Step-by-step debugging
In practice, most real-world applications use a mix of both styles. Great developers know when to prioritize readability and when they need lower-level control.
Declarative vs imperative programming: Code example#
We’ve discussed the key differences between imperative and declarative programming. Let’s look at a simple code example.
For this example, we’ll use Python. As mentioned earlier, Python can be used in both imperative and declarative programming and is one of the most popular languages today for beginners and experts alike.
Imperative programming#
In this example, we’ve created a variable named total and set it to 0. We’ve also created a list of numbers, myList, that we want to add to the total.
Next, we’ve created a for loop to access each item in the list individually and add it to the total. Finally, we’ve used the print function to display our final answer (15).
This code follows a step-by-step process. In the first iteration, we add 1 to the initial total (0) to get the new total (1). Then the loop runs again, adding the next number in our list to 1 to get the new total (3). And so on. You’ve defined the process by creating a loop that iterates through the entire list to perform a task.
This process can become time-consuming and increasingly complex as you add features and code. Now let’s look at how we can achieve the same result using declarative programming.
Declarative programming#
As you can see, the code structure in this example is more concise. Unlike the imperative programming example, we haven’t outlined the steps. Instead of using a loop to iterate over our entire list, we’ve used the sum() method, which works for us.
In other words, you can read the declarative Python code as finding the sum of all the numbers in our list. You only care about the result, not the process.
Get hands-on with imperative programming today.
Python is one of the favorite programming languages among developers and data scientists due to its intuitive syntax and advanced functionality. These properties arguably also make Python the most in-demand programming language in the world today. Python libraries make things easier and help reduce the time and effort required to solve big problems. This path will help you use your programming experience to quickly adapt Python to your programming requirements. You'll also go through a few brain teasers to test your understanding. By the end, you'll have advanced knowledge to confidently use Python in your next project.
React vs vanilla JavaScript: Declarative vs imperative programming in the real world#
One of the easiest ways to understand declarative vs imperative programming is through frontend development. Vanilla JavaScript DOM manipulation is mostly imperative because you manually describe every UI update step. React, on the other hand, is declarative because you describe what the UI should look like based on state, and React handles the DOM updates automatically.
This difference becomes much more important as applications grow in complexity.
The core idea#
With imperative programming, you tell the browser exactly:
Which element to find
What content to change
When to update the UI
With declarative programming, you describe:
The current application state
What the UI should look like for that state
The framework takes care of updating the DOM behind the scenes.
Example: Counter application#
Imperative approach (vanilla JavaScript)#
<div><h2 id="count">0</h2><button id="incrementBtn">Increment</button></div><script>let count = 0;const countElement = document.getElementById("count");const button = document.getElementById("incrementBtn");button.addEventListener("click", () => {// Step-by-step manual updatecount += 1;countElement.textContent = count;});</script>
import { useState } from "react";function Counter() {const [count, setCount] = useState(0);return (<div><h2>{count}</h2><button onClick={() => setCount(count + 1)}>Increment</button></div>);}export default Counter;
What’s happening here?#
You don’t manually update the DOM.
Instead:
You describe the UI based on
countWhen state changes, React automatically re-renders the UI
React handles DOM synchronization internally
You focus on what the UI should look like, not how to update it step by step.
Key difference#
Imperative code gives you direct control over the DOM and execution flow. This can be useful for fine-grained behavior and low-level optimizations.
Declarative code focuses on describing UI state and desired output. React abstracts the DOM update process, which reduces boilerplate and improves maintainability.
As applications become larger, declarative patterns often become easier to manage.
Imperative vs declarative frontend comparison#
Aspect | Imperative DOM manipulation | Declarative React |
Control flow | Manual step-by-step updates | Describe desired UI state |
Readability | More verbose | More concise and readable |
UI updates | Manual DOM manipulation | Automatic re-rendering |
State handling | Managed manually | Built into framework state system |
Boilerplate | Higher | Lower |
Scalability | Harder for large apps | Easier to scale |
Debugging complexity | Easier for tiny apps, harder for large ones | Simpler state-driven debugging |
Why modern frontend frameworks prefer declarative programming#
Modern frontend frameworks prefer declarative programming because it improves maintainability and scalability. Instead of manually updating the UI everywhere, developers work with predictable state changes and reusable components.
This becomes especially important in:
Large applications
Real-time interfaces
Complex state management systems
Team-based development
Declarative programming also speeds up development because developers spend less time writing repetitive DOM manipulation code.
Frameworks like Vue, SwiftUI, and Jetpack Compose also follow declarative principles for the same reason: managing UI state becomes much simpler as applications grow.
Why SQL is a classic declarative programming language#
SQL is one of the best real-world examples of declarative programming because it lets you describe what you want without specifying how to get it. Instead of manually looping through data and controlling execution step by step, you simply write a query describing the desired result.
If you already know basic SQL, you’ve already used declarative programming.
The core idea#
In SQL:
You describe the data you want
The database engine decides how to retrieve it
You do not manually manage loops, traversal logic, or memory allocation
For example, when querying a database, you don’t tell it:
Which rows to scan first
Which sorting algorithm to use
How to optimize memory usage
The database optimizer handles those decisions internally.
That’s what makes SQL declarative.
Example task#
Goal#
Find all users older than 18 and sort them by name.
Imperative-style pseudocode#
results = []for user in users:if user.age > 18:results.append(user)results.sort(key=lambda x:
SELECT nameFROM usersWHERE age > 18ORDER BY name;
What’s different?#
The SQL query only describes:
The data you want (
name)The filtering condition (
age > 18)The final ordering (
ORDER BY name)
You never specify:
How rows are scanned
Which indexes are used
How sorting happens internally
The database engine decides all of that automatically.
Why SQL is declarative#
SQL focuses on WHAT data is needed rather than HOW to retrieve it.
Behind the scenes, the database optimizer may:
Use indexes
Reorder operations
Parallelize execution
Choose faster query plans
This abstraction improves:
Readability
Productivity
Maintainability
A useful analogy is ordering food at a restaurant:
You describe what you want
The kitchen decides how to prepare it
Declarative programming works the same way.
Imperative vs declarative SQL comparison#
Aspect | Imperative approach | Declarative SQL approach |
Control flow | Managed manually | Handled by database engine |
Level of abstraction | Lower-level | Higher-level |
Readability | More verbose | More concise |
Performance optimization responsibility | Developer-managed | Database optimizer-managed |
Code complexity | Higher for large operations | Simpler and cleaner |
Why declarative programming became popular#
Declarative programming became popular because developers can focus more on business logic and less on implementation details. Instead of manually controlling execution flow, developers describe the desired outcome and let systems optimize the execution internally.
This approach scales especially well for complex systems because:
Code becomes easier to maintain
Optimization can happen automatically
Teams can build faster with less boilerplate
That’s why declarative programming appears everywhere in modern software development.
Modern declarative technologies#
You’ll see declarative ideas in many modern tools and frameworks:
React → Describe UI based on application state
GraphQL → Request exactly the data you need
Terraform → Define infrastructure declaratively
Kubernetes YAML → Describe desired system configuration
In all of these cases, developers focus on the desired outcome while the framework or platform handles the execution details internally.
Functional vs imperative programming#
Functional and imperative programming solve problems in very different ways. Imperative programming focuses on changing program state step by step, while functional programming focuses on transforming data through expressions and pure functions.
In many ways, functional programming is considered a more declarative style because you describe what transformations should happen rather than manually controlling execution flow.
Most modern programming languages support multiple paradigms, which means developers often mix both styles in real applications.
The core difference#
Imperative programming works by:
Changing variables over time
Using loops and mutable state
Explicitly controlling execution flow
Functional programming focuses on:
Immutable data
Pure functions
Data transformations
Avoiding side effects
Instead of telling the program exactly how to update state step by step, functional code describes how data should flow through transformations.
Imperative vs functional programming comparison#
Feature | Imperative Programming | Functional Programming |
Main focus | Step-by-step execution | Data transformation and expressions |
State management | Mutable state | Immutable state |
Mutability | Common | Avoided when possible |
Side effects | Frequent | Minimized |
Code structure | Loops and commands | Functions and transformations |
Readability | Explicit but sometimes verbose | Concise and expressive |
Debugging | Easier step tracing | Easier reasoning about pure logic |
Scalability | Can become complex at scale | Often easier for distributed systems |
Parallelism/concurrency | Harder due to shared state | Easier because of immutability |
Common languages/frameworks | C, Java, operating systems code | Haskell, Scala, Spark, functional JavaScript |
numbers = [1, 2, 3, 4, 5, 6]result = []for num in numbers:if num % 2 == 0:result.append(num * 2)print(result)
Functional approach#
numbers = [1, 2, 3, 4, 5, 6]result = list(map(lambda x: x * 2,filter(lambda x: x % 2 == 0, numbers)))print(result)
You could also write this more cleanly using a comprehension:
numbers = [1, 2, 3, 4, 5, 6]result = [x * 2 for x in numbers if x % 2 == 0]print(result)
What’s the difference?#
The imperative version explicitly:
Loops through items
Checks conditions
Modifies a mutable list step by step
The functional version focuses on transformations:
Filter the even numbers
Map them to doubled values
Instead of describing execution flow directly, it describes the data transformation pipeline.
When does imperative programming work best?#
Imperative programming is usually better when:
You need detailed execution control
Performance optimization matters heavily
You’re interacting directly with hardware or memory
Common examples include:
Game loops
Operating systems
Embedded systems
Performance-sensitive workflows
These systems often require precise control over state and execution order.
When does functional programming work best?#
Functional programming shines in systems that involve heavy data transformation or concurrency.
Common examples include:
Data processing pipelines
Distributed systems
Concurrent applications
Stream processing systems
Functional approaches work especially well when immutability and predictable behavior become important.
Why functional programming became popular#
Functional programming became more popular as software systems grew larger and more distributed. Pure functions and immutable state make code easier to reason about because there are fewer unexpected side effects.
This also helps with:
Concurrent execution
Parallel processing
Scalability in distributed systems
Predictable debugging
Modern frameworks and APIs increasingly adopt functional ideas because they improve maintainability and composability.
Functional programming in modern development#
You’ll see functional programming concepts in many modern technologies:
React hooks → Functional state management
Redux → Immutable state updates
Spark → Functional-style distributed data processing
Haskell → Pure functional programming language
Scala → Combines object-oriented and functional styles
JavaScript and Python → Support functions like
map(),filter(), and lambdas
Even if you never use a “pure” functional language, you’ll almost certainly use functional programming concepts in modern software development.
Get started with declarative and imperative programming today#
Today we’ve covered the basics of imperative and declarative programming, along with their key differences. In general, you should have a somewhat easier time using declarative programming to achieve your desired results. Although imperative programming is easy to learn, managing code bases written using the imperative paradigm can become complex as you add more features and code. At the same time, you maintain complete control, allowing you to customize your program more.
As you continue your programming journey, you’ll want to learn the features of other paradigms under the umbrella of imperative programming, like procedural programming and object-oriented programming. Under declarative programming, additional paradigms include functional programming and logic programming.
In the meantime, if you’re interested in starting your declarative programming journey, check out the course An Introductory Guide to SQL. It covers creating, updating, and manipulating databases to attain the results you want, all in an interactive, hands-on environment.
If you prefer to start with imperative programming, we recommend the Python for Programmers learning path. The Python programming language is widely popular and can help you gain an edge in the job market.
Happy learning!
Continue learning about programming languages#
Frequently Asked Questions
What is the difference between declarative and imperative programming?
What is the difference between declarative and imperative programming?