16.1. OOP About

  • Three main programing paradigms

  • Programming paradigms

  • Procedural Programming (PP)

  • Functional Programming (FP)

  • Object Oriented Programming (OOP)

16.1.1. Procedural Programming

  • Languages: C, Pascal, Fortran, COBOL, BASIC, etc.

  • Share: 20% (don't quote me on that)

  • Since: 1950s

  • Vocabulary: variable, constant, reference, procedure, call, loop, iterate, switch, module, subprogram

  • Scaling: Vertical (buy faster computer)

  • Procedure is a set of commands which can be executed in order

  • Procedures == routines == subroutines

  • Function can return, procedures can't

  • Function has read only access to its parameters, and produce no side-effects

  • Procedure might have write access to its parameters, and are expected to produce side-effects

>>> def is_even(x):
...     if x % 2 == 0:
...         return True
...     else:
...         return False
>>>
>>> result = []
>>> for x in range(0,5):
...     if is_even(x):
...         result.append(x)
...
>>> print(result)
[0, 2, 4]

16.1.2. Functional Programming

  • Languages: OCaml, Haskel, Scheme, Lisp, Closure, etc.

  • Share: 5% (don't quote me on that)

  • Since: 1930s

  • Initiator: Alonso Church, lambda calculus, 1930s

  • Scaling: Horizontal (add more computers to the cluster)

  • Vocabulary: lambda, closure, curry, pure function, atom, bridge, monad, monoid, map, filter, reduce

  • No loops, use map, filter, recurrence

  • No variables, only constant values

For instance, a function sort might take a list, and return a new sorted list; whereas a procedure sort might take a list, and modify that list in-place without returning a new list.

>>> from functools import reduce
>>> from operator import add
>>>
>>>
>>> def even(x):
...     return x % 2 == 0
>>>
>>> def positive(x):
...     return x > 0
>>>
>>> def non_negative(x):
...     return x >= 0
>>>
>>> def square(x):
...     return x ** 2
>>>
>>> def increment(x):
...     return x + 1
>>>
>>> def decrement(x):
...     return x - 1
>>>
>>> def apply(data, fn):
...     return map(fn, data)
>>>
>>> filters = [
...     even,
...     positive,
...     non_negative,
... ]
>>>
>>> maps = [
...     square,
...     increment,
...     decrement,
... ]
>>>
>>> data = range(0, 1024)
>>> filtered = reduce(apply, filters, data)
>>> mapped = reduce(apply, maps, filtered)
>>> result = reduce(add, mapped)
>>>
>>> result
1024

16.1.3. Object Oriented Programming

  • Languages: Python, Java, JavaScript, C++, C#, Smalltalk, Swift

  • Share: 75% (don't quote me on that)

  • Since: 1970s

  • Vocabulary: class, instance, method, attribute, inheritance, subclass, superclass

  • Scaling: Vertical (buy faster computer)

>>> class User:
...     def __init__(self, firstname, lastname):
...         self.firstname = firstname
...         self.lastname = lastname
...         self._authenticated = False
...
...     def login(self, username, password):
...         if username == 'mwatney' and password == 'Ares3':
...             self._authenticated = True
...             print('User logged-in')
...         else:
...             raise PermissionError('Invalid username or password')
...
...     def logout(self):
...         self._authenticated = False
...         print('User logged-out')
...
...     def set_name(self, firstname, lastname):
...         if self._authenticated:
...             self.firstname = firstname
...             self.lastname = lastname
...             print('User name changed')
...         else:
...             raise PermissionError('User is not authenticated')
>>> user = User('Mark', 'Watney')
>>>
>>> vars(user)
{'firstname': 'Mark', 'lastname': 'Watney', '_authenticated': False}
>>> user.set_name('Melissa', 'Lewis')
Traceback (most recent call last):
PermissionError: User is not authenticated
>>> user.login('mwatney', 'Ares3')
User logged-in
>>>
>>> vars(user)
{'firstname': 'Mark', 'lastname': 'Watney', '_authenticated': True}
>>> user.set_name('Melissa', 'Lewis')
User name changed
>>>
>>> vars(user)
{'firstname': 'Melissa', 'lastname': 'Lewis', '_authenticated': True}
>>> user.logout()
User logged-out
>>>
>>> vars(user)
{'firstname': 'Melissa', 'lastname': 'Lewis', '_authenticated': False}