Functional programming

Pure functions

Given same argument to the function, it should always return same output

Pure functions

Should not mutate anything that can be seen outside function 

some_global_list = []


def not_so_pure(mutable_object):
    mutable_object.append(1)


def also_not_so_pure(mutable_object):
    mutable_object.append(2)

Pure functions

also_not_so_pure(some_global_list)
not_so_pure(some_global_list)
not_so_pure(some_global_list)
also_not_so_pure(some_global_list)

Function invocations are not connected in any way, but order matters

mutated_list = much_purer(some_global_list)
mutated_list = also_much_purer(mutated_list)
mutated_list = also_much_purer(much_purer(some_global_list))

Explicit connections between function calls

some_global_mess = []


def dirty_one():
    some_global_mess.append("lol")


def dirty_two():
    some_global_mess.append("kek")


dirty_one()
dirty_two()
print(some_global_mess)

Even more global variables

print()
random.random()
input()


def sum(a, b):
    print(f"I added {b} to {a}!")
    return a + b

Dirty functions

def sum(log: List[str], a: int, b: int) -> Tuple[int, List[str]]:
    return a + b, [*log, f"I added {b} to {a}!"]

We can lift side effects as far as possible

Pure functions

  • Predictable
  • Readable
  • Cacheable

Functions as first class objects

Functions are usual objects that can be saved in variable or passed as function argument

Higher order functions

Functions that take as argument or return other function

  • map
  • reduce
  • filter
  • sorted

deck

By Aleksandr Slepchenkov