6. ❏ DIY: cleaning ❏ Transparent parallelism
❏ Parallelism vs Concurrency
❏ Parallel collections
Table of content
7. Pros and cons of functional programming
Pros Cons
Efficiency Efficiency
Entry threshold Entry threshold
Mathematical
description of
reality
Mathematical
description of
reality
8. 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
12. Fundamental concepts in functional programming
❏ Function is a first-class citizen
❏ No side effects
❏ Immutability
❏ Lambda Calculus
13. 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)
27. 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;
}
}
28. 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);
}
}
30. trait Copy
{
public function copy($field, $value)
{
$clone = clone $this;
$clone->$field = $value;
return $clone;
}
}
31. 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);
}
}
105. 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();
}
106. 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ć?
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();
}
Future<NonBlockingGetResult>
Jak powinno to wyglądać?
Future<Response>
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>
Jak powinno to wyglądać?
Future<Response>
Response
109. 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ć?
110. 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ć?
112. use PhpSlangCollectionListCollection;
...
public function beautifulMultiplyBy(
array $input, float $multiplication) : ListCollection
{
return (new ListCollection($input))
->map(function ($number) use ($multiplication) {
return $number * $multiplication;
});
}
113. use PhpSlangCollectionParallelListCollection;
...
public function beautifulMultiplyBy(
array $input, float $multiplication) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map(function ($number) use ($multiplication) {
return $number * $multiplication;
});
}
114. 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();
}
}
115. 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>
116. use PhpSlangCollectionParallelListCollection;
...
public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree();
}
117. use PhpSlangCollectionParallelListCollection;
...
public function asyncChainedComputationExample(array $input) : ParallelListCollection
{
return (new ParallelListCollection($input))
->map($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree();
}
118. use PhpSlangCollectionParallelListCollection;
...
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();
});
}
119. use PhpSlangCollectionParallelListCollection;
…
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();
});
}
120. What do I miss in PHP7 that Scala
luckily has?
126. 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;
}
127. 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);
}
128. 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);
}
129. 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);
}
:(
133. <?php
namespace PhpSlangUtilTrampoline;
...
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 {...}
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);
}
echo fibonacci(8);
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();
}
echo fibonacci(8);
136. What do I miss in PHP7 that Scala
luckily has?