SlideShare ist ein Scribd-Unternehmen logo
1 von 141
Downloaden Sie, um offline zu lesen
Witek Adamus
PHPCon 2016, Rawa Mazowiecka
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
❏ What can
functional
programming
bring to the
table?
❏ When language
can be
described as
functional?
Table of content
❏ DIY: cleaning ❏ Transparent parallelism
❏ Parallelism vs Concurrency
❏ Parallel collections
Table of content
Pros and cons of functional programming
Pros Cons
Efficiency Efficiency
Entry threshold Entry threshold
Mathematical
description of
reality
Mathematical
description of
reality
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
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();
}
Fundamental concepts in functional programming
❏ Function is a first-class citizen
❏ No side effects
❏ Immutability
❏ Lambda Calculus
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)
No side effects? Immutability?
:(
Lambda Calculus
ƛ(x) = z
Lambda Calculus
ƛ(x) = z
❏ Higher-order functions
❏ Currying
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
Few rules to
make your
code
functional
Do not use
❏ reassignments
❏ if
❏ null
❏ for
❏ foreach
Do not use
❏ reassignments
$bigHouse = new Building(5);
$smallerHouse = $bigHouse->setFloors(2);
echo $bigHouse->getFloors() . PHP_EOL;
echo $smallerHouse->getFloors() . PHP_EOLl;
$bigHouse = new Building(5);
$smallerHouse = $bigHouse->setFloors(2);
echo $bigHouse->getFloors() . PHP_EOL; //2
echo $smallerHouse->getFloors() . PHP_EOLl; //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;
}
}
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);
}
}
$bigHouse = new Building(5);
$smallerHouse = $bigHouse->withFloors(2);
echo $bigHouse->getFloors() . PHP_EOL; //5
echo $smallerHouse->getFloors() . PHP_EOLl; //2
trait Copy
{
public function copy($field, $value)
{
$clone = clone $this;
$clone->$field = $value;
return $clone;
}
}
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);
}
}
Few rules to
make your
code
functional
Do not use
:) reassignments
❏ if
❏ null
❏ for
❏ foreach
https://github.com/php-slang/php-slang
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?
Option
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
Fishy Monad Tutorial
http://maciejpirog.github.io/fishy/ (cc-by-sa)
https://github.com/php-slang/php-slang
# composer require php-slang/php-slang
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
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));
}
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));
}
Option
How about nesting
public function displayNameForUser(string $email) : string
{
$this
->userRepository
->findByEmail($email)
->get()
->getFirstName();
}
public function displayNameForUser(string $email) : string
{
$this
->userRepository
->findByEmail($email)
->map(function (User $user) {
return $user->firstName;
})
->getOrElse('oh my');
}
public function displayNameForUser(string $email) : ???
{
$this
->userRepository
->findByEmail($email)
->map(function (User $user) {
return $user->getFirstName();
});
}
public function displayNameForUser(string $email) : ???
{
$this
->userRepository
->findByEmail($email)
->map(function (User $user) {
return $user->getFirstName();
});
}
?
public function displayNameForUser(string $email) : ???
{
$this
->userRepository
->findByEmail($email)
->map(function (User $user) {
return $user->getFirstName();
});
}
Option<Option<String>>
public function displayNameForUser(string $email) : Option
{
$this
->userRepository
->findByEmail($email)
->flatMap(function (User $user) {
return $user->getFirstName();
});
}
public function displayNameForUser(string $email) : string
{
$this
->userRepository
->findByEmail($email)
->flatMap(function (User $user) {
return $user->getFirstName();
})
->getOrElse($email);
}
public function displayNameForUser(string $email) : string
{
$this
->userRepository
->findByEmail($email)
->flatMap(function (User $user) {
return $user->getFirstName();
})
->getOrCall(function () use ($email) {
$this->getAlternative($email);
});
}
public function displayNameForUser(string $email) : string
{
$this
->userRepository
->findByEmail($email)
->flatMap(function (User $user) {
return $user->getFirstName();
})
->getOrCall($this->getAlternative($email));
}
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);
};
}
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($this->getAlternative($email));
}
public function getAlternative(string $email) : Closure
{
return function () use (string $email) : string {
return $this->doSomethingElseWith($email);
};
}
public function displayNameForUser(string $email) : string
{
$this
->userRepository
->findByEmail($email)
->flatMap((User $user) => $user->getFirstName())
->getOrCall(() => $this->doSomethingElseWith($email))
}
:(
Generic types
public function maybeSomething(string $email) : Option
{
...
}
public function maybeSomething(string $email) : Option<string>
{
...
}
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
:(
/**
* @return Option<string>
*/
public function maybeSomething(string $email) : Option
{
...
}
https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md
:(
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()
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);
}
}
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
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>
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();
}
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()));
}
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()));
};
}
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
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();
}
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) => NotFound
case Left(UserService.VersioningMissmatch) => NotAcceptable
case Left(UserService.NoModificationsAllowed) => Locked
case Left(UserService.InvalidPayload) => BadRequest
}
}
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
public function multiplyBy(
array $input, float $multiplication): array
{
$output = [];
foreach($input as $number)
{
$output[] = $number * $multiplication;
}
return $output;
}
use PhpSlangCollectionListCollection;
...
public function beautifulMultiplyBy(
array $input, float $multiplication) : ListCollection
{
return (new ListCollection($input))
->map(function ($number) use ($multiplication) {
return $number * $multiplication;
});
}
public function multiplyOddsBy(
array $input, float $multiplication): array
{
$output = [];
foreach ($input as $number) {
if ($number % 2 !== 0) {
$output[] = $number * $multiplication;
}
}
return $output;
}
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(); //ArrayCollection([2,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>
Jak powinno to wyglądać?
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>
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
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ć?
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ć?
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;
});
}
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();
}
}
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>
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($this->transformationOne())
->map($this->transformationTwo())
->map($this->transformationThree();
}
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();
});
}
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();
});
}
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);
}
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
<?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 {...}
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);
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);
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
● Don’t set traps for your team
● Learn Haskell, Clojure, Scala, F#, JavaScript -> TypeScript
Witek Adamus
witold.adamus@xsolve.pl
xsolve.pl/nobodyexpects

