Download - Stories from the other side
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Stories fromthe Other Side
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Exploring OOP andFunctional Programming(to become a better programmer)
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Why am I interested in this?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Smart guys go FP (lambdalicious, phunkie)The Little SchemerScala is the rage!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
What is this, OOP + FP?Where did these paradigms start?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
The term "Object Oriented Programming" was coined by Alan Kay
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Original image by Marcin Wichary - Thanks!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Amongst many other achievements,Alan Kay created Smalltalk
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
"OOP to me means only messaging,local retention and protection
and hiding of state-process, and extreme late-binding of all things"
It can be done in Smalltalk and in LISP."~ Alan Kay
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
"It can be done in Smalltalk and in LISP."
wait... WHAT?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
OOP in LISP?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
((lambda (f) (define pick (lambda (n lat) (cond ((zero? (sub1 n)) (car lat)) (else (pick (sub1 n) (cdr lat))))))
It's lists and recursion all the way down
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
How does OOP work with that?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
What is OOP?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Is it about inheritance?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
"OOP to me means only messaging,local retention and protection
and hiding of state-process, and extreme late-binding of all things"
~ Alan Kay
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Kay doesn't mention inheritance.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Is OOP about classes?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Kay doesn't mention classes either.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
If OOP is not aboutclasses or inheritance,
what is it about?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Lets start with
Messaging
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
I guess that means method calls.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
In class based OOP,the methods of a class define its
Interface.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Interface==
Related MethodsMageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Quite similar to
related Functionswithin a Namespace
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
So OOP is about grouping methods together?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
"... local retention and protection ..."~ Alan Kay
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Oh yeah, objects have states.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
What is a state?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
State in class based OOP:class Foo{ private static $class_state = 42;
private $instance_state = -0.2;}
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
State in RL is more likepublic function __construct(...){ $this->type = 'simple'; $this->customerSession = $customerSession; $this->scopeConfig = $scopeConfig; $this->counter = 0; $this->id = $_REQUEST['id']; $this->names = $db->getNames();}
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
What properties do these examples of state have?
public function __construct(...){ $this->type = 'simple'; $this->customerSession = $customerSession; $this->scopeConfig = $scopeConfig; $this->counter = 0; $this->id = $_REQUEST['id']; $this->names = $db->getNames();}
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
A literal $this->type = 'simple';
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
A shared object $this->customerSession = $customerSession;
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Literal zero(but looks like that might change)
$this->counter = 0;
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Global state $this->id = $_REQUEST['id'];
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Stuff from the DB $this->names = $db->getNames();
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Can we partition those examples?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
1. State that is always the same2. State that might change
(within the lifespan of the object)
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
State that might change: → Counter→ Session
→ Filesystem / DB / Internet→ Globals
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Non-changing state→ The Type ID
→ Application State→ Configuration
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
What can we do with this information?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Pure Functions!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Pure functions?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
→ Don't cause any side effects→ Given the same arguments
always return the same result
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
What areside effects?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
→ Changing state non-local to the function scope
→ DB or Filesystem or Network access→ Throwing Exceptions
→ Forking
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
No side effectswas one part.
What was the other?MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Same Arguments==>
Same ResultMageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
A function that always returns the same result given the same arguments is called
Referentially Transparent
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Referentially Transparent Functions
must not use state that might change!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Why should we care?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Benefitsof Pure Functions!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
→ Easier to think about(reasonability)
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
→ Easier to break apart(decomposability)
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
→ Easier to combine(composability & reuseability)
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
→ Easier to show correctness(testability)
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
→ Easier to parallelize(threadability ;))
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Mkay.
But what about the changing things?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
How can we deal with changing state?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We treat objects as snapshots of thestate of the world in one moment.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
The state of the world in thatmoment will never change.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
If change occurs, it means now is a different moment in time.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We can represent change in two ways:→ by modifying the object
→ by creating a new instance
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
ImmutabilityMageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
For example, what happens when an admin logs in?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
$loggedInAdmin = $loggedOutAdmin->login();
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
public function login(){ return new self($isLoggedIn = true);}
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
But what if a method needs the
"current instance"?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Either that object has to be recreatedwith the current instance,
or the current instance has to bepassed as a method argument.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
OOP style$authorizationManager->hasAccess($dashboard, $loggedInAdmin);
$authorizationManager->hasAccess($dashboard, $loggedOutAdmin);
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
In FP$has_access($dashboard, $loggedInAdmin);
$has_access($dashboard, $loggedOutAdmin);
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
There are more parameters in RL!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Okay, lets reduce the argument count by adding properties to the object.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
$dashboardAuthorizationManager =
new class($authorizationManager, $dashboard) {
private $authorizationManager; private $page;
public function __construct($authorizationManager, $page) { $this->authorizationManager = $authorizationManager; $this->page = $page; }
public function hasAccess($admin) { return $this->authorizationManager ->hasAccess($this->page, $admin); }}
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Only one argument left:$pageAuthorizationManager->hasAccess($loggedInAdmin);
$pageAuthorizationManager->hasAccess($loggedOutAdmin);
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
How might that look like in FP?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
$has_access_to_dashboard =
function ($admin) use ($dashboard, $has_access) { return $has_access($dashboard, $admin); }
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
$has_access_to_dashboard($loggedInAdmin);
$has_access_to_dashboard($loggedOutAdmin);
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Can we remove all arguments?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
$loggedInAdminDashboardAuthorization =
new class($dashboardAuthorizationManager, $loggedInAdmin){ private $pageAuthorizationManager; private $admin;
public function __construct($pageAuthorizationManager, $admin) { $this->pageAuthorizationManager = $pageAuthorizationManager; $this->admin = $admin; }
public function hasAccess() { return $this->pageAuthorizationManager ->hasAccess($this->admin); }}
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
In FP:$has_logged_in_admin_access_to_dashboard =
function () use ($has_access_to_dashboard, $admin) { return $has_access_to_dashboard($admin); }
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We can bundle stateand functions
without classes!MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We can bundle stateand process
without classes!MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Look Ma,OOP in PHP without
hands classes!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We have the choice:→ pass state with method arguments→ set state as object properties
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
The more volatile the object state,the more often we need to
create new instances...
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
...if we want to havePure Functions.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Lesson from FP:Distinguish between mutable and
immutable object properties.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
"Mutable stateful objects are the new spaghetti code"
~ Rich Hickey
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
SummaryMageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Concepts from the FP languages can be useful in OO PHP.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We can benefit from designing ourOO code so it exhibits the properties of
pure functions.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We barely scratched the surface.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Don't be afraid of FP's mathematical pattern names. It's still just code.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Building these slides Ilearned something about OOP.
I hope you found it interesting, too!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
(if (has-communication? you vinai) (communicate you vinai) (enjoy you remaining-agenda))
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp