Javier Rojas
March, 2021
Pure functions make code easier to read
With immutability:
d = %{age: 7, height: 110}
d = %{d | age: 9}
d = %{john: %{age: 7}, meg: %{age: 20}}
# d[:john][:age] = 8
d = %{ d | john: %{ d[:john] | age: 8 } }
Functions as variables
Functions as arguments to functions
Functions as return values
from uuid import uuid4
def prefixed_uuid():
return "acc-" + uuid4().hex
class Account(models.Model):
...
public_id = StringField(default=prefixed_uuid)
def authentication(view_func):
def authenticated_view(*args, **kwargs):
if args[0] == 'valid_user':
return view_func(*args, **kwargs)
return redirect_to_login()
return authenticated_view
@authentication
def welcome_view(username):
print(f"hello {username}!")
welcome_view = authentication(welcome_view)
Map: apply a function to all the elements of a list:
map(lambda x: x * x, range(5))
[0, 1, 4, 9, 16]
[x * x for x in range(5)]
[0, 1, 4, 9, 16]
Filter: Keep only some elements from a list:
filter(
lambda x: x % 2 == 0,
range(5)
)
[0, 2, 4]
[
elem
for elem in range(5)
if elem % 2 == 0
]
[0, 2, 4]
takewhile
, dropwhile
, groupby
, …reduce
, cache
(memoize), partial
(currying), …
def external_service():
"""Fetches a number from a remote endpoint"""
return 41
def action(retries=3):
""""Obtains number from a service, adds 1 to it.
Retries in case of timeout
"""
try:
v = external_service()
except Timeout as exc:
if retries > 0:
return action(retries=retries - 1)
else:
return 0
return v + 1
Goal: test retries in action
how?
Mock external_service
to timeout once and succeed afterwards
But, how to make the mock remember how many times it’s been called?
using a closure
(see closures.py)
A class can define a __call__
method, which will be called when instances are “called” as functions.
(see closures.py)