Exploring the foundations of OOP and FP in PHP.
This presentation was held at MageTitans 2016 in Manchster.
It is the first time I've given this talk, I expect it to evolve over time.
Stories from
the Other Side
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Exploring OOP and
Functional 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 Schemer
Scala 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
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 about
classes or inheritance,
what is it about?
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
Quite similar to
related Functions
within 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 like
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
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
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 same
2. 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
→ Don't cause any side effects
→ Given the same arguments
always return the same result
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 effects
was one part.
What was the other?
MageTitans 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
→ 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 the
state of the world in one moment.
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
The state of the world in that
moment 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
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 recreated
with the current instance,
or the current instance has to be
passed as a method argument.
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
We can bundle state
and functions
without classes!
MageTitans Manchester, UK - #MageTitansMCR 2016-11-12 - twitter://@VinaiKopp
We can bundle state
and 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 have
Pure 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
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 our
OO 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 I
learned 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