Weitere ähnliche Inhalte

Was ist angesagt?

Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven DevelopmentAugusto Pascutti
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix itRafael Dohms
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsGuilherme Blanco
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)Michiel Rook
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)brian d foy
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationKirill Chebunin
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Nikita Popov
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 

Was ist angesagt? (20)

Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven Development
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)The road to continuous deployment (PHPCon Poland 2016)
The road to continuous deployment (PHPCon Poland 2016)
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 

Andere mochten auch

How to be agile at Agile Hack?! - agilehack.pl
How to be agile at Agile Hack?! - agilehack.plHow to be agile at Agile Hack?! - agilehack.pl
How to be agile at Agile Hack?! - agilehack.plXSolve
 
Xsolve presentation - programming, bodyleasing, e-commerce
Xsolve presentation - programming, bodyleasing, e-commerceXsolve presentation - programming, bodyleasing, e-commerce
Xsolve presentation - programming, bodyleasing, e-commerceXSolve
 
Piątek z XSolve - TravisCI & Continuous Delivery
Piątek z XSolve - TravisCI & Continuous DeliveryPiątek z XSolve - TravisCI & Continuous Delivery
Piątek z XSolve - TravisCI & Continuous DeliveryXSolve
 
Xlab #2: wzorce projektowe
Xlab #2: wzorce projektoweXlab #2: wzorce projektowe
Xlab #2: wzorce projektoweXSolve
 
xlab #7 - ReactJS & NodeJS
xlab #7 - ReactJS & NodeJSxlab #7 - ReactJS & NodeJS
xlab #7 - ReactJS & NodeJSXSolve
 
xlab #8 - Architektura mikroserwisów na platformie Spring Boot
xlab #8 - Architektura mikroserwisów na platformie Spring Bootxlab #8 - Architektura mikroserwisów na platformie Spring Boot
xlab #8 - Architektura mikroserwisów na platformie Spring BootXSolve
 
M&m's m.p. amarillo
M&m's m.p. amarilloM&m's m.p. amarillo
M&m's m.p. amarilloDani Vidal
 
Curso Web20 S1 Conversacion Distribuida
Curso Web20 S1 Conversacion DistribuidaCurso Web20 S1 Conversacion Distribuida
Curso Web20 S1 Conversacion DistribuidaDomingo Méndez
 
2ª circular foto orla 6º primaria 14 15
2ª circular foto orla 6º primaria 14 152ª circular foto orla 6º primaria 14 15
2ª circular foto orla 6º primaria 14 15Cole Navalazarza
 
Nuestra tierra 40 Geografía de la vida
Nuestra tierra 40 Geografía de la vidaNuestra tierra 40 Geografía de la vida
Nuestra tierra 40 Geografía de la vidaXimena Sosa Motta
 
firmenkontor24
firmenkontor24firmenkontor24
firmenkontor24infoprimus
 
Do the Chinese really lose face?
Do the Chinese really lose face?Do the Chinese really lose face?
Do the Chinese really lose face?Daniela Fehring
 
Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...
Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...
Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...Par-Tec S.p.A.
 
Nmedia marketing escuela nautica - forca 6 - estudio de mercado gratis
Nmedia marketing   escuela nautica - forca 6 - estudio de mercado gratisNmedia marketing   escuela nautica - forca 6 - estudio de mercado gratis
Nmedia marketing escuela nautica - forca 6 - estudio de mercado gratisNmediaMarketing
 
Codetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, Signature
Codetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, SignatureCodetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, Signature
Codetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, Signaturemi gen
 

Andere mochten auch (20)

How to be agile at Agile Hack?! - agilehack.pl
How to be agile at Agile Hack?! - agilehack.plHow to be agile at Agile Hack?! - agilehack.pl
How to be agile at Agile Hack?! - agilehack.pl
 
Xsolve presentation - programming, bodyleasing, e-commerce
Xsolve presentation - programming, bodyleasing, e-commerceXsolve presentation - programming, bodyleasing, e-commerce
Xsolve presentation - programming, bodyleasing, e-commerce
 
Piątek z XSolve - TravisCI & Continuous Delivery
Piątek z XSolve - TravisCI & Continuous DeliveryPiątek z XSolve - TravisCI & Continuous Delivery
Piątek z XSolve - TravisCI & Continuous Delivery
 
Xlab #2: wzorce projektowe
Xlab #2: wzorce projektoweXlab #2: wzorce projektowe
Xlab #2: wzorce projektowe
 
xlab #7 - ReactJS & NodeJS
xlab #7 - ReactJS & NodeJSxlab #7 - ReactJS & NodeJS
xlab #7 - ReactJS & NodeJS
 
xlab #8 - Architektura mikroserwisów na platformie Spring Boot
xlab #8 - Architektura mikroserwisów na platformie Spring Bootxlab #8 - Architektura mikroserwisów na platformie Spring Boot
xlab #8 - Architektura mikroserwisów na platformie Spring Boot
 
M&m's m.p. amarillo
M&m's m.p. amarilloM&m's m.p. amarillo
M&m's m.p. amarillo
 
Curso Web20 S1 Conversacion Distribuida
Curso Web20 S1 Conversacion DistribuidaCurso Web20 S1 Conversacion Distribuida
Curso Web20 S1 Conversacion Distribuida
 
2ª circular foto orla 6º primaria 14 15
2ª circular foto orla 6º primaria 14 152ª circular foto orla 6º primaria 14 15
2ª circular foto orla 6º primaria 14 15
 
