Declarative & Imperative
Declarative VS Imperative Approach
In a declarative style, the code defines what should be done and abstracts away the implementation details, often relying on built-in functionality or higher-order abstractions. It focuses on what the program should do rather than on how it should be done. The imperative style focuses on how the program achieves the result, explicitly outlining the steps.
Declarative Converting Text to Uppercase
class TextTransformer:
def __init__(self, text):
self.text = text
def transform(self):
# Declarative: Use the built-in string method
return self.text.upper()
# Usage
transformer = TextTransformer("hello world")
print(transformer.transform()) # Output: HELLO WORLD
TIP
- The
upper()
method is declarative, as it directly specifies the desired outcome (uppercase transformation).
Imperative converting Text to Uppercase
class TextTransformer:
def __init__(self, text):
self.text = text
def transform(self):
# Imperative: Explicitly create a new uppercase string
result = ""
for char in self.text:
if 'a' <= char <= 'z': # Check if the character is lowercase
result += chr(ord(char) - 32) # Convert to uppercase
else:
result += char # Keep non-lowercase characters unchanged
return result
# Usage
transformer = TextTransformer("hello world")
print(transformer.transform()) # Output: HELLO WORLD
TIP
- Every step is explicitly defined, including checking if each character is lowercase and manually converting it to uppercase using ASCII values.
Comparison
Feature | Declarative | Imperative |
---|---|---|
Focus | Specifies the desired outcome directly | Explicitly describes each transformation |
Simplicity | Abstracts details | More verbose and detailed |
Readability | Easier to understand | Harder to follow for complex logic |
This example shows how declarative programming relies on high-level abstractions (like upper()
), while imperative programming handles the details explicitly.
Example 2
Declarative filter Using a filter
Function
class NumberFilter:
def __init__(self, numbers):
self.numbers = numbers
def get_even_numbers(self):
# Declarative: Specify "what" to filter
return list(filter(lambda x: x % 2 == 0, self.numbers))
# Usage
numbers = NumberFilter([1, 2, 3, 4, 5, 6])
print(numbers.get_even_numbers()) # Output: [2, 4, 6]
TIP
- The
filter
function handles the iteration and condition checking. - The focus is on describing the outcome, not the steps.
Imperative filter Using a Loop in a Method
class NumberFilter:
def __init__(self, numbers):
self.numbers = numbers
def get_even_numbers(self):
# Imperative: Specify "how" to filter
even_numbers = []
for num in self.numbers:
if num % 2 == 0:
even_numbers.append(num)
return even_numbers
# Usage
numbers = NumberFilter([1, 2, 3, 4, 5, 6])
print(numbers.get_even_numbers()) # Output: [2, 4, 6]
TIP
- You explicitly define the iteration (
for num in self.numbers
) and filtering logic (if num % 2 == 0
). - The process involves step-by-step instructions.
Key Differences
Feature | Declarative | Imperative |
---|---|---|
Iteration | Abstracted (uses filter ) | Manual (uses for loop) |
Focus | Describes the outcome | Describes the process |
Code Simplicity | Often more concise | Often more verbose |
Example 3
Declarative (Using sum
inside a class)
class NumberOperations:
def __init__(self, numbers):
self.numbers = numbers
def get_sum(self):
# Declarative: Use built-in sum
return sum(self.numbers)
# Usage
numbers = NumberOperations([1, 2, 3, 4, 5])
print(numbers.get_sum()) # Output: 15
Imperative (Manually Computing the Sum)
class NumberOperations:
def __init__(self, numbers):
self.numbers = numbers
def get_sum(self):
# Imperative: Explicitly calculate the sum
total = 0
for num in self.numbers:
total += num
return total
# Usage
numbers = NumberOperations([1, 2, 3, 4, 5])
print(numbers.get_sum()) # Output: 15
In a Nutshell
A declarative approach abstracts away the implementation details, while the imperative approach gives explicit control over the process.