Advanced HOF Techniques
Complex Function Manipulation
Functional Programming Paradigms
from functools import reduce
def pipeline(*functions):
def inner(arg):
return reduce(lambda x, f: f(x), functions, arg)
return inner
## Complex transformation pipeline
transform = pipeline(
lambda x: x * 2,
lambda x: x + 10,
str
)
result = transform(5) ## "20"
Generator-Based Higher Order Functions
Lazy Evaluation Techniques
def infinite_generator(start=0):
while True:
yield start
start += 1
def take(n, generator):
return [next(generator) for _ in range(n)]
counter = infinite_generator()
first_five = take(5, counter)
print(first_five) ## [0, 1, 2, 3, 4]
graph LR
A[Input Generator] --> B[Transformation Function]
B --> C[Output Generator]
Advanced Decorator Patterns
Context-Aware Decorators
def log_context(context='default'):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"Executing {func.__name__} in {context} context")
return func(*args, **kwargs)
return wrapper
return decorator
@log_context('LabEx Environment')
def process_data(data):
return data * 2
Functional Composition Strategies
Technique |
Description |
Use Case |
Currying |
Breaking multi-argument functions |
Partial application |
Function Chaining |
Sequential function applications |
Data transformation |
Monadic Operations |
Handling complex transformations |
Error management |
Currying Implementation
def curry(func):
def curried(*args):
if len(args) >= func.__code__.co_argcount:
return func(*args)
return lambda x: curried(*args, x)
return curried
@curry
def multiply(x, y, z):
return x * y * z
double_multiplier = multiply(2)
triple_result = double_multiplier(3)(4)
Advanced Error Handling
def retry(max_attempts=3):
def decorator(func):
def wrapper(*args, **kwargs):
attempts = 0
while attempts < max_attempts:
try:
return func(*args, **kwargs)
except Exception as e:
attempts += 1
if attempts == max_attempts:
raise e
return wrapper
return decorator
@retry(max_attempts=3)
def unstable_network_call():
## Simulated network operation
import random
if random.random() < 0.7:
raise ConnectionError("Network unstable")
return "Success"
Memoization with LRU Cache
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
Functional Programming Best Practices
- Minimize side effects
- Prefer immutability
- Keep functions pure
- Use composition over inheritance
Key Takeaways
- Advanced HOF techniques enable complex transformations
- Generators provide memory-efficient processing
- Decorators offer powerful function modification
- Functional programming principles enhance code quality