Hoja de vida. fernando mesa
Hoja de vida. fernando mesaHoja de vida. fernando mesa
Hoja de vida. fernando mesa
 
Linux
LinuxLinux
Linux
 
Nuestra tierra 40 Geografía de la vida
Nuestra tierra 40 Geografía de la vidaNuestra tierra 40 Geografía de la vida
Nuestra tierra 40 Geografía de la vida
 
Futmondo
FutmondoFutmondo
Futmondo
 
firmenkontor24
firmenkontor24firmenkontor24
firmenkontor24
 
Do the Chinese really lose face?
Do the Chinese really lose face?Do the Chinese really lose face?
Do the Chinese really lose face?
 
Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...
Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...
Forum ICT Security 2015 - Identificare gli attacchi di nuova generazione medi...
 
Cuadrosdesebas
CuadrosdesebasCuadrosdesebas
Cuadrosdesebas
 
Nmedia marketing escuela nautica - forca 6 - estudio de mercado gratis
Nmedia marketing   escuela nautica - forca 6 - estudio de mercado gratisNmedia marketing   escuela nautica - forca 6 - estudio de mercado gratis
Nmedia marketing escuela nautica - forca 6 - estudio de mercado gratis
 
Codetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, Signature
Codetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, SignatureCodetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, Signature
Codetwo Exchange Rules 2007 Users Manual - Exchange Disclaimer, Signature
 
Einladung Cleantech Konferenz
Einladung Cleantech KonferenzEinladung Cleantech Konferenz
Einladung Cleantech Konferenz
 

Ähnlich wie PHPCon 2016: PHP7 by Witek Adamus / XSolve

Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Lucas Witold Adamus
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developersStoyan Stefanov
 
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
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
 
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
 
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSLPHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSLiMasters
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPWildan Maulana
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your CodeAbbas Ali
 
Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Stephan Schmidt
 
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
 
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
 
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
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with YieldJason Myers
 

Ähnlich wie PHPCon 2016: PHP7 by Witek Adamus / XSolve (20)

Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
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
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
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
 
Functional php
Functional phpFunctional php
Functional php
 
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSLPHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Oops in php
Oops in phpOops in php
Oops in php
 
Hack tutorial
Hack tutorialHack tutorial
Hack tutorial
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Functional programming with php7
Functional programming with php7Functional programming with php7
Functional programming with php7
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5Go OO! - Real-life Design Patterns in PHP 5
Go OO! - Real-life Design Patterns in PHP 5
 
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...
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
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
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with Yield
 

Mehr von XSolve

Jak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricksJak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricksXSolve
 
How to Create an Agile Office
How to Create an Agile OfficeHow to Create an Agile Office
How to Create an Agile OfficeXSolve
 
Xlab #10: Integracja zewnętrznych API z wykorzystaniem platformy Spring
Xlab #10: Integracja zewnętrznych API z wykorzystaniem platformy SpringXlab #10: Integracja zewnętrznych API z wykorzystaniem platformy Spring
Xlab #10: Integracja zewnętrznych API z wykorzystaniem platformy SpringXSolve
 
How to build a Tesla car for the price of a Chevrolet
How to build a Tesla car for the price of a ChevroletHow to build a Tesla car for the price of a Chevrolet
How to build a Tesla car for the price of a ChevroletXSolve
 
Piątek z XSolve - Bezpieczne nagłówki HTTP
Piątek z XSolve - Bezpieczne nagłówki HTTPPiątek z XSolve - Bezpieczne nagłówki HTTP
Piątek z XSolve - Bezpieczne nagłówki HTTPXSolve
 
Grafowa baza danych i integracja z symfony
Grafowa baza danych  i integracja z symfonyGrafowa baza danych  i integracja z symfony
Grafowa baza danych i integracja z symfonyXSolve
 
How to outsource Scrum projects - a guide
How to outsource Scrum projects - a guideHow to outsource Scrum projects - a guide
How to outsource Scrum projects - a guideXSolve
 
