FUNCTIONAL PROGRAMMING CONCEPTS IN PYTHON
#WHO
Matt Gathu
Software Engineer at Jumo World
Pythonista and Rust Enthusiast
#WHAT IS FP
#FEATURES
-
Modularity
-
No shared state (purity)
-
No mutability (No side effects)
#ADVANTAGES
-
Modular Design
-
Ease of debugging and Testing
-
Composability
-
Formal provability
-
Memoization
-
Concurrency
#FP in Python
#Language Features
First Class Functions |
---|
High Order Functions |
Comprehensions |
Lazy Evaluation |
#First Class Functions
assigned to variables
returned as values
passed as arguments
def handle_value_error(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except ValueError:
return None
return wrapper
#High Order Functions
map | filter | reduce |
---|
def upper(x):
return x.upper()
def apply(func, args):
return func(*args)
def map(func, sequence):
return [apply(func, x) for x in sequence]
map(upper, ['a', 'b', 'c']) == ['A', 'B', 'C']
#Decorator Functions
High Order functions that apply transformation to other functions.
def auto_retry(tries=3, exc=Exception, delay=5):
def decorator(func):
def wrapper(*args, **kwargs):
for trial in range(1, tries+1):
try:
return func(*args, **kwargs)
except exc:
time.sleep(trial * delay)
continue
raise exc
return wrapper
return decorator
@auto_retry(exc=HTTPException)
def moyale_network_call():
...
#Comprehensions
based on set-builder notation.
# List Comprehensions
squares = [x**2 for x in range(10)]
# Generator Comprehensions
squares = (x**2 for x in range(10))
# Set Comprehensions
a = {x for x in 'abracadabra' if x not in 'abc'}
# Dictionary Comprehensions
squares = {x: x**2 for x in (2, 4, 6)}
#Lazy Evaluation
This is a call-by-need evaluation strategy that delays evaluation of an expression until its value is needed.
def gen_even_ints(n):
for i in range(n):
if i % 2 == 0:
yield i
>>> gen = gen_even_ints(4)
>>> gen
<generator object gen_even_ints at 0x108dee258>
>>> next(gen)
0
>>> next(gen)
2
>>> next(gen)
-------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-6-8a6233884a6c> in <module>()
----> 1 next(gen)
StopIteration:
#Batteries Included
#Itertools Module
count
cycle
repeat
accumulate
chain
dropwhile
combinations
permutations
count() | count(10) --> 10 11 12 13 14 ... |
---|---|
cycle() | cycle('ABCD') --> A B C D A B C D . |
repeat() | repeat(10, 3) --> 10 10 10 |
accumulate() | accumulate([1,2,3,4,5]) --> 1 3 6 10 15 |
---|---|
chain() | chain('ABC', 'DEF') --> A B C D E F |
#Functools Module
partial
reduce
wraps
import functools
def log (message, subsystem):
"Write the contents of 'message' to the specified subsystem."
print '%s: %s' % (subsystem, message)
...
server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')
Functional Programming Concepts in Python
By Matt Gathu
Functional Programming Concepts in Python
Functional Programming Concepts in Python
- 844