SlideShare ist ein Scribd-Unternehmen logo
1 von 141
Downloaden Sie, um offline zu lesen
Witek Adamus
DocPlanner 2017, Warszawa
Why async
and
functional
programming
in PHP7 suck
and how to
get over it?
Who am I?
5 years of
imperative
programming
2 years of
functional
programming
Back to
PHP7
❏ WHY?
❏ What can functional programming bring to the table?
❏ WHAT?
❏ When language can be described as functional?
❏ PROBLEMS?
❏ Top sins of PHP
❏ SOLUTION?
Table of content
WHY?
❏ Higher quality?
❏ Speed / Scalability
❏ Less bugs
❏ Easy to reason about
❏ Predictability
WHY?
WHY?
Pros Cons
Efficiency ???
Entry threshold ???
Mathematical
description of
reality
???
WHY?
Pros Cons In result
Efficiency Efficiency Scalability / Quality
Entry threshold Entry threshold Let’s get the party
started
Mathematical
description of
reality
Mathematical
description of
reality
Shorter and more
descriptive code
WHY?
Pros Cons In result
Efficiency Efficiency Scalability / Quality
Entry threshold Entry threshold Let’s get the party
started
Mathematical
description of
reality
Mathematical
description of
reality
Shorter and more
descriptive code
INVEST AND WAIT
FOR A DIVIDEND
public function someMethodWithMisleadingName(
array $mysteriousInput){
$arr = [];
foreach ($mysteriousInput as $inp) {
if ($inp > 10) { $arr[] = $inp; }
}
$arrLeft = $arrRight = $arrCenter = [];
foreach ($arr as $elem) {
$bucket = $elem <=> 20;
if ($bucket < 0) { $arrLeft[] = $elem; }
if ($bucket == 0) { $arrCenter[] = $elem; }
if ($bucket > 0) { $arrRight[] = $elem;}
}
$countLeft = count($arrLeft);
$countCenter = count($arrCenter);
$countRight = count($arrRight);
return array_sum([$countLeft, $countCenter, $countRight]) / 3;
}
public function someMethodWithMisleadingName(
array $mysteriousInput) {
$arr = [];
foreach ($mysteriousInput as $inp) {
if ($inp > 10) { $arr[] = $inp; }
}
$arrLeft = $arrRight = $arrCenter = [];
foreach ($arr as $elem) {
$bucket = $elem <=> 20;
if ($bucket < 0) { $arrLeft[] = $elem; }
if ($bucket == 0) { $arrCenter[] = $elem; }
if ($bucket > 0) { $arrRight[] = $elem;}
}
$countLeft = count($arrLeft);
$countCenter = count($arrCenter);
$countRight = count($arrRight);
return array_sum(
[$countLeft, $countCenter, $countRight]
) / 3;
}
public function
someMethodWithMisleadingName(
ParallelListCollection $mysteriousInput) {
return $mysteriousInput
->filter(function ($elem) {
return $elem > 10;
})
->partition(function ($elem) {
return $elem <=> 20;
})
->map(function ($bucket) {
return $bucket->count();
})
->avg();
}
public function someMethodWithMisleadingName(
array $mysteriousInput) {
$arr = [];
foreach ($mysteriousInput as $inp) {
if ($inp > 10) { $arr[] = $inp; }
}
$arrLeft = $arrRight = $arrCenter = [];
foreach ($arr as $elem) {
$bucket = $elem <=> 20;
if ($bucket < 0) { $arrLeft[] = $elem; }
if ($bucket == 0) { $arrCenter[] = $elem; }
if ($bucket > 0) { $arrRight[] = $elem;}
}
$countLeft = count($arrLeft);
$countCenter = count($arrCenter);
$countRight = count($arrRight);
return array_sum(
[$countLeft, $countCenter, $countRight]
) / 3;
}
public function
someMethodWithMisleadingName(
ParallelListCollection $mysteriousInput) {
return $mysteriousInput
->filter(function ($elem) {
return $elem > 10;
})
->partition(function ($elem) {
return $elem <=> 20;
})
->map(function ($bucket) {
return $bucket->count();
})
->avg();
}
WHAT?
❏ Function is a first-class citizen
❏ Lambda Calculus
❏ Immutability
❏ No side effects
First-class citizen
❏ Can be stored in variable and data structures
❏ Can be passed as a parameter to procedure/functions
❏ Can be returned by procedures/functions
❏ Can be instantiated inline
❏ Has it’s own identity (name independent)
Lambda Calculus
ƛ(x) = z
Lambda Calculus
ƛ(x) = z
❏ Higher-order functions
❏ Currying
Lambda Calculus
ƛ(x) = z
❏ Higher-order functions
❏ Currying
SWITCH YOUR THINKING
FROM “HOW?” TO “WHAT?”
No side effects? Immutability?
:(
Functional vs Object oriented programming
?
PHP7 is functional

but is dirty and salty as well
What do I miss in PHP7 that Scala
luckily has?
❏ Immutability by default
❏ Objects cloning
❏ Options
❏ Either
❏ Future
❏ Parallel collections
❏ Tail recurrency
❏ Generic types
❏ Arrow functions
❏ Pattern matching / case classes
https://github.com/php-slang/php-slang
http://phpslang.io
# composer require php-slang/php-slang
Few rules to
make your
code
functional
Do not use
❏ reassignments
❏ if
❏ null
❏ for
❏ foreach
Quick pool
❏ Do you DDD?
Quick pool
❏ Do you DDD?
❏ Do you use setters?
Quick pool
❏ Do you DDD?
❏ Do you use setters?
“VALUE OBJECTS are completely immutable.”
Eric Evans
Do not use
❏ reassignments
$bigHouse = new Building(5);
$bigHouse = new Building(5);
$smallerHouse = $bigHouse->setFloors(2);
echo $bigHouse->getFloors();
echo $smallerHouse->getFloors();
$bigHouse = new Building(5);
$smallerHouse = $bigHouse->setFloors(2);
echo $bigHouse->getFloors(); //2
echo $smallerHouse->getFloors(); //2
class Building
{
protected $floors;
public function __construct(int $floors)
{
$this->setFloors($floors);
}
public function getFloors() : int
{
return $this->floors;
}
public function setFloors(int $floors) : Building
{
$this->floors = $floors;
return $this;
}
}
use PhpSlangUtilCopy;
class Building
{
use Copy;
protected $floors;
public function __construct(int $floors)
{
$this->floors = $floors;
}
public function getFloors() : int
{
return $this->floors;
}
public function withFloors(int $floors) : Building
{
return $this->copy('floors', $floors);
}
}
$bigHouse = new Building(5);
$smallerHouse = $bigHouse->withFloors(2);
echo $bigHouse->getFloors(); //5
echo $smallerHouse->getFloors(); //2
$bigHouse = new Building(5);
$smallerHouse = $bigHouse->withFloors(2);
echo $bigHouse->getFloors(); //5
echo $smallerHouse->getFloors(); //2
REFERENTIALTRANSPARENCY
Referential transparency
❏ f(x, y) = (x+y) * y
Referential transparency
❏ f(x, y) = (x+y) * y
x, y and a result can
be a function as well
Referential transparency
❏ f(x, y) = (x+y) * y
Eg.
❏ f(2, 4) = (2 + 4) * 4 = 8 * 4 = 32
❏ f(1, 8) = (1 + 8) * 8 = 9 * 8 = 72
Referential transparency
❏ f(x, y) = (x+y) * y
Eg.
❏ f(2, 4) = (2 + 4) * 4 = 8 * 4 = 32
❏ f(1, 8) = (1 + 8) * 8 = 9 * 8 = 72
i = 71;
ComputingService::_opCount++;
comps.push(new Tuple2(x, y));
Referential transparency
❏ f(x, y) = (x+y) * y
Eg.
❏ f(2, 4) = (2 + 4) * 4 = 8 * 4 = 32
❏ f(1, 8) = (1 + 8) * 8 = 9 * 8 = 72
i = 71;
ComputingService::_opCount++;
comps.push(new Tuple2(x, y));
Few rules to
make your
code
functional
Do not use
:) reassignments
❏ if
❏ null
❏ for
❏ foreach
Do not use
:) reassignments
❏ if
❏ null
❏ for
❏ foreach
?
Do not use
:) reassignments
❏ if
❏ null
❏ for
❏ foreach
Option
Option
Monad which may contain something or nothing
What is a monad?
What is a monad?
What is a monad?
What is a monad?
What is a monad?
map
What is a monad?
flatMap
What is a monad?
Option
Option
NoneSome
Option
Option
NoneSome
map(Closure $expression)
getOrElse($default)
map(Closure $expression)
getOrElse($default)
Option
Option
NoneSome
map(Closure $expression)
getOrElse($default)
map(Closure $expression)
getOrElse($default)
Some($expression($this->content)
$this->content
Option
Option
NoneSome
map(Closure $expression)
getOrElse($default)
map(Closure $expression)
getOrElse($default)
None
$default
public function findByEmail(string $email) : User
{
$user = $this->findOneBy(['email' => $email]);
if (!$user instanceof User) {
throw new NotFoundException("oh my");
}
return $user;
}
try {
return new Response(findByEmail($email), HTTP_OK);
} catch (NotFoundException $exception) {
return new Response([], HTTP_NOT_FOUND);
}
public function findByEmail(string $email) : User
{
$user = $this->findOneBy(['email' => $email]);
if (!$user instanceof User) {
throw new NotFoundException("oh my");
}
return $user;
}
try {
return new Response(findByEmail($email), HTTP_OK);
} catch (NotFoundException $exception) {
return new Response([], HTTP_NOT_FOUND);
}
public function findByEmail(string $email) : Option
{
return Option::of($this->findOneBy(['email' => $email]));
}
return findByEmail($email))
->map(function (User $user) {
return new Response($user, HTTP_OK);
})
->getOrElse(new Response('', HTTP_NOT_FOUND));
public function findByEmail(string $email) : User
{
$user = $this->findOneBy(['email' => $email]);
if (!$user instanceof User) {
throw new NotFoundException("oh my");
}
return $user;
}
try {
return new Response(findByEmail($email), HTTP_OK);
} catch (NotFoundException $exception) {
return new Response([], HTTP_NOT_FOUND);
}
public function findByEmail(string $email) : Option
{
return Option::of($this->findOneBy(['email' => $email]));
}
return findByEmail($email))
->map(function (User $user) {
return new Response($user, HTTP_OK);
})
->getOrElse(new Response('', HTTP_NOT_FOUND));
map
Option
How about nesting
public function findByEmail(string $email) : Option
{
return Option::of($this->findOneBy(['email' => $email]));
}
public function postalCode(string $email, PostalCode $default) : PostalCode
{
return findByEmail($email)
->map(function (User $user) {
return $user->getProfile()->getAdress()->getPostalCode();
})
->getOrElse($default);
}
public function postalCode(string $email, PostalCode $default) : PostalCode
{
return findByEmail($email);
->map(function (User $user) {
return $user->getProfile()->getAdress()->getPostalCode();
})
->getOrElse($default);
}
public function postalCode(string $email, PostalCode $default) : PostalCode
{
return findByEmail($email)
->flatMap(function (User $user) {
return $user->getProfile();
})
->flatMap(function (UserProfile $userProfile) {
return $userProfile->getAdress();
})
->flatMap(function (Adress $adress) {
return $adress->getPostalCode();
})
->getOrElse($default);
}
public function postalCode(string $email, PostalCode $default) : PostalCode
{
return findByEmail($email)
->flatMap(function (User $user) {
return $user->getProfile();
})
->flatMap(function (UserProfile $userProfile) {
return $userProfile->getAdress();
})
->flatMap(function (Adress $adress) {
return $adress->getPostalCode();
})
->getOrElse($default);
}
flatMap
Few rules to
make your
code
functional
Do not use
:) reassignments
:) if
:) null
❏ for
❏ foreach
Shortened notation for
anonymous functions
public function displayNameForUser(string $email) : string
{
return $this
->userRepository
->findByEmail($email)
->flatMap(function (User $user) {
return $user->getFirstName();
})
->getOrCall(function () use (string $email) : string {
return $this->getSomethingElseWith($email);
});
}
public function displayNameForUser(string $email) : string
{
return $this
->userRepository
->findByEmail($email)
->flatMap(function (User $user) {
return $user->getFirstName();
})
->getOrCall(function () use (string $email) : string {
return $this->getSomethingElseWith($email);
});
}
public displayNameForUser(string email) : string
userRepository
->findByEmail(email)
->flatMap(_->getFirstName)
->getOrCall(getSomethingElseWith(email))
:(
public def displayNameForUser(email : string) : string =
userRepository
.findByEmail(email)
.flatMap(_.getFirstName)
.getOrElse(_ => getSomethingElseWith(email))
:)
public function displayNameForUser(string $email) : string
{
return $this
->userRepository
->findByEmail($email)
->flatMap(Extract($user)->getFirstName())
->getOrCall(Extract($this)->getSomethingElseWith($email));
}
NYI
:)
Generic types
public function maybeSomething(string $email) : Option
{
...
}
/**
* @return Option<string>
*/
public function maybeSomething(string $email) : Option
{
...
}
https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md
:(
public function maybeSomething(string $email) : Option<string>
{
...
}
:o
public function maybeSomething(string $email) : Option<string>
{
...
}
❏ Version: 0.4.0
❏ Date: 2016-01-06
❏ Author:
❏ Ben Scholzen 'DASPRiD' mail@dasprids.de,
❏ Rasmus Schultz rasmus@mindplay.dk
❏ Status: Draft
❏ First Published at: http://wiki.php.net/rfc/generics
:(
public function maybeSomething(string $email) : Option<string>
{
...
}
WANT TO EARN EXTRA $1020 ?
https://www.bountysource.com/issues/20553561-add-generics-support
:~|
Syntax doesn’t matter
thinking does
Erlang guys
What do I miss in PHP7 that Scala
luckily has?
:/ Immutability by default
:) Objects cloning
:) Options
❏ Either
❏ Future
❏ Parallel collections
❏ Tail recurrency
:( Generic types
:( Arrow functions
❏ Pattern matching / case classes
Either
Either
Either
RightLeft
Either
Either
RightLeft
left(Closure $expr): Either
right(Closure $expr): Either
get()
left(Closure $expr): Either
right(Closure $expr): Either
get()
Either
Either
RightLeft
left(Closure $expr): Either
right(Closure $expr): Either
get()
left(Closure $expr): Either
right(Closure $expr): Either
get()
SEMANTICS!
What do I miss in PHP7 that Scala
luckily has?
:/ Immutability by default
:) Objects cloning
:) Options
:) Either
❏ Future
❏ Parallel collections
❏ Tail recurrency
:( Generic types
:( Arrow functions
❏ Pattern matching / case classes
Pattern Matching
Pattern matching
Result
Variant 1
Variant 2
Variant 3
Variant N
...
return (Match::of($someKindResult))
->match(
new Case(IvalidInput::class, new Response('', HTTP_BAD_REQUEST)),
new Case(NotFound::class, new Response('',HTTP_NOT_FOUND),
new Default(function () use ($someKindResult) {
return new Response($someKindResult, HTTP_OK);
})
);
What do I miss in PHP7 that Scala
luckily has?
:/ Immutability by default
:) Objects cloning
:) Options
:) Either
❏ Future
❏ Parallel collections
❏ Tail recurrency
:( Generic types
:( Arrow functions
:)/:( Pattern matching / case classes
Parallel collections
Parallel collections
Collection
N...3210
public function beautifulMultiplyOddsBy(
array $input, float $multiplication) : ListCollection
{
return (new ListCollection($input))
->filter(function ($number) {
return $number % 2 !== 0;
})
->map(function ($number) use ($multiplication) {
return $number * $multiplication;
});
}
public function accumulatedText(array $words) : string {
$text = '';
foreach ($words as $word) {
$text .= $word . ' ';
}
return $text;
}
public function accumulatedText(array $words) : string {
return (new ListCollection($words))
->fold('', function (string $acumulator, string $word) {
return $acumulator . $word . ' ';
});
}
(new ListCollection([1,2,3,4]))->tail(); //ListCollection([2,3,4])
(new ListCollection([1,2,3,4]))->every(2); //ListCollection([2,4])
(new ListCollection([1,2,3,4]))->groups(2);
ListCollection([
ListCollection([1,2]),
ListCollection([3,4]),
])
Few rules to
make your
code
functional
Do not use
:) reassignments
:) if
:) null
:) for
:) foreach
Parallelism vs Concurrency
Future
public function nonBlockingGet(string $id): Future
{
...
}
public function exampleAction(string $id1) : Response
{
return $this
->nonBlockingService
->nonBlockingGet($id)
->map(function (NonBlockingGetResult $output) {
return new Response($output);
})
->await();
}
public function nonBlockingGet(string $id): Future
{
...
}
public function exampleAction(string $id1) : Response
{
return $this
->nonBlockingService
->nonBlockingGet($id)
->map(function (NonBlockingGetResult $output) {
return new Response($output);
})
->await();
}
Future<NonBlockingGetResult>
NYI
public function nonBlockingGet(string $id): Future
{
...
}
public function exampleAction(string $id1) : Response
{
return $this
->nonBlockingService
->nonBlockingGet($id)
->map(function (NonBlockingGetResult $output) {
return new Response($output);
})
->await();
}
Future<NonBlockingGetResult>
NYI
Future<Response>
public function nonBlockingGet(string $id): Future
{
...
}
public function exampleAction(string $id1) : Response
{
return $this
->nonBlockingService
->nonBlockingGet($id)
->map(function (NonBlockingGetResult $output) {
return new Response($output);
})
->await();
}
Future<NonBlockingGetResult>
NYI
Future<Response>
Response
public function nonBlockingGet(string $id): Future
{
...
}
public function exampleAction(string $id1, string $id2, string $id3) : Response
{
return Future::all([
$this->nonBlockingService1->nonBlockingGet($id1),
$this->nonBlockingService2->nonBlockingGet($id2),
$this->nonBlockingService3->nonBlockingGet($id3),
])
->map(function ($output) {
return new Response($output);
})
->await();
}
NYI
Future & Parallel collections
use PhpSlangCollectionListCollection;
...
public function beautifulMultiplyBy(array $input, float $multiplication) : ListCollection
{
return (new ListCollection($input))
->map(function ($number) use ($multiplication) {
return $number * $multiplication;
});
}
use PhpSlangCollectionParallelListCollection;
...
public function beautifulMultiplyBy(array $input, float $multiplication) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map(function ($number) use ($multiplication) {
return $number * $multiplication;
});
}
use PhpSlangCollectionListCollection;
...
public function asyncChainedComputationExample(array $input) : ListCollection
{
return (new ListCollection($input))
->map($this->transformationOne());
}
use PhpSlangCollectionParallelListCollection;
...
public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map($this->transformationOne());
}
use PhpSlangCollectionListCollection;
...
public function asyncChainedComputationExample(array $input) : ListCollection
{
return (new ListCollection($input))
->map($this->transformationOne());
}
use PhpSlangCollectionParallelListCollection;
...
public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map($this->transformationOne());
}
use PhpSlangCollectionParallelListCollection;
...
public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map($this->transformationOne());
}
CPU vs IO
use PhpSlangCollectionParallelListCollection;
...
public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree();
}
use PhpSlangCollectionParallelListCollection;
...
public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map(function ($number) {
return new Some($number)
->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree()
->get();
});
}
use PhpSlangCollectionParallelListCollection;