Prezentacja firmy XSolve - programowanie, e-commerce, bodyleasing
Prezentacja firmy XSolve - programowanie, e-commerce, bodyleasingPrezentacja firmy XSolve - programowanie, e-commerce, bodyleasing
Prezentacja firmy XSolve - programowanie, e-commerce, bodyleasingXSolve
 
Dlaczego git to nie svn oraz dlaczego to dobrze ?
Dlaczego git to nie svn oraz dlaczego to dobrze ?Dlaczego git to nie svn oraz dlaczego to dobrze ?
Dlaczego git to nie svn oraz dlaczego to dobrze ?XSolve
 
Programowanie zorientowane aspektowo
Programowanie zorientowane aspektowoProgramowanie zorientowane aspektowo
Programowanie zorientowane aspektowoXSolve
 
Agile estimating and planning
Agile estimating and planningAgile estimating and planning
Agile estimating and planningXSolve
 
Tailoring of PRINCE2
Tailoring of PRINCE2Tailoring of PRINCE2
Tailoring of PRINCE2XSolve
 
Mongo db baza danych zorientowana dokumentowo
Mongo db  baza danych zorientowana dokumentowo Mongo db  baza danych zorientowana dokumentowo
Mongo db baza danych zorientowana dokumentowo XSolve
 
Debugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebugDebugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebugXSolve
 
Zarządzanie projektami w XSolve
Zarządzanie projektami w XSolveZarządzanie projektami w XSolve
Zarządzanie projektami w XSolveXSolve
 

Mehr von XSolve (15)

Jak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricksJak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricks
 
How to Create an Agile Office
How to Create an Agile OfficeHow to Create an Agile Office
How to Create an Agile Office
 
Xlab #10: Integracja zewnętrznych API z wykorzystaniem platformy Spring
Xlab #10: Integracja zewnętrznych API z wykorzystaniem platformy SpringXlab #10: Integracja zewnętrznych API z wykorzystaniem platformy Spring
Xlab #10: Integracja zewnętrznych API z wykorzystaniem platformy Spring
 
How to build a Tesla car for the price of a Chevrolet
How to build a Tesla car for the price of a ChevroletHow to build a Tesla car for the price of a Chevrolet
How to build a Tesla car for the price of a Chevrolet
 
Piątek z XSolve - Bezpieczne nagłówki HTTP
Piątek z XSolve - Bezpieczne nagłówki HTTPPiątek z XSolve - Bezpieczne nagłówki HTTP
Piątek z XSolve - Bezpieczne nagłówki HTTP
 
Grafowa baza danych i integracja z symfony
Grafowa baza danych  i integracja z symfonyGrafowa baza danych  i integracja z symfony
Grafowa baza danych i integracja z symfony
 
How to outsource Scrum projects - a guide
How to outsource Scrum projects - a guideHow to outsource Scrum projects - a guide
How to outsource Scrum projects - a guide
 
Prezentacja firmy XSolve - programowanie, e-commerce, bodyleasing
Prezentacja firmy XSolve - programowanie, e-commerce, bodyleasingPrezentacja firmy XSolve - programowanie, e-commerce, bodyleasing
Prezentacja firmy XSolve - programowanie, e-commerce, bodyleasing
 
Dlaczego git to nie svn oraz dlaczego to dobrze ?
Dlaczego git to nie svn oraz dlaczego to dobrze ?Dlaczego git to nie svn oraz dlaczego to dobrze ?
Dlaczego git to nie svn oraz dlaczego to dobrze ?
 
Programowanie zorientowane aspektowo
Programowanie zorientowane aspektowoProgramowanie zorientowane aspektowo
Programowanie zorientowane aspektowo
 
Agile estimating and planning
Agile estimating and planningAgile estimating and planning
Agile estimating and planning
 
Tailoring of PRINCE2
Tailoring of PRINCE2Tailoring of PRINCE2
Tailoring of PRINCE2
 
