Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional approach in software design

Functional approach in software design

Functional programming is a paradigm known for decades. It is gaining popularity again, due to the rise of purely functional languages like Haskell. You may wonder, how it could be useful in PHP? Using a few techniques and a slight change of perspective you will be able to write code that is cleaner and easier to understand. You will be able to design and implement huge solutions by composing them from small and well-tested parts.

Tomasz Kowalczyk

March 08, 2018
Tweet

More Decks by Tomasz Kowalczyk

Other Decks in Programming

Transcript

  1. $result = []; foreach($this->users as $user) { if($user->isDisabled()) { continue;

    } if($user->isHidden()) { continue; } $result[] = $user; } return $result;
  2. $result = []; foreach($this->users as $user) { if($user->isDisabled()) { continue;

    } if($user->isHidden()) { continue; } $result[] = $user; } return $result;
  3. $isEnabled = function(User $u): bool { return false === $u->isDisabled();

    }; $isVisible = function(User $u): bool { return false === $u->isHidden(); }; return array_filter( array_filter($this->users, $isVisible), $isEnabled);
  4. $isEnabled = function(User $u): bool { return false === $u->isDisabled();

    }; $isVisible = function(User $u): bool { return false === $u->isHidden(); }; return $this->users ->filter($isVisible) ->filter($isEnabled);
  5. $ids = []; foreach($this->users as $user) { foreach($user->getTags() as $tag)

    { $tagId = $tag->getId(); if(false === in_array($tagId, $ids, true)) { $ids[] = $tagId; } } } return $ids;
  6. $ids = []; foreach($this->users as $user) { foreach($user->getTags() as $tag)

    { $tagId = $tag->getId(); if(false === in_array($tagId, $ids, true)) { $ids[] = $tagId; } } } return $ids;
  7. $userToTags = function(User $user): array { return $user->getTags(); }; $tagToId

    = function(Tag $tag): int { return $tag->getId(); }; return array_unique(array_map($tagToId, array_merge( ...array_map($userToTags, $this->users) )));
  8. $userToTags = function(User $user): array { return $user->getTags(); }; $tagToId

    = function(Tag $tag): int { return $tag->getId(); }; return $this->users ->flatMap($userToTags) ->map($tagToId) ->unique();
  9. $addPoints = function(int $state, User $user): int { return $state

    + $user->getPoints(); }; return array_reduce($this->users, $addPoints, 0);
  10. $addPoints = function(int $state, User $user): int { return $state

    + $user->getPoints(); }; return $this->users ->reduce($addPoints, 0);
  11. $isEnabled = function(User $u): bool { return !$u->isDisabled(); }; $isVisible

    = function(User $user): bool { return !$u->isHidden(); }; $userToPoints = function(User $user): int { return $user->getPoints(); }; $addPoints = function(int $st, User $u): int { return $st + $u->getPoints(); }; return $this->users ->filter($isEnabled) ->filter($isVisible) ->map($userToPoints) ->reduce($addPoints, 0);
  12. $isEnabled = function(User $u): bool { return !$u->isDisabled(); }; $isVisible

    = function(User $user): bool { return !$u->isHidden(); }; $userToPoints = function(User $user): int { return $user->getPoints(); }; $addPoints = function(int $st, User $u): int { return $st + $u->getPoints(); }; return $this->users ->filter($isEnabled) ->filter($isVisible) ->map($userToPoints) ->reduce($addPoints, 0);
  13. entry | input → request routing | request → route

    controller | controller → response events | request → request | response → response forms | data → mapping validation | data → violations
  14. $s = new Serializard($normalizers, $hydrators, $formats); $user = new User(1337,

    '[email protected]'); $json = $s->serialize($user, 'json'); $user = $s->unserialize($json, 'json', User::class);
  15. $processor = new Processor($parser, $handlers); $text = 'This is a

    [b]bold text[/b].'; $result = $processor->process($text);