public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map(function ($number) {
return new Some($number)
->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree()
->get();
});
}
What do I miss in PHP7 that Scala
luckily has?
:/ Immutability by default
:) Objects cloning
:) Options
:) Either
:/ Future
:) Parallel collections
❏ Tail recurrency
:( Generic types
:( Arrow functions
:)/:( Pattern matching / case classes
Tail recurrency
def fibonacci(index : Int) : Int =
index match {
case 0 | 1 => index
case _ => fibonacci(index - 1 ) + fibonacci(index - 2)
}
function fibonacci(int $index) : int
{
return in_array($index, [0, 1])
? $index
: fibonacci($index - 1) + fibonacci($index - 2);
}
def fibonacci(index : Int) : Int =
index match {
case 0 | 1 => index
case _ => fibonacci(index - 1 ) + fibonacci(index - 2)
}
function fibonacci(int $index) : int
{
return in_array($index, [0, 1])
? $index
: fibonacci($index - 1) + fibonacci($index - 2);
}
echo fibonacci(123123123123);
Fatal error: Maximum function nesting level of '...' reached, aborting!
ini_set('xdebug.max_nesting_level', 9999999);
?
def fibonacci(index: Int): Int = {
var a = 0
var b = 1
var i = 0
while (i < index) {
val c = a + b
a = b
b = c
i = i + 1
}
return a
}
function fibonacci(int $index) : int
{
$a = 0;
$b = 1;
$i = 0;
while ($i < $index) {
$c = $a + $b;
$a = $b;
$b = $c;
$i += 1;
}
return $a;
}
def recursiveFibonacci(n: Int, a:Int, b:Int): Int =
n match {
case 0 => a
case _ => recursiveFibonacci( n-1, b, a+b )
}
def fibonacci( n : Int) : Int =
recursiveFibonacci( n, 0, 1)
function recursiveFibonacci(int $n, int $a, int $b) {
return ($n == 0)
? $a
: recursiveFibonacci($n - 1, $b, $a + $b);
}
function fibonacci(int $n) : int
{
return recursiveFibonacci($n, 0, 1);
}
def fibonacci(index : Int) : Int =
index match {
case 0 | 1 => index
case _ => fibonacci(index - 1 ) + fibonacci(index - 2)
}
function fibonacci(int $index) : int
{
return in_array($index, [0, 1])
? $index
: fibonacci($index - 1) + fibonacci($index - 2);
}
@tailrec
def recursiveFibonacci(n: Int, a:Int, b:Int): Int =
n match {
case 0 => a
case _ => recursiveFibonacci( n-1, b, a+b )
}
def fibonacci( n : Int) : Int =
recursiveFibonacci( n, 0, 1)
function recursiveFibonacci(int $n, int $a, int $b) {
return ($n == 0)
? $a
: recursiveFibonacci($n - 1, $b, $a + $b);
}
function fibonacci(int $n) : int
{
return recursiveFibonacci($n, 0, 1);
}
:(
:)
Tail recurrency
Trampolines
Recurrency
Recurrency Trampoline
function recursiveFibonacci(int $n, int $a, int $b) {
return ($n == 0)
? $a
: recursiveFibonacci($n - 1, $b, $a + $b);
}
function fibonacci($n)
{
return recursiveFibonacci($n, 0, 1);
}
function recursiveFibonacci(int $n, int $a, int $b) {
return ($n == 0)
? new Done($a)
: new Bounce(function () use ($n, $b, $a) {
return recursiveFibonacci($n - 1, $b, $a + $b);
});
}
function fibonacci($n)
{
return (new Trampoline(function () use ($n) {
return recursiveFibonacci($n, 0, 1);
}))->run();
}
Recurrency Trampoline
What do I miss in PHP7 that Scala
luckily has?
:/ Immutability by default
:) Objects cloning
:) Options
:) Either
:/ Future
:) Parallel collections
:) Tail recurrency
:( Generic types
:( Arrow functions
:)/:( Pattern matching / case classes
Conclusions
● Don’t be afraid of monads
● Care about transparency (especially referential)
● Learn Haskell, Clojure, Scala, F#, JavaScript -> TypeScript
Witek Adamus
witold.adamus@xsolve.pl
http://phpslang.io

Weitere Àhnliche Inhalte

Was ist angesagt?

Hive function-cheat-sheet
Hive function-cheat-sheetHive function-cheat-sheet
Hive function-cheat-sheetDr. Volkan OBAN
 
R Language Introduction
R Language IntroductionR Language Introduction
R Language IntroductionKhaled Al-Shamaa
 
Data transformation-cheatsheet
Data transformation-cheatsheetData transformation-cheatsheet
Data transformation-cheatsheetDieudonne Nahigombeye
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance HaskellJohan Tibell
 
Data Analysis and Programming in R
Data Analysis and Programming in RData Analysis and Programming in R
Data Analysis and Programming in REshwar Sai
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsKirill Kozlov
 
Map, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftAleksandras Smirnovas
 
Data Structures In Scala
Data Structures In ScalaData Structures In Scala
Data Structures In ScalaKnoldus Inc.
 
Data Analysis with R (combined slides)
Data Analysis with R (combined slides)Data Analysis with R (combined slides)
Data Analysis with R (combined slides)Guy Lebanon
 
R programming intro with examples
R programming intro with examplesR programming intro with examples
R programming intro with examplesDennis
 
R programming language
R programming languageR programming language
R programming languageAlberto Minetti
 
Introduction to R Programming
Introduction to R ProgrammingIntroduction to R Programming
Introduction to R Programmingizahn
 
Programming in R
Programming in RProgramming in R
Programming in RSmruti Sarangi
 
Introduction to pandas
Introduction to pandasIntroduction to pandas
Introduction to pandasPiyush rai
 

Was ist angesagt? (20)

Hive function-cheat-sheet
Hive function-cheat-sheetHive function-cheat-sheet
Hive function-cheat-sheet
 
R Language Introduction
R Language IntroductionR Language Introduction
R Language Introduction
 
R Refcard
R RefcardR Refcard
R Refcard
 
Data transformation-cheatsheet
Data transformation-cheatsheetData transformation-cheatsheet
Data transformation-cheatsheet
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance Haskell
 
Data Analysis and Programming in R
Data Analysis and Programming in RData Analysis and Programming in R
Data Analysis and Programming in R
 
Python programming : Standard Input and Output
Python programming : Standard Input and OutputPython programming : Standard Input and Output
Python programming : Standard Input and Output
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. Monads
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
 
Map, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in Swift
 
Data Structures In Scala
Data Structures In ScalaData Structures In Scala
Data Structures In Scala
 
Data Analysis with R (combined slides)
Data Analysis with R (combined slides)Data Analysis with R (combined slides)
Data Analysis with R (combined slides)
 
R programming intro with examples
R programming intro with examplesR programming intro with examples
R programming intro with examples
 
R programming language
R programming languageR programming language
R programming language
 
Introduction to R Programming
Introduction to R ProgrammingIntroduction to R Programming
Introduction to R Programming
 
R language
R languageR language
R language
 
Programming in R
Programming in RProgramming in R
Programming in R
 
Python crush course
Python crush coursePython crush course
Python crush course
 
Introduction to pandas
Introduction to pandasIntroduction to pandas
Introduction to pandas
 
Data import-cheatsheet
Data import-cheatsheetData import-cheatsheet
Data import-cheatsheet
 

Ähnlich wie Why async and functional programming in PHP7 suck and how to get overr it?

PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developersStoyan Stefanov
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrowPete McFarlane
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareKuan Yen Heng
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
Writing Maintainable Perl
Writing Maintainable PerlWriting Maintainable Perl
Writing Maintainable Perltinypigdotcom
 
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...James Titcumb
 
Smelling your code
Smelling your codeSmelling your code
Smelling your codeRaju Mazumder
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with YieldJason Myers
 

Ähnlich wie Why async and functional programming in PHP7 suck and how to get overr it? (20)

PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrow
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Functional php
Functional phpFunctional php
Functional php
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Writing Maintainable Perl
Writing Maintainable PerlWriting Maintainable Perl
Writing Maintainable Perl
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
 
Smelling your code
Smelling your codeSmelling your code
Smelling your code
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with Yield
 

KĂŒrzlich hochgeladen

UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)
UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)
UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)Dr SOUNDIRARAJ N
 
Introduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptxIntroduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptxk795866
 
Vishratwadi & Ghorpadi Bridge Tender documents
Vishratwadi & Ghorpadi Bridge Tender documentsVishratwadi & Ghorpadi Bridge Tender documents
Vishratwadi & Ghorpadi Bridge Tender documentsSachinPawar510423
 
System Simulation and Modelling with types and Event Scheduling
System Simulation and Modelling with types and Event SchedulingSystem Simulation and Modelling with types and Event Scheduling
System Simulation and Modelling with types and Event SchedulingBootNeck1
 
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONTHE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONjhunlian
 
National Level Hackathon Participation Certificate.pdf
National Level Hackathon Participation Certificate.pdfNational Level Hackathon Participation Certificate.pdf
National Level Hackathon Participation Certificate.pdfRajuKanojiya4
 
Industrial Safety Unit-I SAFETY TERMINOLOGIES
Industrial Safety Unit-I SAFETY TERMINOLOGIESIndustrial Safety Unit-I SAFETY TERMINOLOGIES
Industrial Safety Unit-I SAFETY TERMINOLOGIESNarmatha D
 
Unit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfg
Unit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfgUnit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfg
Unit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfgsaravananr517913
 
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdfCCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdfAsst.prof M.Gokilavani
 
