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}