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

Functional programming: basic concepts you can ...

Functional programming: basic concepts you can start using today

Thiago Colares

May 14, 2021
Tweet

More Decks by Thiago Colares

Other Decks in Programming

Transcript

  1. FUNCTIONAL PROGRAMMING Basic concepts you can start using today Thiago

    Colares, 2021-05-14. Montréal, Québec, Canada.
  2. 2

  3. What is functional programming? ▪ It's a programming paradigm. ▪

    Treat functions as mathematical ones: pure functions. ▪ No hidden IOs; avoid state and side effects. ▪ No pure functional programming language is needed. 4
  4. A function in Math It's a mapping from a set

    of inputs x to a set of outputs y. 1. Each input x is mapped to exactly one and only one y. 2. y depends solely and exclusively on x. 5
  5. 7 1. The output depends only on the input. 2.

    No side effects. It does NOT: - modify the global state; - launch a missile; - modify the input; etc... A code function as in Math: Pure Functions.
  6. What are the benefits? ▪ Fewer side effects → fewer

    bugs ▪ Output only depends on arguments → easier tests ▪ Inputs and outputs are explicit → easier maintenance ▪ More reuse and composition → faster coding 9
  7. Fewer side effects. Fewer bugs. class Calendar { public $defaultInterval

    = "P1D"; // ... function addOneDay($date) { return $date->add(new DateInterval($this->defaultInterval)); } } 11 class Calendar { // ... function addOneDay($date) { return (clone $date)->add(new DateInterval("P1D")); } } $now = new DateTime; // 2021-05-05 // ... $nowAddedInOneDay = $calendar->addOneDay($now); // $nowAddedInOneDay: 2021-05-06. Fine! // $now: 2021-05-06. Wait, waat?
  8. Output only depends on arguments. Easier tests. 12 class Calendar

    { public $defaultInterval = "P1D"; // ... function addOneDay($date) { return $date->add(new DateInterval($this->defaultInterval)); } } class Calendar { // ... function addOneDay($date) { return $date->add(new DateInterval("P1D")); } } $calendar->defaultInterval = 'P2D'; // oops! //... $now = new DateTime; // Value: 2021-05-05. $nowAddedInOneDay = $calendar->addOneDay($now); // Result: 2021-05-07. Expected: 2021-05-06.
  9. Inputs and outputs are explicit. Easier maintenance. 13 class Calendar

    { public $defaultInterval = "P1D"; // ... function addOneDay($date) { return $date->add(new DateInterval($this->defaultInterval)); } } class Calendar { // ... function addOneDay($date) { return $date->add(new DateInterval("P1D")); } } class Calendar { // ... function addInterval($date, $durationIso) { return $date->add(new DateInterval($durationIso)); } } $calendar->defaultInterval = 'P2D'; // oops! //... $now = new DateTime; // Value: 2021-05-05. $nowAddedInOneDay = $calendar->addOneDay($now); // Result: 2021-05-07. Expected: 2021-05-06.
  10. public function render($request, \Exception $exception) { $code = null; //

    ... switch (true) { case $exception instanceof ApplicationException: $code = Response::HTTP_BAD_REQUEST; // ... case $exception instanceof NotFoundHttpException: $code = Response::HTTP_NOT_FOUND; // ... // ... 82 lines } return response()->json( // ... $code ); } 15 What if something else modifies $code in between?
  11. public function render($request, \Exception $exception) { $code = null; //

    ... switch (true) { case $exception instanceof ApplicationException: $code = Response::HTTP_BAD_REQUEST; // ... case $exception instanceof NotFoundHttpException: $code = Response::HTTP_NOT_FOUND; // ... // ... 82 lines } return response()->json( // ... $code ); } 16 public function render($request, \Exception $exception) { //... if ($exception instanceof ApplicationException) { return response()->json(//..., Response::HTTP_BAD_REQUEST); } //... if ($exception instanceof NotFoundHttpException) { return response()->json(//..., Response::HTTP_NOT_FOUND); } // ... 82 lines } No state, no aux vars needed here.
  12. This is the tip of the iceberg 18 Referential transparency

    Lambda expressions Monads Immutability Recursion map(), reduce(), filter() Parametric polymorphism Currying Closures Functors
  13. Conclusions ▪ Pure functions: no state, no side effects, explicit

    IOs. ▪ Fewer side effects → fewer bugs ▪ Output only depends on arguments → easier tests ▪ Inputs and outputs are explicit → easier maintenance ▪ More reuse and composition → faster coding ▪ There are no silver bullets. Use them when it makes sense. 19
  14. “ Explicit is better than implicit. Flat is better than

    nested. If the implementation is hard to explain, it’s a bad idea. If the implementation is easy to explain, it may be a good idea. The Zen of Python. 20