Risk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfRisk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfROCENODodongVILLACER
 
Research Methodology for Engineering pdf
Research Methodology for Engineering pdfResearch Methodology for Engineering pdf
Research Methodology for Engineering pdfCaalaaAbdulkerim
 
Earthing details of Electrical Substation
Earthing details of Electrical SubstationEarthing details of Electrical Substation
Earthing details of Electrical Substationstephanwindworld
 
Instrumentation, measurement and control of bio process parameters ( Temperat...
Instrumentation, measurement and control of bio process parameters ( Temperat...Instrumentation, measurement and control of bio process parameters ( Temperat...
Instrumentation, measurement and control of bio process parameters ( Temperat...121011101441
 
Arduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.pptArduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.pptSAURABHKUMAR892774
 
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncWhy does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncssuser2ae721
 
Internet of things -Arshdeep Bahga .pptx
Internet of things -Arshdeep Bahga .pptxInternet of things -Arshdeep Bahga .pptx
Internet of things -Arshdeep Bahga .pptxVelmuruganTECE
 
welding defects observed during the welding
welding defects observed during the weldingwelding defects observed during the welding
welding defects observed during the weldingMuhammadUzairLiaqat
 

KĂŒrzlich hochgeladen (20)

UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)
UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)
UNIT III ANALOG ELECTRONICS (BASIC ELECTRONICS)
 
Introduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptxIntroduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptx
 
Vishratwadi & Ghorpadi Bridge Tender documents
Vishratwadi & Ghorpadi Bridge Tender documentsVishratwadi & Ghorpadi Bridge Tender documents
Vishratwadi & Ghorpadi Bridge Tender documents
 
System Simulation and Modelling with types and Event Scheduling
System Simulation and Modelling with types and Event SchedulingSystem Simulation and Modelling with types and Event Scheduling
System Simulation and Modelling with types and Event Scheduling
 
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
 
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONTHE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
 
National Level Hackathon Participation Certificate.pdf
National Level Hackathon Participation Certificate.pdfNational Level Hackathon Participation Certificate.pdf
National Level Hackathon Participation Certificate.pdf
 
Industrial Safety Unit-I SAFETY TERMINOLOGIES
Industrial Safety Unit-I SAFETY TERMINOLOGIESIndustrial Safety Unit-I SAFETY TERMINOLOGIES
Industrial Safety Unit-I SAFETY TERMINOLOGIES
 
Unit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfg
Unit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfgUnit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfg
Unit7-DC_Motors nkkjnsdkfnfcdfknfdgfggfg
 
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdfCCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
 
Risk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfRisk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdf
 
Research Methodology for Engineering pdf
Research Methodology for Engineering pdfResearch Methodology for Engineering pdf
Research Methodology for Engineering pdf
 
young call girls in Green Park🔝 9953056974 🔝 escort Service
young call girls in Green Park🔝 9953056974 🔝 escort Serviceyoung call girls in Green Park🔝 9953056974 🔝 escort Service
young call girls in Green Park🔝 9953056974 🔝 escort Service
 
Earthing details of Electrical Substation
Earthing details of Electrical SubstationEarthing details of Electrical Substation
Earthing details of Electrical Substation
 
Instrumentation, measurement and control of bio process parameters ( Temperat...
Instrumentation, measurement and control of bio process parameters ( Temperat...Instrumentation, measurement and control of bio process parameters ( Temperat...
Instrumentation, measurement and control of bio process parameters ( Temperat...
 
Arduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.pptArduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.ppt
 
POWER SYSTEMS-1 Complete notes examples
POWER SYSTEMS-1 Complete notes  examplesPOWER SYSTEMS-1 Complete notes  examples
POWER SYSTEMS-1 Complete notes examples
 
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncWhy does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
 
Internet of things -Arshdeep Bahga .pptx
Internet of things -Arshdeep Bahga .pptxInternet of things -Arshdeep Bahga .pptx
Internet of things -Arshdeep Bahga .pptx
 
welding defects observed during the welding
welding defects observed during the weldingwelding defects observed during the welding
welding defects observed during the welding
 

Why async and functional programming in PHP7 suck and how to get overr it?

  • 2. Why async and functional programming in PHP7 suck and how to get over it?
  • 4. 5 years of imperative programming 2 years of functional programming Back to PHP7
  • 5. ❏ WHY? ❏ What can functional programming bring to the table? ❏ WHAT? ❏ When language can be described as functional? ❏ PROBLEMS? ❏ Top sins of PHP ❏ SOLUTION? Table of content
  • 7. ❏ Higher quality? ❏ Speed / Scalability ❏ Less bugs ❏ Easy to reason about ❏ Predictability WHY?
  • 8. WHY? Pros Cons Efficiency ??? Entry threshold ??? Mathematical description of reality ???
  • 9. WHY? Pros Cons In result Efficiency Efficiency Scalability / Quality Entry threshold Entry threshold Let’s get the party started Mathematical description of reality Mathematical description of reality Shorter and more descriptive code
  • 10. WHY? Pros Cons In result Efficiency Efficiency Scalability / Quality Entry threshold Entry threshold Let’s get the party started Mathematical description of reality Mathematical description of reality Shorter and more descriptive code INVEST AND WAIT FOR A DIVIDEND
  • 11. public function someMethodWithMisleadingName( array $mysteriousInput){ $arr = []; foreach ($mysteriousInput as $inp) { if ($inp > 10) { $arr[] = $inp; } } $arrLeft = $arrRight = $arrCenter = []; foreach ($arr as $elem) { $bucket = $elem <=> 20; if ($bucket < 0) { $arrLeft[] = $elem; } if ($bucket == 0) { $arrCenter[] = $elem; } if ($bucket > 0) { $arrRight[] = $elem;} } $countLeft = count($arrLeft); $countCenter = count($arrCenter); $countRight = count($arrRight); return array_sum([$countLeft, $countCenter, $countRight]) / 3; }
  • 12. public function someMethodWithMisleadingName( array $mysteriousInput) { $arr = []; foreach ($mysteriousInput as $inp) { if ($inp > 10) { $arr[] = $inp; } } $arrLeft = $arrRight = $arrCenter = []; foreach ($arr as $elem) { $bucket = $elem <=> 20; if ($bucket < 0) { $arrLeft[] = $elem; } if ($bucket == 0) { $arrCenter[] = $elem; } if ($bucket > 0) { $arrRight[] = $elem;} } $countLeft = count($arrLeft); $countCenter = count($arrCenter); $countRight = count($arrRight); return array_sum( [$countLeft, $countCenter, $countRight] ) / 3; } public function someMethodWithMisleadingName( ParallelListCollection $mysteriousInput) { return $mysteriousInput ->filter(function ($elem) { return $elem > 10; }) ->partition(function ($elem) { return $elem <=> 20; }) ->map(function ($bucket) { return $bucket->count(); }) ->avg(); }
  • 13. public function someMethodWithMisleadingName( array $mysteriousInput) { $arr = []; foreach ($mysteriousInput as $inp) { if ($inp > 10) { $arr[] = $inp; } } $arrLeft = $arrRight = $arrCenter = []; foreach ($arr as $elem) { $bucket = $elem <=> 20; if ($bucket < 0) { $arrLeft[] = $elem; } if ($bucket == 0) { $arrCenter[] = $elem; } if ($bucket > 0) { $arrRight[] = $elem;} } $countLeft = count($arrLeft); $countCenter = count($arrCenter); $countRight = count($arrRight); return array_sum( [$countLeft, $countCenter, $countRight] ) / 3; } public function someMethodWithMisleadingName( ParallelListCollection $mysteriousInput) { return $mysteriousInput ->filter(function ($elem) { return $elem > 10; }) ->partition(function ($elem) { return $elem <=> 20; }) ->map(function ($bucket) { return $bucket->count(); }) ->avg(); }
  • 14. WHAT? ❏ Function is a first-class citizen ❏ Lambda Calculus ❏ Immutability ❏ No side effects
  • 15. First-class citizen ❏ Can be stored in variable and data structures ❏ Can be passed as a parameter to procedure/functions ❏ Can be returned by procedures/functions ❏ Can be instantiated inline ❏ Has it’s own identity (name independent)
  • 17. Lambda Calculus ƛ(x) = z ❏ Higher-order functions ❏ Currying
  • 18. Lambda Calculus ƛ(x) = z ❏ Higher-order functions ❏ Currying SWITCH YOUR THINKING FROM “HOW?” TO “WHAT?”
  • 19. No side effects? Immutability? :(
  • 20. Functional vs Object oriented programming ?
  • 21.
  • 22. PHP7 is functional 
but is dirty and salty as well
  • 23. What do I miss in PHP7 that Scala luckily has?
  • 24. ❏ Immutability by default ❏ Objects cloning ❏ Options ❏ Either ❏ Future ❏ Parallel collections ❏ Tail recurrency ❏ Generic types ❏ Arrow functions ❏ Pattern matching / case classes
  • 26. Few rules to make your code functional
  • 27. Do not use ❏ reassignments ❏ if ❏ null ❏ for ❏ foreach
  • 29. Quick pool ❏ Do you DDD? ❏ Do you use setters?
  • 30. Quick pool ❏ Do you DDD? ❏ Do you use setters? “VALUE OBJECTS are completely immutable.” Eric Evans
  • 31. Do not use ❏ reassignments
  • 32. $bigHouse = new Building(5);
  • 33. $bigHouse = new Building(5); $smallerHouse = $bigHouse->setFloors(2); echo $bigHouse->getFloors(); echo $smallerHouse->getFloors();
  • 34. $bigHouse = new Building(5); $smallerHouse = $bigHouse->setFloors(2); echo $bigHouse->getFloors(); //2 echo $smallerHouse->getFloors(); //2
  • 35. class Building { protected $floors; public function __construct(int $floors) { $this->setFloors($floors); } public function getFloors() : int { return $this->floors; } public function setFloors(int $floors) : Building { $this->floors = $floors; return $this; } }
  • 36. use PhpSlangUtilCopy; class Building { use Copy; protected $floors; public function __construct(int $floors) { $this->floors = $floors; } public function getFloors() : int { return $this->floors; } public function withFloors(int $floors) : Building { return $this->copy('floors', $floors); } }
  • 37. $bigHouse = new Building(5); $smallerHouse = $bigHouse->withFloors(2); echo $bigHouse->getFloors(); //5 echo $smallerHouse->getFloors(); //2
  • 38. $bigHouse = new Building(5); $smallerHouse = $bigHouse->withFloors(2); echo $bigHouse->getFloors(); //5 echo $smallerHouse->getFloors(); //2 REFERENTIALTRANSPARENCY
  • 40. Referential transparency ❏ f(x, y) = (x+y) * y x, y and a result can be a function as well
  • 41. Referential transparency ❏ f(x, y) = (x+y) * y Eg. ❏ f(2, 4) = (2 + 4) * 4 = 8 * 4 = 32 ❏ f(1, 8) = (1 + 8) * 8 = 9 * 8 = 72
  • 42. Referential transparency ❏ f(x, y) = (x+y) * y Eg. ❏ f(2, 4) = (2 + 4) * 4 = 8 * 4 = 32 ❏ f(1, 8) = (1 + 8) * 8 = 9 * 8 = 72 i = 71; ComputingService::_opCount++; comps.push(new Tuple2(x, y));
  • 43. Referential transparency ❏ f(x, y) = (x+y) * y Eg. ❏ f(2, 4) = (2 + 4) * 4 = 8 * 4 = 32 ❏ f(1, 8) = (1 + 8) * 8 = 9 * 8 = 72 i = 71; ComputingService::_opCount++; comps.push(new Tuple2(x, y));
  • 44. Few rules to make your code functional
  • 45. Do not use :) reassignments ❏ if ❏ null ❏ for ❏ foreach
  • 46. Do not use :) reassignments ❏ if ❏ null ❏ for ❏ foreach ?
  • 47. Do not use :) reassignments ❏ if ❏ null ❏ for ❏ foreach Option
  • 48. Option Monad which may contain something or nothing
  • 49. What is a monad?
  • 50. What is a monad?
  • 51. What is a monad?
  • 52. What is a monad?
  • 53. What is a monad? map
  • 54. What is a monad? flatMap
  • 55. What is a monad?
  • 60. public function findByEmail(string $email) : User { $user = $this->findOneBy(['email' => $email]); if (!$user instanceof User) { throw new NotFoundException("oh my"); } return $user; } try { return new Response(findByEmail($email), HTTP_OK); } catch (NotFoundException $exception) { return new Response([], HTTP_NOT_FOUND); }
  • 61. public function findByEmail(string $email) : User { $user = $this->findOneBy(['email' => $email]); if (!$user instanceof User) { throw new NotFoundException("oh my"); } return $user; } try { return new Response(findByEmail($email), HTTP_OK); } catch (NotFoundException $exception) { return new Response([], HTTP_NOT_FOUND); } public function findByEmail(string $email) : Option { return Option::of($this->findOneBy(['email' => $email])); } return findByEmail($email)) ->map(function (User $user) { return new Response($user, HTTP_OK); }) ->getOrElse(new Response('', HTTP_NOT_FOUND));
  • 62. public function findByEmail(string $email) : User { $user = $this->findOneBy(['email' => $email]); if (!$user instanceof User) { throw new NotFoundException("oh my"); } return $user; } try { return new Response(findByEmail($email), HTTP_OK); } catch (NotFoundException $exception) { return new Response([], HTTP_NOT_FOUND); } public function findByEmail(string $email) : Option { return Option::of($this->findOneBy(['email' => $email])); } return findByEmail($email)) ->map(function (User $user) { return new Response($user, HTTP_OK); }) ->getOrElse(new Response('', HTTP_NOT_FOUND)); map
  • 64. public function findByEmail(string $email) : Option { return Option::of($this->findOneBy(['email' => $email])); } public function postalCode(string $email, PostalCode $default) : PostalCode { return findByEmail($email) ->map(function (User $user) { return $user->getProfile()->getAdress()->getPostalCode(); }) ->getOrElse($default); }
  • 65. public function postalCode(string $email, PostalCode $default) : PostalCode { return findByEmail($email); ->map(function (User $user) { return $user->getProfile()->getAdress()->getPostalCode(); }) ->getOrElse($default); }
  • 66. public function postalCode(string $email, PostalCode $default) : PostalCode { return findByEmail($email) ->flatMap(function (User $user) { return $user->getProfile(); }) ->flatMap(function (UserProfile $userProfile) { return $userProfile->getAdress(); }) ->flatMap(function (Adress $adress) { return $adress->getPostalCode(); }) ->getOrElse($default); }
  • 67. public function postalCode(string $email, PostalCode $default) : PostalCode { return findByEmail($email) ->flatMap(function (User $user) { return $user->getProfile(); }) ->flatMap(function (UserProfile $userProfile) { return $userProfile->getAdress(); }) ->flatMap(function (Adress $adress) { return $adress->getPostalCode(); }) ->getOrElse($default); } flatMap
  • 68. Few rules to make your code functional
  • 69. Do not use :) reassignments :) if :) null ❏ for ❏ foreach
  • 71. public function displayNameForUser(string $email) : string { return $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall(function () use (string $email) : string { return $this->getSomethingElseWith($email); }); }
  • 72. public function displayNameForUser(string $email) : string { return $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall(function () use (string $email) : string { return $this->getSomethingElseWith($email); }); }
  • 73. public displayNameForUser(string email) : string userRepository ->findByEmail(email) ->flatMap(_->getFirstName) ->getOrCall(getSomethingElseWith(email)) :(
  • 74. public def displayNameForUser(email : string) : string = userRepository .findByEmail(email) .flatMap(_.getFirstName) .getOrElse(_ => getSomethingElseWith(email)) :)
  • 75. public function displayNameForUser(string $email) : string { return $this ->userRepository ->findByEmail($email) ->flatMap(Extract($user)->getFirstName()) ->getOrCall(Extract($this)->getSomethingElseWith($email)); } NYI :)
  • 77. public function maybeSomething(string $email) : Option { ... }
  • 78. /** * @return Option<string> */ public function maybeSomething(string $email) : Option { ... } https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md :(
  • 79. public function maybeSomething(string $email) : Option<string> { ... } :o
  • 80. public function maybeSomething(string $email) : Option<string> { ... } ❏ Version: 0.4.0 ❏ Date: 2016-01-06 ❏ Author: ❏ Ben Scholzen 'DASPRiD' mail@dasprids.de, ❏ Rasmus Schultz rasmus@mindplay.dk ❏ Status: Draft ❏ First Published at: http://wiki.php.net/rfc/generics :(
  • 81. public function maybeSomething(string $email) : Option<string> { ... } WANT TO EARN EXTRA $1020 ? https://www.bountysource.com/issues/20553561-add-generics-support :~|
  • 83. What do I miss in PHP7 that Scala luckily has?
  • 84. :/ Immutability by default :) Objects cloning :) Options ❏ Either ❏ Future ❏ Parallel collections ❏ Tail recurrency :( Generic types :( Arrow functions ❏ Pattern matching / case classes
  • 87. Either Either RightLeft left(Closure $expr): Either right(Closure $expr): Either get() left(Closure $expr): Either right(Closure $expr): Either get()
  • 88. Either Either RightLeft left(Closure $expr): Either right(Closure $expr): Either get() left(Closure $expr): Either right(Closure $expr): Either get() SEMANTICS!
  • 89. What do I miss in PHP7 that Scala luckily has?
  • 90. :/ Immutability by default :) Objects cloning :) Options :) Either ❏ Future ❏ Parallel collections ❏ Tail recurrency :( Generic types :( Arrow functions ❏ Pattern matching / case classes
  • 92. Pattern matching Result Variant 1 Variant 2 Variant 3 Variant N ...
  • 93. return (Match::of($someKindResult)) ->match( new Case(IvalidInput::class, new Response('', HTTP_BAD_REQUEST)), new Case(NotFound::class, new Response('',HTTP_NOT_FOUND), new Default(function () use ($someKindResult) { return new Response($someKindResult, HTTP_OK); }) );
  • 94. What do I miss in PHP7 that Scala luckily has?
  • 95. :/ Immutability by default :) Objects cloning :) Options :) Either ❏ Future ❏ Parallel collections ❏ Tail recurrency :( Generic types :( Arrow functions :)/:( Pattern matching / case classes
  • 98. public function beautifulMultiplyOddsBy( array $input, float $multiplication) : ListCollection { return (new ListCollection($input)) ->filter(function ($number) { return $number % 2 !== 0; }) ->map(function ($number) use ($multiplication) { return $number * $multiplication; }); }
  • 99. public function accumulatedText(array $words) : string { $text = ''; foreach ($words as $word) { $text .= $word . ' '; } return $text; } public function accumulatedText(array $words) : string { return (new ListCollection($words)) ->fold('', function (string $acumulator, string $word) { return $acumulator . $word . ' '; }); }
  • 100. (new ListCollection([1,2,3,4]))->tail(); //ListCollection([2,3,4]) (new ListCollection([1,2,3,4]))->every(2); //ListCollection([2,4]) (new ListCollection([1,2,3,4]))->groups(2); ListCollection([ ListCollection([1,2]), ListCollection([3,4]), ])
  • 101. Few rules to make your code functional
  • 102. Do not use :) reassignments :) if :) null :) for :) foreach
  • 104.
  • 105.
  • 106. Future
  • 107. public function nonBlockingGet(string $id): Future { ... } public function exampleAction(string $id1) : Response { return $this ->nonBlockingService ->nonBlockingGet($id) ->map(function (NonBlockingGetResult $output) { return new Response($output); }) ->await(); }
  • 108. public function nonBlockingGet(string $id): Future { ... } public function exampleAction(string $id1) : Response { return $this ->nonBlockingService ->nonBlockingGet($id) ->map(function (NonBlockingGetResult $output) { return new Response($output); }) ->await(); } Future<NonBlockingGetResult> NYI
  • 109. public function nonBlockingGet(string $id): Future { ... } public function exampleAction(string $id1) : Response { return $this ->nonBlockingService ->nonBlockingGet($id) ->map(function (NonBlockingGetResult $output) { return new Response($output); }) ->await(); } Future<NonBlockingGetResult> NYI Future<Response>
  • 110. public function nonBlockingGet(string $id): Future { ... } public function exampleAction(string $id1) : Response { return $this ->nonBlockingService ->nonBlockingGet($id) ->map(function (NonBlockingGetResult $output) { return new Response($output); }) ->await(); } Future<NonBlockingGetResult> NYI Future<Response> Response
  • 111. public function nonBlockingGet(string $id): Future { ... } public function exampleAction(string $id1, string $id2, string $id3) : Response { return Future::all([ $this->nonBlockingService1->nonBlockingGet($id1), $this->nonBlockingService2->nonBlockingGet($id2), $this->nonBlockingService3->nonBlockingGet($id3), ]) ->map(function ($output) { return new Response($output); }) ->await(); } NYI
  • 112. Future & Parallel collections
  • 113. use PhpSlangCollectionListCollection; ... public function beautifulMultiplyBy(array $input, float $multiplication) : ListCollection { return (new ListCollection($input)) ->map(function ($number) use ($multiplication) { return $number * $multiplication; }); }
  • 114. use PhpSlangCollectionParallelListCollection; ... public function beautifulMultiplyBy(array $input, float $multiplication) : ParallelListCollection { return (new ParallelListCollection($input)) ->map(function ($number) use ($multiplication) { return $number * $multiplication; }); }
  • 115. use PhpSlangCollectionListCollection; ... public function asyncChainedComputationExample(array $input) : ListCollection { return (new ListCollection($input)) ->map($this->transformationOne()); } use PhpSlangCollectionParallelListCollection; ... public function asyncChainedComputationExample(array $input) : ParallelListCollection { return (new ParallelListCollection($input)) ->map($this->transformationOne()); }
  • 116. use PhpSlangCollectionListCollection; ... public function asyncChainedComputationExample(array $input) : ListCollection { return (new ListCollection($input)) ->map($this->transformationOne()); } use PhpSlangCollectionParallelListCollection; ... public function asyncChainedComputationExample(array $input) : ParallelListCollection { return (new ParallelListCollection($input)) ->map($this->transformationOne()); }
  • 117. use PhpSlangCollectionParallelListCollection; ... public function asyncChainedComputationExample(array $input) : ParallelListCollection { return (new ParallelListCollection($input)) ->map($this->transformationOne()); } CPU vs IO
  • 118. use PhpSlangCollectionParallelListCollection; ... public function asyncChainedComputationExample(array $input) : ParallelListCollection { return (new ParallelListCollection($input)) ->map($this->transformationOne()) ->map($this->transformationTwo()) ->map($this->transformationThree(); }
  • 119. use PhpSlangCollectionParallelListCollection; ... public function asyncChainedComputationExample(array $input) : ParallelListCollection { return (new ParallelListCollection($input)) ->map(function ($number) { return new Some($number) ->map($this->transformationOne()) ->map($this->transformationTwo()) ->map($this->transformationThree() ->get(); }); }
  • 120. use PhpSlangCollectionParallelListCollection; 
 public function asyncChainedComputationExample(array $input) : ParallelListCollection { return (new ParallelListCollection($input)) ->map(function ($number) { return new Some($number) ->map($this->transformationOne()) ->map($this->transformationTwo()) ->map($this->transformationThree() ->get(); }); }
  • 121. What do I miss in PHP7 that Scala luckily has?
  • 122. :/ Immutability by default :) Objects cloning :) Options :) Either :/ Future :) Parallel collections ❏ Tail recurrency :( Generic types :( Arrow functions :)/:( Pattern matching / case classes
  • 124. def fibonacci(index : Int) : Int = index match { case 0 | 1 => index case _ => fibonacci(index - 1 ) + fibonacci(index - 2) } function fibonacci(int $index) : int { return in_array($index, [0, 1]) ? $index : fibonacci($index - 1) + fibonacci($index - 2); }
  • 125. def fibonacci(index : Int) : Int = index match { case 0 | 1 => index case _ => fibonacci(index - 1 ) + fibonacci(index - 2) } function fibonacci(int $index) : int { return in_array($index, [0, 1]) ? $index : fibonacci($index - 1) + fibonacci($index - 2); } echo fibonacci(123123123123); Fatal error: Maximum function nesting level of '...' reached, aborting!
  • 127. def fibonacci(index: Int): Int = { var a = 0 var b = 1 var i = 0 while (i < index) { val c = a + b a = b b = c i = i + 1 } return a } function fibonacci(int $index) : int { $a = 0; $b = 1; $i = 0; while ($i < $index) { $c = $a + $b; $a = $b; $b = $c; $i += 1; } return $a; }
  • 128. def recursiveFibonacci(n: Int, a:Int, b:Int): Int = n match { case 0 => a case _ => recursiveFibonacci( n-1, b, a+b ) } def fibonacci( n : Int) : Int = recursiveFibonacci( n, 0, 1) function recursiveFibonacci(int $n, int $a, int $b) { return ($n == 0) ? $a : recursiveFibonacci($n - 1, $b, $a + $b); } function fibonacci(int $n) : int { return recursiveFibonacci($n, 0, 1); }
  • 129. def fibonacci(index : Int) : Int = index match { case 0 | 1 => index case _ => fibonacci(index - 1 ) + fibonacci(index - 2) } function fibonacci(int $index) : int { return in_array($index, [0, 1]) ? $index : fibonacci($index - 1) + fibonacci($index - 2); }
  • 130. @tailrec def recursiveFibonacci(n: Int, a:Int, b:Int): Int = n match { case 0 => a case _ => recursiveFibonacci( n-1, b, a+b ) } def fibonacci( n : Int) : Int = recursiveFibonacci( n, 0, 1) function recursiveFibonacci(int $n, int $a, int $b) { return ($n == 0) ? $a : recursiveFibonacci($n - 1, $b, $a + $b); } function fibonacci(int $n) : int { return recursiveFibonacci($n, 0, 1); } :( :)
  • 134. function recursiveFibonacci(int $n, int $a, int $b) { return ($n == 0) ? $a : recursiveFibonacci($n - 1, $b, $a + $b); } function fibonacci($n) { return recursiveFibonacci($n, 0, 1); }
  • 135. function recursiveFibonacci(int $n, int $a, int $b) { return ($n == 0) ? new Done($a) : new Bounce(function () use ($n, $b, $a) { return recursiveFibonacci($n - 1, $b, $a + $b); }); } function fibonacci($n) { return (new Trampoline(function () use ($n) { return recursiveFibonacci($n, 0, 1); }))->run(); }
  • 137. What do I miss in PHP7 that Scala luckily has?
  • 138. :/ Immutability by default :) Objects cloning :) Options :) Either :/ Future :) Parallel collections :) Tail recurrency :( Generic types :( Arrow functions :)/:( Pattern matching / case classes
  • 139.
  • 140. Conclusions ● Don’t be afraid of monads ● Care about transparency (especially referential) ● Learn Haskell, Clojure, Scala, F#, JavaScript -> TypeScript