PHPCon 2016: PHP7 by Witek Adamus / XSolve
-
Upload
xsolve-software-house -
Category
Technology
-
view
597 -
download
0
Transcript of PHPCon 2016: PHP7 by Witek Adamus / XSolve
![Page 1: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/1.jpg)
Witek Adamus
PHPCon 2016, Rawa Mazowiecka
![Page 2: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/2.jpg)
Why async and functional programming in PHP7 suck and how to get over it?
![Page 3: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/3.jpg)
Who am I?
![Page 4: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/4.jpg)
5 years of
imperative
programming
2 years of
functional
programming
Back to
PHP7
![Page 5: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/5.jpg)
❏ What can functional programming bring to the table?
❏ When language can be described as functional?
Table of content
![Page 6: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/6.jpg)
❏ DIY: cleaning ❏ Transparent parallelism❏ Parallelism vs Concurrency
❏ Parallel collections
Table of content
![Page 7: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/7.jpg)
Pros and cons of functional programming
Pros Cons
Efficiency Efficiency
Entry threshold Entry threshold
Mathematical description of
reality
Mathematical description of
reality
![Page 8: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/8.jpg)
Pros and cons of functional programming
Pros Cons In result
Efficiency Efficiency Scalability
Entry threshold Entry threshold Let’s get the party started
Mathematical description of
reality
Mathematical description of
reality
Shorter and more descriptive code
![Page 9: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/9.jpg)
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;}
![Page 10: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/10.jpg)
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();}
![Page 11: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/11.jpg)
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();}
![Page 12: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/12.jpg)
Fundamental concepts in functional programming
❏ Function is a first-class citizen
❏ No side effects
❏ Immutability
❏ Lambda Calculus
![Page 13: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/13.jpg)
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)
![Page 14: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/14.jpg)
No side effects? Immutability?
:(
![Page 15: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/15.jpg)
Lambda Calculus
ƛ(x) = z
![Page 16: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/16.jpg)
Lambda Calculus
ƛ(x) = z❏ Higher-order functions❏ Currying
![Page 17: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/17.jpg)
Functional vs Object oriented programming
?
![Page 18: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/18.jpg)
![Page 19: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/19.jpg)
PHP7 is functional
…but is dirty and salty as well
![Page 20: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/20.jpg)
What do I miss in PHP7 that Scala luckily has?
![Page 21: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/21.jpg)
❏ Immutability by default❏ Objects cloning❏ Options❏ Either❏ Future❏ Parallel collections❏ Tail recurrency
❏ Generic types❏ Arrow functions❏ Pattern matching / case classes
![Page 22: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/22.jpg)
Few rules to make your code functional
![Page 23: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/23.jpg)
Do not use
❏ reassignments❏ if❏ null❏ for❏ foreach
![Page 24: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/24.jpg)
Do not use
❏ reassignments
![Page 25: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/25.jpg)
$bigHouse = new Building(5);$smallerHouse = $bigHouse->setFloors(2);
echo $bigHouse->getFloors() . PHP_EOL; echo $smallerHouse->getFloors() . PHP_EOLl;
![Page 26: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/26.jpg)
$bigHouse = new Building(5);$smallerHouse = $bigHouse->setFloors(2);
echo $bigHouse->getFloors() . PHP_EOL; //2echo $smallerHouse->getFloors() . PHP_EOLl; //2
![Page 27: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/27.jpg)
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; }}
![Page 28: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/28.jpg)
class Building{ protected $floors;
public function __construct(int $floors) { $this->floors = $floors; }
public function getFloors() : int { return $this->floors; }
private function setFloors(int $floors) : Building { $this->floors = $floors; return $this; }
public function withFloors(int $floors) : Building { return (clone($this))->setFloors($floors); }}
![Page 29: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/29.jpg)
$bigHouse = new Building(5);$smallerHouse = $bigHouse->withFloors(2);
echo $bigHouse->getFloors() . PHP_EOL; //5echo $smallerHouse->getFloors() . PHP_EOLl; //2
![Page 30: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/30.jpg)
trait Copy{ public function copy($field, $value) { $clone = clone $this; $clone->$field = $value; return $clone; }}
![Page 31: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/31.jpg)
use PhpSlang\Util\Copy;
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); }}
![Page 32: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/32.jpg)
Few rules to make your code functional
![Page 33: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/33.jpg)
Do not use
:) reassignments❏ if❏ null❏ for❏ foreach
![Page 34: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/34.jpg)
https://github.com/php-slang/php-slang
![Page 35: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/35.jpg)
Do not use
:) reassignments❏ if❏ null❏ for❏ foreach
?
![Page 36: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/36.jpg)
Do not use
:) reassignments❏ if❏ null❏ for❏ foreach
Option
![Page 37: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/37.jpg)
OptionMonad which may contain something or nothing
![Page 38: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/38.jpg)
What is a monad?Option
![Page 39: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/39.jpg)
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
![Page 40: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/40.jpg)
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
![Page 41: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/41.jpg)
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
![Page 42: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/42.jpg)
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
![Page 43: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/43.jpg)
https://github.com/php-slang/php-slang
# composer require php-slang/php-slang
![Page 44: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/44.jpg)
Option
Option
NoneSome
![Page 45: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/45.jpg)
Option
Option
NoneSomemap(Closure $expression)getOrElse($default)
map(Closure $expression)getOrElse($default)
![Page 46: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/46.jpg)
Option
Option
NoneSomemap(Closure $expression)getOrElse($default)
map(Closure $expression)getOrElse($default)
Some($expression($this->content)
$this->content
![Page 47: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/47.jpg)
Option
Option
NoneSomemap(Closure $expression)getOrElse($default)
map(Closure $expression)getOrElse($default)
None
$default
![Page 48: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/48.jpg)
class UserRepository extends EntityRepository{ public function findByEmail(string $email) : User { $user = $this->findOneByMail(['email' => $email]);
if (!$user instanceof User) { throw new NotFoundException("oh my"); }
return $user; }}
public function findUserAction(string $email) : Response try { $user = $this ->userRepository ->findByEmail($email); return new Response($user); } catch (NotFoundException $exception) { return new Response([], Response::HTTP_NOT_FOUND); }}
![Page 49: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/49.jpg)
class UserRepository extends EntityRepository{ public function findByEmail(string $email) : Option { return Option::of($this>findOneByMail(['email' => $email])); }}
public function findUserAction(string $email) : Response return $this ->userRepository ->findByEmail($email)); ->map(function (User $user) { return new Response($user); }) ->getOrElse(new Response('', Response::HTTP_NOT_FOUND));}
![Page 50: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/50.jpg)
class UserRepository extends EntityRepository{ public function findByEmail(string $email) : User { $user = $this->findOneByMail(['email' => $email]);
if (!$user instanceof User) { throw new NotFoundException("oh my"); }
return $user; }}
public function findUserAction(string $email) : Response try { $user = $this ->userRepository ->findByEmail($email); return new Response($user); } catch (NotFoundException $exception) { return new Response([], Response::HTTP_NOT_FOUND); }}
class UserRepository extends EntityRepository{ public function findByEmail(string $email) : Option { return Option::of( $this>findOneByMail(['email' => $email])); }}
public function findUserAction(string $email) : Response return $this ->userRepository ->findByEmail($email)); ->map(function (User $user) { return new Response($user); }) ->getOrElse( new Response('', Response::HTTP_NOT_FOUND));}
![Page 51: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/51.jpg)
OptionHow about nesting
![Page 52: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/52.jpg)
public function displayNameForUser(string $email) : string{ $this ->userRepository ->findByEmail($email) ->get() ->getFirstName();}
![Page 53: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/53.jpg)
public function displayNameForUser(string $email) : string{ $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->firstName; }) ->getOrElse('oh my');}
![Page 54: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/54.jpg)
public function displayNameForUser(string $email) : ???{ $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->getFirstName(); });}
![Page 55: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/55.jpg)
public function displayNameForUser(string $email) : ???{ $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->getFirstName(); });}
?
![Page 56: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/56.jpg)
public function displayNameForUser(string $email) : ???{ $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->getFirstName(); });}
Option<Option<String>>
![Page 57: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/57.jpg)
public function displayNameForUser(string $email) : Option{ $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); });}
![Page 58: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/58.jpg)
public function displayNameForUser(string $email) : string{ $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrElse($email);}
![Page 59: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/59.jpg)
public function displayNameForUser(string $email) : string{ $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall(function () use ($email) { $this->getAlternative($email); });}
![Page 60: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/60.jpg)
public function displayNameForUser(string $email) : string{ $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall($this->getAlternative($email));}
![Page 61: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/61.jpg)
public function displayNameForUser(string $email) : string{ $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall($this->getAlternative($email));}
public function getAlternative(string $email) : \Closure{ return function () use (string $email) : string { return $this->doSomethingElseWith($email); };}
![Page 62: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/62.jpg)
Few rules to make your code functional
![Page 63: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/63.jpg)
Do not use
:) reassignments:) if:) null❏ for❏ foreach
![Page 64: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/64.jpg)
Shortened notation for anonymous functions
![Page 65: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/65.jpg)
public function displayNameForUser(string $email) : string{ return $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall($this->getAlternative($email));}
public function getAlternative(string $email) : \Closure{ return function () use (string $email) : string { return $this->doSomethingElseWith($email); };}
![Page 66: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/66.jpg)
public function displayNameForUser(string $email) : string{ $this ->userRepository ->findByEmail($email) ->flatMap((User $user) => $user->getFirstName()) ->getOrCall(() => $this->doSomethingElseWith($email))} :(
![Page 67: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/67.jpg)
Generic types
![Page 68: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/68.jpg)
public function maybeSomething(string $email) : Option{ ...}
![Page 69: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/69.jpg)
public function maybeSomething(string $email) : Option<string>{ ...}
![Page 70: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/70.jpg)
public function maybeSomething(string $email) : Option<string>{ ...}
❏ Version: 0.4.0❏ Date: 2016-01-06❏ Author: Ben Scholzen 'DASPRiD' [email protected], Rasmus Schultz [email protected]❏ Status: Draft❏ First Published at: http://wiki.php.net/rfc/generics
:(
![Page 71: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/71.jpg)
/*** @return Option<string>*/public function maybeSomething(string $email) : Option{ ...}
https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md
:(
![Page 72: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/72.jpg)
What do I miss in PHP7 that Scala luckily has?
![Page 73: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/73.jpg)
:) Immutability by default:) Objects cloning:) Options❏ Either❏ Future❏ Parallel collections❏ Tail recurrency
:( Generic types:( Arrow functions❏ Pattern matching / case classes
![Page 74: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/74.jpg)
Either
![Page 75: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/75.jpg)
Either
Either
RightLeft
![Page 76: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/76.jpg)
Either
Either
RightLeftleft(Closure $expr): Eitherright(Closure $expr): Eitherget()
left(Closure $expr): Eitherright(Closure $expr): Eitherget()
![Page 77: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/77.jpg)
public function findUserAction(string $email) : Response try { $user = $this ->userRepository ->findByEmail($email); return new Response($user); } catch (NotFoundException $exception) { return new Response([], Response::HTTP_NOT_FOUND); }}
![Page 78: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/78.jpg)
public function findUserAction(string $email) : Response try { $user = $this ->userRepository ->findByEmail($email); return new Response($user); } catch (NotFoundException $exception) { return new Response([], Response::HTTP_NOT_FOUND); } catch (ExternalServiceResponseException $exception) { return new Response([], Response::HTTP_FAILED_DEPENDENCY); } catch (IncorrectEmailException $exception) { return new Response([], Response::HTTP_BAD_REQUEST); } catch (UserNotAllowedException $exception) { return new Response([], Response::HTTP_FORBIDDEN); }}
“Co jest piękniejszego niż rdest? No chyba tylko bylina rdestu, bo rzadziej występuje.”Ohanhutep
![Page 79: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/79.jpg)
interface ServiceError {}
class NotFound implements ServiceError {}class ServiceNotWorking implements ServiceError {}class Param2IsPoorlyFormatted implements ServiceError {}
public function getSomethingNontrivial(string $param1, string $param2, string $param3) : Either{ ...}
Either<ServiceError, User>
![Page 80: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/80.jpg)
public function exampleAction(string $param1, string $param2, string $param3) : Response {
return $this ->userService ->getSomethingNontrivial($param1, $param2, $param3) ->left(function (ServiceError $someKindOfFailure) : Response { new Case(ServiceNotWorking::class, new Response('', Response::HTTP_FAILED_DEPENDENCY)), new Case(Param2IsPoorlyFormatted::class, new Response('', Response::HTTP_BAD_REQUEST)), new Case(NotFound()::class, new Response([], Response::HTTP_NOT_FOUND)); }) ->right(function (User $nonTrivialAllRight) : Response { return new Response($nonTrivialAllRight, Response::HTTP_OK); }) ->get();}
![Page 81: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/81.jpg)
public function getSomethingNontrivial( string $param1, string $param2, string $param3) : Either{ return $this ->translateParam2($param2) ->map(function ($param2Translated) { return new Right($this->getUserBy($param2Translated)); }) ->getOrElse(new Left(new Param2IsPoorlyFormatted()));}
![Page 82: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/82.jpg)
public function getSomethingNontrivial(string $param1, string $param2, string $param3) : Either{ return $this ->translateParam2($param2) ->map($this->handleWithTranslatedParam($param1, $param3)) ->getOrElse(new Left(new Param2IsPoorlyFormatted()));}
public function handleWithTranslatedParam(string $param1, string $param3) : \Clojure{ return function (Param2Translated $param2Translated) use ($param1, $param3) : Either { return $this ->someOtherMagic($param2Translated, $param1, $param3) ->map(function (User $magicResult) use ($param1, $param3) : Either { return new Right($magicResult); }) ->getOrElse(new Left(new ServiceNotWorking())); };}
![Page 83: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/83.jpg)
What do I miss in PHP7 that Scala luckily has?
![Page 84: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/84.jpg)
:) Immutability by default:) Objects cloning:) Options❏ Either❏ Future❏ Parallel collections❏ Tail recurrency
:( Generic types:( Arrow functions❏ Pattern matching / case classes
![Page 85: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/85.jpg)
Pattern Matching
![Page 86: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/86.jpg)
public function exampleAction(string $param1, string $param2, string $param3) : Response{ return $this ->userService ->getSomethingNontrivial($param1, $param2, $param3) ->left(function (ServiceError $someKindOfFailure) : Response { return (Match::of($someKindOfFailure))->match( new Case(ServiceNotWorking::class, new Response('', Response::HTTP_FAILED_DEPENDENCY)), new Case(Param2IsPoorlyFormatted::class, new Response('', Response::HTTP_BAD_REQUEST)), new Case(NotFound::class, new Response([], Response::HTTP_NOT_FOUND)); }) ->right(function (User $nonTrivialAllRight) : Response { return new Response($nonTrivialAllRight, Response::HTTP_OK); }) ->get();}
![Page 87: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/87.jpg)
def update(id: String): Action[JsValue] = Action.async(parse.json) { request => user.update(id, userConverterFactory.of(request.body).toInput)
.map {case Right(user) => Ok(user)case Left(UserService.UserNotFound) => NotFoundcase Left(UserService.VersioningMissmatch) => NotAcceptablecase Left(UserService.NoModificationsAllowed) => Lockedcase Left(UserService.InvalidPayload) => BadRequest
}}
![Page 88: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/88.jpg)
What do I miss in PHP7 that Scala luckily has?
![Page 89: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/89.jpg)
:) Immutability by default:) Objects cloning:) Options:) Either❏ Future❏ Parallel collections❏ Tail recurrency
:( Generic types:( Arrow functions:)/:( Pattern matching / case classes
![Page 90: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/90.jpg)
Parallel collections
![Page 91: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/91.jpg)
public function multiplyBy( array $input, float $multiplication): array{ $output = [];
foreach($input as $number) { $output[] = $number * $multiplication; }
return $output;}
![Page 92: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/92.jpg)
use PhpSlang\Collection\ListCollection;...public function beautifulMultiplyBy( array $input, float $multiplication) : ListCollection{ return (new ListCollection($input)) ->map(function ($number) use ($multiplication) { return $number * $multiplication; });}
![Page 93: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/93.jpg)
public function multiplyOddsBy( array $input, float $multiplication): array{ $output = [];
foreach ($input as $number) { if ($number % 2 !== 0) { $output[] = $number * $multiplication; } }
return $output;}
![Page 94: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/94.jpg)
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; });}
![Page 95: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/95.jpg)
public function accumulatedText(array $words) : string { $text = '';
foreach ($words as $word) { $text .= $word . ' '; }
return $text;}
![Page 96: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/96.jpg)
public function accumulatedText(array $words) : string{ return (new ListCollection($words)) ->fold('', function (string $acumulator, string $word) { return $acumulator . $word . ' '; });}
![Page 97: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/97.jpg)
![Page 98: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/98.jpg)
(new ListCollection([1,2,3,4]))->tail(); //ArrayCollection([2,3,4])
![Page 99: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/99.jpg)
Few rules to make your code functional
![Page 100: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/100.jpg)
Do not use
:) reassignments:) if:) null:) for:) foreach
![Page 101: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/101.jpg)
Parallelism vs Concurrency
![Page 102: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/102.jpg)
![Page 103: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/103.jpg)
![Page 104: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/104.jpg)
Future
![Page 105: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/105.jpg)
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();}
![Page 106: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/106.jpg)
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>
Jak powinno to wyglądać?
![Page 107: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/107.jpg)
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>
Jak powinno to wyglądać?
Future<Response>
![Page 108: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/108.jpg)
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>
Jak powinno to wyglądać?
Future<Response>
Response
![Page 109: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/109.jpg)
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();}
Jak powinno to wyglądać?
![Page 110: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/110.jpg)
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();}
Jak powinno to wyglądać?
![Page 111: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/111.jpg)
Future & Parallel collections
![Page 112: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/112.jpg)
use PhpSlang\Collection\ListCollection;...public function beautifulMultiplyBy( array $input, float $multiplication) : ListCollection{ return (new ListCollection($input)) ->map(function ($number) use ($multiplication) { return $number * $multiplication; });}
![Page 113: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/113.jpg)
use PhpSlang\Collection\ParallelListCollection;...public function beautifulMultiplyBy( array $input, float $multiplication) : ParallelListCollection{ return (new ParallelListCollection($input)) ->map(function ($number) use ($multiplication) { return $number * $multiplication; });}
![Page 114: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/114.jpg)
class ParallelListCollection extends ListCollection{ public function map(Closure $func) { return Future::all( (new ArrayCollection($this->elements)) ->map(function ($element) use ($func) { return new Future(function () use ($func, $element) { return $func($element); }); }) ->toArray()) ->await(); }}
![Page 115: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/115.jpg)
class ParallelListCollection extends ListCollection{ public function map(\Closure $func) { return Future::all( (new ArrayCollection($this->elements)) ->map(function ($element) use ($func) { return new Future(function () use ($func, $element) { return $func($element); }); }) ->toArray()) ->await(); }}
ArrayCollection<Future<mixed>>
Future<ArrayCollection<mixed>>
ArrayCollection<mixed>
![Page 116: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/116.jpg)
use PhpSlang\Collection\ParallelListCollection;...public function asyncChainedComputationExample(array $input) : ParallelListCollection{ return (new ParallelListCollection($input))
->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree();}
![Page 117: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/117.jpg)
use PhpSlang\Collection\ParallelListCollection;...public function asyncChainedComputationExample(array $input) : ParallelListCollection{ return (new ParallelListCollection($input))
->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree();}
![Page 118: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/118.jpg)
use PhpSlang\Collection\ParallelListCollection;...public function asyncChainedComputationExample(array $input) : ParallelListCollection{ return (new ParallelListCollection($input)) ->map(function ($number) { return Option::of($number) ->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree()
->get(); });}
![Page 119: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/119.jpg)
use PhpSlang\Collection\ParallelListCollection;…public function asyncChainedComputationExample(array $input) : ParallelListCollection{ return (new ParallelListCollection($input)) ->map(function ($number) { return Option::of($number) ->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree()
->get(); });}
![Page 120: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/120.jpg)
What do I miss in PHP7 that Scala luckily has?
![Page 121: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/121.jpg)
:) Immutability by default:) Objects cloning:) Options:) Either:)/:( Future:) Parallel collections❏ Tail recurrency
:( Generic types:( Arrow functions:)/:( Pattern matching / case classes
![Page 122: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/122.jpg)
Tail recurrency
![Page 123: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/123.jpg)
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);}
![Page 124: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/124.jpg)
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!
![Page 125: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/125.jpg)
ini_set('xdebug.max_nesting_level', 9999999);
?
![Page 126: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/126.jpg)
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;}
![Page 127: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/127.jpg)
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);}
![Page 128: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/128.jpg)
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);}
![Page 129: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/129.jpg)
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);} :(
![Page 130: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/130.jpg)
Tail recurrencyTrampolines
![Page 131: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/131.jpg)
Recurrency
![Page 132: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/132.jpg)
Recurrency Trampoline
![Page 133: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/133.jpg)
<?php
namespace PhpSlang\Util\Trampoline;...class Trampoline{ /** * @var TrampolineResult */ var $expression;
public function __construct(Closure $expression) { $this->expression; } public function run() { $result = new Bounce(function () { return ($this->expression)(); }); while ($result instanceof Bounce) { $result = $result->run(); } return $result->run()->get(); }}
interface TrampolineResult{ public function run() : TrampolineResult;
public function get();}
class Bounce implements TrampolineResult {...}
class Done implements TrampolineResult {...}
![Page 134: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/134.jpg)
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);}
echo fibonacci(8);
![Page 135: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/135.jpg)
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();}
echo fibonacci(8);
![Page 136: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/136.jpg)
What do I miss in PHP7 that Scala luckily has?
![Page 137: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/137.jpg)
:) Immutability by default:) Objects cloning:) Options:) Either:)/:( Future:) Parallel collections:) Tail recurrency
:( Generic types:( Arrow functions:)/:( Pattern matching / case classes
![Page 138: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/138.jpg)
![Page 139: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/139.jpg)
Conclusions
● Don’t be afraid of monads● Don’t set traps for your team
● Learn Haskell, Clojure, Scala, F#, JavaScript -> TypeScript
![Page 141: PHPCon 2016: PHP7 by Witek Adamus / XSolve](https://reader036.fdocuments.net/reader036/viewer/2022062412/589ffdfa1a28abd40b8b4597/html5/thumbnails/141.jpg)
xsolve.pl/nobodyexpects