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

Curing the Common Loop

Curing the Common Loop

Trying to understand a complex function full of nested loops and conditionals is like trying to read a "choose your own adventure" book from front to back.

In this whirlwind tour of programming with collection pipelines, you'll learn how to use functional programming ideas to break down complex code and abstract hidden duplication behind expressive higher order functions.

Together we'll refactor ugly, complicated spaghetti into a series of simple, elegant transformations; free of loops, complex conditionals, and temporary variables.

Adam Wathan

July 29, 2016
Tweet

More Decks by Adam Wathan

Other Decks in Programming

Transcript

  1. $totalRevenue = 0; $minSales = 75000; foreach ($employees as $employee)

    { $employeeType = $employee->getType(); if ($employeeType == 'Sales') { $customers = $employee->getCustomers(); foreach ($customers as $customer) { $customerTotalSales = 0; foreach ($customer->getOrders() as $order) { $customerTotalSales += $order->total; } if ($customerTotalSales >= $minSales) { $totalRevenue += $customerTotalSales; } } } } return $totalRevenue;
  2. $stockTotals = []; foreach ($inventoryItems as $item) { $stockTotals[] =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; } return $stockTotals;
  3. $customerEmails = []; foreach ($customers as $customer) { $email =

    $customer->email; $customerEmails[] = $email; } return $customerEmails;
  4. $stockTotals = []; foreach ($inventoryItems as $item) { $stockTotals[] =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; } return $stockTotals;
  5. $stockTotals = []; foreach ($inventoryItems as $item) { $stockTotal =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; $stockTotals[] = $stockTotal; } return $stockTotals;
  6. $stockTotals = []; foreach ($inventoryItems as $item) { $stockTotal =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; $stockTotals[] = $stockTotal; } return $stockTotals;
  7. $results = []; foreach ($items as $item) { $result =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; $results[] = $result; } return $results;
  8. $results = []; foreach ($items as $item) { $result =

    $item->email; $results[] = $result; } return $results;
  9. $results = []; foreach ($items as $item) { $result =

    $item->email; $results[] = $result; } return $results;
  10. $callback = function ($item) { return $item->email; }; $results =

    []; foreach ($items as $item) { $result = $callback($item); $results[] = $result; } return $results;
  11. $results = []; foreach ($items as $item) { $result =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; $results[] = $result; } return $results;
  12. $callback = function ($item) { return [ 'product' => $item->productName,

    'total_value' => $item->quantity * $item->price, ]; }; $results = []; foreach ($items as $item) { $result = $callback($item); $results[] = $result; } return $results;
  13. $callback = function ($item) { return [ 'product' => $item->productName,

    'total_value' => $item->quantity * $item->price, ]; }; $results = []; foreach ($items as $item) { $result = $callback($item); $results[] = $result; } return $results;
  14. $callback = function ($item) { return $item->email; }; $results =

    []; foreach ($items as $item) { $result = $callback($item); $results[] = $result; } return $results;
  15. function array_map($callback, $items) { } $results = []; foreach ($items

    as $item) { $result = $callback($item); $results[] = $result; } return $results;
  16. $stockTotals = []; foreach ($inventoryItems as $item) { $stockTotals[] =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; } return $stockTotals;
  17. $stockTotals = []; foreach ($inventoryItems as $item) { $stockTotals[] =

    [ 'product' => $item->productName, 'total_value' => $item->quantity * $item->price, ]; } return $stockTotals;
  18. $stockTotals = array_map(function ($inventoryItem) { return [ 'product' => $item->productName,

    'total_value' => $item->quantity * $item->price, ]; }, $inventoryItems);
  19. $outOfStockProducts = []; foreach ($products as $product) { if ($product->isOutOfStock())

    { $outOfStockProducts[] = $product; } } return $outOfStockProducts;
  20. $expensiveProducts = []; foreach ($products as $product) { if ($product->price

    > 100) { $expensiveProducts[] = $product; } } return $expensiveProducts;
  21. $results = []; foreach ($items as $item) { if ($item->price

    > 100) { $results[] = $item; } } return $results;
  22. $outOfStockProducts = []; foreach ($products as $product) { if ($product->isOutOfStock())

    { $outOfStockProducts[] = $product; } } return $outOfStockProducts;
  23. $results = []; foreach ($items as $item) { if ($item->price

    > 100) { $results[] = $item; } } return $results;
  24. $callback = function ($item) { return $item->price > 100; };

    $results = []; foreach ($items as $item) { if ($callback($item)) { $results[] = $item; } } return $results;
  25. $callback = function ($item) { return $item->isOutOfStock(); }; $results =

    []; foreach ($items as $item) { if ($callback($item)) { $results[] = $item; } } return $results;
  26. $callback = function ($item) { return $item->isOutOfStock(); }; $results =

    []; foreach ($items as $item) { if ($callback($item)) { $results[] = $item; } } return $results;
  27. $callback = function ($item) { return $item->price > 100; };

    $results = []; foreach ($items as $item) { if ($callback($item)) { $results[] = $item; } } return $results;
  28. function array_filter($items, $callback) { $results = []; foreach ($items as

    $item) { if ($callback($item)) { $results[] = $item; } } return $results; } $results = []; foreach ($items as $item) { if ($callback($item)) { $results[] = $item; } } return $results;
  29. $outOfStockProducts = []; foreach ($products as $product) { if ($product->isOutOfStock())

    { $outOfStockProducts[] = $product; } } return $outOfStockProducts;
  30. $expensiveProducts = []; foreach ($products as $product) { if ($product->price

    > 100) { $expensiveProducts[] = $product; } } return $expensiveProducts;
  31. function getSalesEmails($employees) { $emails = []; foreach ($employees as $employee)

    { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  32. function getSalesEmails($employees) { $emails = []; foreach ($employees as $employee)

    { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; } …map?
  33. function getSalesEmails($employees) { $emails = []; foreach ($employees as $employee)

    { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  34. function getSalesEmails($employees) { $emails = []; foreach ($employees as $employee)

    { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  35. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($employees as $employee) { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  36. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($employees as $employee) { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  37. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($employees as $employee) { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  38. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($salesEmployees as $employee) { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  39. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($salesEmployees as $employee) { if ($employee->department === 'Sales') { $emails[] = $employee->email; } } return $emails; }
  40. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($salesEmployees as $employee) { $emails[] = $employee->email; } return $emails; }
  41. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($salesEmployees as $employee) { $emails[] = $employee->email; } return $emails; }
  42. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($salesEmployees as $employee) { $emails[] = $employee->email; } return $emails; } Map!
  43. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = []; foreach ($salesEmployees as $employee) { $emails[] = $employee->email; } return $emails; }
  44. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  45. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  46. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  47. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  48. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  49. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  50. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); return array_map(function ($employee) { return $employee->email; }, $salesEmployees); }
  51. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); return array_map(function ($employee) { return $employee->email; }, $salesEmployees); }
  52. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); return array_map(function ($employee) { return $employee->email; }, $salesEmployees); }
  53. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); return array_map(function ($employee) { return $employee->email; }, $salesEmployees); }
  54. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); return array_map(function ($employee) { return $employee->email; }, array_filter($employees, function ($employee) { return $employee->department == 'Sales'; })); }
  55. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); return array_map(function ($employee) { return $employee->email; }, array_filter($employees, function ($employee) { return $employee->department == 'Sales'; })); }
  56. function getSalesEmails($employees) { return array_map(function ($employee) { return $employee->email; },

    array_filter($employees, function ($employee) { return $employee->department == 'Sales'; })); }
  57. # => hello_there_laracon function toCamelCase($snakeString) { return lcfirst( str_replace(' ',

    '', ucwords(str_replace('_', ' ', $snakeString)) ) ); } # => helloThereLaracon
  58. # => hello_there_laracon function toCamelCase($snakeString) { return $snakeString->replace('_', ' ')

    ->ucwords() ->replace(' ', '') ->lcfirst(); } # => helloThereLaracon
  59. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  60. function getSalesEmails($employees) { $salesEmployees = array_filter($employees, function ($employee) { return

    $employee->department == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  61. function getSalesEmails($employees) { $salesEmployees = $employees->filter(function ($employee) { return $employee->department

    == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  62. function getSalesEmails($employees) { $salesEmployees = $employees->filter(function ($employee) { return $employee->department

    == 'Sales'; }); $emails = array_map(function ($employee) { return $employee->email; }, $salesEmployees); return $emails; }
  63. function getSalesEmails($employees) { $salesEmployees = $employees->filter(function ($employee) { return $employee->department

    == 'Sales'; }); $emails = $salesEmployees->map(function ($employee) { return $employee->email; }); return $emails; }