Mongo db baza danych zorientowana dokumentowo
Mongo db  baza danych zorientowana dokumentowo Mongo db  baza danych zorientowana dokumentowo
Mongo db baza danych zorientowana dokumentowo
 
Debugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebugDebugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebug
 
Zarządzanie projektami w XSolve
Zarządzanie projektami w XSolveZarządzanie projektami w XSolve
Zarządzanie projektami w XSolve
 

Kürzlich hochgeladen

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 

Kürzlich hochgeladen (20)

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 

PHPCon 2016: PHP7 by Witek Adamus / XSolve

  • 1. Witek Adamus PHPCon 2016, Rawa Mazowiecka
  • 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. ❏ What can functional programming bring to the table? ❏ When language can be described as functional? Table of content
  • 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
  • 9. 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; }
  • 10. 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(); }
  • 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; } 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(); }
  • 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)
  • 14. No side effects? Immutability? :(
  • 16. Lambda Calculus ƛ(x) = z ❏ Higher-order functions ❏ Currying
  • 17. Functional vs Object oriented programming ?
  • 18.
  • 19. PHP7 is functional …but is dirty and salty as well
  • 20. What do I miss in PHP7 that Scala luckily has?
  • 21. ❏ Immutability by default ❏ Objects cloning ❏ Options ❏ Either ❏ Future ❏ Parallel collections ❏ Tail recurrency ❏ Generic types ❏ Arrow functions ❏ Pattern matching / case classes
  • 22. Few rules to make your code functional
  • 23. Do not use ❏ reassignments ❏ if ❏ null ❏ for ❏ foreach
  • 24. Do not use ❏ reassignments
  • 25. $bigHouse = new Building(5); $smallerHouse = $bigHouse->setFloors(2); echo $bigHouse->getFloors() . PHP_EOL; echo $smallerHouse->getFloors() . PHP_EOLl;
  • 26. $bigHouse = new Building(5); $smallerHouse = $bigHouse->setFloors(2); echo $bigHouse->getFloors() . PHP_EOL; //2 echo $smallerHouse->getFloors() . PHP_EOLl; //2
  • 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); } }
  • 29. $bigHouse = new Building(5); $smallerHouse = $bigHouse->withFloors(2); echo $bigHouse->getFloors() . PHP_EOL; //5 echo $smallerHouse->getFloors() . PHP_EOLl; //2
  • 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); } }
  • 32. Few rules to make your code functional
  • 33. Do not use :) reassignments ❏ if ❏ null ❏ for ❏ foreach
  • 35. Do not use :) reassignments ❏ if ❏ null ❏ for ❏ foreach ?
  • 36. Do not use :) reassignments ❏ if ❏ null ❏ for ❏ foreach Option
  • 37. Option Monad which may contain something or nothing
  • 38. What is a monad? Option
  • 48. 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); } }
  • 49. 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)); }
  • 50. 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)); }
  • 52. public function displayNameForUser(string $email) : string { $this ->userRepository ->findByEmail($email) ->get() ->getFirstName(); }
  • 53. public function displayNameForUser(string $email) : string { $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->firstName; }) ->getOrElse('oh my'); }
  • 54. public function displayNameForUser(string $email) : ??? { $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->getFirstName(); }); }
  • 55. public function displayNameForUser(string $email) : ??? { $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->getFirstName(); }); } ?
  • 56. public function displayNameForUser(string $email) : ??? { $this ->userRepository ->findByEmail($email) ->map(function (User $user) { return $user->getFirstName(); }); } Option<Option<String>>
  • 57. public function displayNameForUser(string $email) : Option { $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }); }
  • 58. public function displayNameForUser(string $email) : string { $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrElse($email); }
  • 59. public function displayNameForUser(string $email) : string { $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall(function () use ($email) { $this->getAlternative($email); }); }
  • 60. public function displayNameForUser(string $email) : string { $this ->userRepository ->findByEmail($email) ->flatMap(function (User $user) { return $user->getFirstName(); }) ->getOrCall($this->getAlternative($email)); }
  • 61. 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); }; }
  • 62. Few rules to make your code functional
  • 63. Do not use :) reassignments :) if :) null ❏ for ❏ foreach
  • 65. 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); }; }
  • 66. public function displayNameForUser(string $email) : string { $this ->userRepository ->findByEmail($email) ->flatMap((User $user) => $user->getFirstName()) ->getOrCall(() => $this->doSomethingElseWith($email)) } :(
  • 68. public function maybeSomething(string $email) : Option { ... }
  • 69. public function maybeSomething(string $email) : Option<string> { ... }
  • 70. 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 :(
  • 71. /** * @return Option<string> */ public function maybeSomething(string $email) : Option { ... } https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md :(
  • 72. What do I miss in PHP7 that Scala luckily has?
  • 73. :) Immutability by default :) Objects cloning :) Options ❏ Either ❏ Future ❏ Parallel collections ❏ Tail recurrency :( Generic types :( Arrow functions ❏ Pattern matching / case classes
  • 76. Either Either RightLeft left(Closure $expr): Either right(Closure $expr): Either get() left(Closure $expr): Either right(Closure $expr): Either get()
  • 77. 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); } }
  • 78. 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
  • 79. 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>
  • 80. 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(); }
  • 81. 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())); }
  • 82. 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())); }; }
  • 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
  • 86. 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(); }
  • 87. 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) => NotFound case Left(UserService.VersioningMissmatch) => NotAcceptable case Left(UserService.NoModificationsAllowed) => Locked case Left(UserService.InvalidPayload) => BadRequest } }
  • 88. What do I miss in PHP7 that Scala luckily has?
  • 89. :) Immutability by default :) Objects cloning :) Options :) Either ❏ Future ❏ Parallel collections ❏ Tail recurrency :( Generic types :( Arrow functions :)/:( Pattern matching / case classes
  • 91. public function multiplyBy( array $input, float $multiplication): array { $output = []; foreach($input as $number) { $output[] = $number * $multiplication; } return $output; }
  • 92. use PhpSlangCollectionListCollection; ... public function beautifulMultiplyBy( array $input, float $multiplication) : ListCollection { return (new ListCollection($input)) ->map(function ($number) use ($multiplication) { return $number * $multiplication; }); }
  • 93. public function multiplyOddsBy( array $input, float $multiplication): array { $output = []; foreach ($input as $number) { if ($number % 2 !== 0) { $output[] = $number * $multiplication; } } return $output; }
  • 94. 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; }); }
  • 95. public function accumulatedText(array $words) : string { $text = ''; foreach ($words as $word) { $text .= $word . ' '; } return $text; }
  • 96. public function accumulatedText(array $words) : string { return (new ListCollection($words)) ->fold('', function (string $acumulator, string $word) { return $acumulator . $word . ' '; }); }
  • 97.
  • 99. Few rules to make your code functional
  • 100. Do not use :) reassignments :) if :) null :) for :) foreach
  • 102.
  • 103.
  • 104. Future
  • 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ć?
  • 111. Future & Parallel collections
  • 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?
  • 121. :) Immutability by default :) Objects cloning :) Options :) Either :)/:( Future :) Parallel collections ❏ Tail recurrency :( Generic types :( Arrow functions :)/:( Pattern matching / case classes
  • 123. 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); }
  • 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); } echo fibonacci(123123123123); Fatal error: Maximum function nesting level of '...' reached, aborting!
  • 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?
  • 137. :) Immutability by default :) Objects cloning :) Options :) Either :)/:( Future :) Parallel collections :) Tail recurrency :( Generic types :( Arrow functions :)/:( Pattern matching / case classes
  • 138.
  • 139. Conclusions ● Don’t be afraid of monads ● Don’t set traps for your team ● Learn Haskell, Clojure, Scala, F#, JavaScript -> TypeScript