SlideShare ist ein Scribd-Unternehmen logo
1 von 32
Downloaden Sie, um offline zu lesen
FORGET ABOUT LOOPS
DUŠAN KASAN
FORGET ABOUT LOOPSDUŠAN KASAN
github.com/DusanKasan
@DusanKasan
me@dusankasan.com
FORGET ABOUT LOOPSDUŠAN KASAN
What it’ll be about
• The problem
• Functional programming
• Collection pipelines
• Collection pipelines in PHP
Problem | FP | Collection Pipelines | PHP
What’s the problem?
$output .= "function {$properties['unifunc']} (Smarty_Internal_Template $_smarty_tpl) {n";

// include code for plugins

if (!$cache) {

if (!empty($_template->compiled->required_plugins[ 'compiled' ])) {

foreach ($_template->compiled->required_plugins[ 'compiled' ] as $tmp) {

foreach ($tmp as $data) {

$file = addslashes($data[ 'file' ]);

if (is_array($data[ 'function' ])) {

$output .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';n";

} else {

$output .= "if (!is_callable('{$data['function']}')) require_once '{$file}';n";

}

}

}

}

if ($_template->caching && !empty($_template->compiled->required_plugins[ 'nocache' ])) {

$_template->compiled->has_nocache_code = TRUE;

$output .= "echo '/*%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/<?php $_smarty = $_smarty_tpl->smarty; ";

foreach ($_template->compiled->required_plugins[ 'nocache' ] as $tmp) {

foreach ($tmp as $data) {

$file = addslashes($data[ 'file' ]);

if (is_array($data[ 'function' ])) {

$output .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file
} else {

$output .= addslashes("if (!is_callable('{$data['function']}')) require_once '{$file}';n");

}

}

}

$output .= "?>/*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/';n";

}

}

smarty_internal_runtime_codeframe.php
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Let’s boil it down[

{

"id": 1,

"username": "john",

"verified": true,

"posts": [

{

"body": "Hi I'm John.",

"likes": [2, 3, 5]

},

{

"body": "I hate this site.",

"likes": []

}

]

},

{

"id": 2,

"username": "tom",

"verified": false,

"posts": []

},

{

"id": 3,

"username": "jane",

"verified": true,

"posts": [

{

"body": "Hi I'm Jane.",

"likes": [4, 5]

}

]

}

]

{

"1": [

{

"body": "Hi I'm John.",

"likes": [2, 3, 5]

}

],

"3": [

{

"body": "Hi I'm jane.",

"likes": [4, 5]

}

]

}
=>
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Let’s boil it down
$likedPosts = [];



foreach ($users as $user) {

if ($user['verified']) {

$userId = $user['id'];



foreach ($user['posts'] as $post) {

if (count($post['likes'])) {

$likedPosts[$userId][] = $post;

}

}

}

}
4 levels of nesting
Harder to follow / cognitive load
Too much memorization
Refactoring candidate
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Refactoring - extract more functions
$likedPosts = [];



foreach ($users as $user) {

if ($user['verified']) {

$userId = $user['id'];



foreach ($user['posts'] as $post) {

if (count($post['likes'])) {

$likedPosts[$userId][] = $post;

}

}

}

} private function getLikedPosts(array $posts)

{

$likedPosts = [];

foreach ($posts as $post) {

if (count($post['likes'])) {

$likedPosts[] = $post;

}

}



return $likedPosts;

}
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Refactoring - extract more functions
$likedPosts = [];





foreach ($users as $user) {

$likedPosts = $this->getLikedPosts($user['posts']);



if ($user['verified'] && count($likedPosts)) {

$likedPosts[$user['id']] = $likedPosts;

}

}
• Pretty good solution
• The new function name carries the meaning of the logic
• Enough for quick understanding
• For real understanding, we’ll hop between functions
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Refactoring - built-in array functions
$indexedUsers = [];

foreach ($users as $user) {

$indexedUsers[$user['id']] = $user;

}
$verifiedUsers = array_filter(

$indexedUsers,

function ($user) {

return $user['verified'];

}

);
$likedPosts = array_map(

function($verifiedUser) {

return array_filter(

$verifiedUser['posts'],

function($post) {return count($post['likes']);}

);

},

$verifiedUsers

);
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Refactoring - built-in array functions
( °□°) ︵
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Refactoring - built-in array functions
$indexedUsers = [];

foreach ($users as $user) {

$indexedUsers[$user['id']] = $user;

}
$verifiedUsers = array_filter(

$indexedUsers,

function ($user) {

return $user['verified'];

}

);
$likedPosts = array_map(

function($verifiedUser) {

return array_filter(

$verifiedUser['posts'],

function($post) {return count($post['likes']);}

);

},

$verifiedUsers

);
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming buzzwords
Immutability
No side effects
Higher-order functions
ConcurrencyParallelism
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming buzzwords
Immutability
function withName(User $user, $name) {

$result = User::from($user);

$result->setName($name);



return $result;

}



$tim = new User(1, ’tim', ....);

$tom = withName($tim, 'tom');



echo $tim->getName(); //'tim'

echo $tom->getName(); //'tom'
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
class User

{

...



public function withName($name)

{

return new self($this->getId(), $name, ...);

}

}
Functional programming buzzwords
Immutability
No side effects
Higher-order functions
ConcurrencyParallelism
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming buzzwords
No side effects
$anotherTry = function ($a, $b, $c) {

return $a . $b . $c;

};



$a = $anotherTry(
$randomObscureThing,
$_REQUEST['absolutely_safe'],
DateTime::ATOM
);

$totallyNoSideEffectsHere = function () use ($randomObscureThing) {

return $randomObscureThing . $_REQUEST['absolutely_safe'] . DateTime::ATOM;

};



$a = $totallyNoSideEffectsHere();
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming buzzwords
Immutability
No side effects
Higher-order functions
ConcurrencyParallelism
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming buzzwords
Higher-order functions
function show(callable $c) {

echo $c();

}



function style(callable $c) : callable {

return function () use ($c) {

return '**' . $c() . '**';

};

}



$nameProvider = function () {

return 'John';

};



show($nameProvider); //John

show(style($nameProvider)); //**John**

FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming buzzwords
Immutability
No side effects
Higher-order functions
ConcurrencyParallelism
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Functional programming buzzwords
ConcurrencyParallelism
getOrderDetails(

getOrderById($id),

getPaymentByOrderId($id)

);
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Collection Pipelines
( - )
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Collection Pipelines
• What are collections?
• Group of values or key, value pairs
• Think arrays or Traversables
• Collection pipeline
• Design pattern
• Sequential operations on collections
• Operations e.g.: filter, map or reduce
• Used by both FP and OOP languages
• Immutable, lazy, concurrent
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Simple explanation
map([🌽, 🐮, 🐔], cook) => [🍿, 🍔, 🍳]
filter([🍿, 🍔, 🍳], isVegetarian) => [🍿, 🍳]
reduce([🍿, 🍳], eat) => 💩
From a tweet by @steveluscher
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Simple explanation
[🌽, 🐮, 🐔]
.map(cook) // [🍿, 🍔, 🍳]
.filter(isVegetarian) // [🍿, 🍳]
.reduce(eat) // 💩
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Collection pipeline operations
append, combine, concat, contains, countBy, cycle, diff, distinct,
drop, dropLast, dropWhile, each, every, except, extract, filter, find,
first, flatten, flip, frequencies, get, getOrDefault, groupBy,
groupByKey, has, indexBy, interleave, interpose, intersect, isEmpty,
isNotEmpty, keys, last, map, mapcat, only, partition, partitionBy,
prepend, realize, reduce, reduceRight, reductions, reject, replace,
reverse, second, shuffle, size, slice, some, sort, splitAt, splitWith,
take, takeNth, takeWhile, transform, toArray, zip,
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
The original problem[

{

"id": 1,

"username": "john",

"verified": true,

"posts": [

{

"body": "Hi I'm John.",

"likes": [2, 3, 5]

},

{

"body": "I hate this site.",

"likes": []

}

]

},

{

"id": 2,

"username": "tom",

"verified": false,

"posts": []

},

{

"id": 3,

"username": "jane",

"verified": true,

"posts": [

{

"body": "Hi I'm Jane.",

"likes": [4, 5]

}

]

}

]

{

"1": [

{

"body": "Hi I'm John.",

"likes": [2, 3, 5]

}

],

"3": [

{

"body": "Hi I'm jane.",

"likes": [4, 5]

}

]

}
=>
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Refactoring - Collections
$likedPosts = [];



foreach ($users as $user) {

if ($user['verified']) {

$userId = $user['id'];



foreach ($user['posts'] as $post) {

if (count($post['likes'])) {

$likedPosts[$userId][] = $post;

}

}

}

}
$likedPosts = Collection::from($users)

->filter(function ($user) {return $user['verified'];})

->indexBy(function($user) {return $user['id'];})

->map(function($user) {

return Collection::from($user['posts'])

->filter(function($post) {return count($post['likes']);});

})

->reject(function($posts) {return isEmpty($posts);});
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
When to use collection pipelines
• Where you work with collections?
• API
• Import CSV
• Any nontrivial collection based work
• Refactoring of current code base to for comprehension
Drawbacks?
• Function call overhead
• You have to understand it :)
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Collection pipelines in PHP
• CakePHP Collection (github.com/cakephp/collection)
• Laravel Collections (github.com/illuminate/support)
• PHP-Collection (github.com/emonkak/php-collection)
• Knapsack (github.com/DusanKasan/Knapsack)
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
PHP’s shortcomings
$collection->map(function($item) {return $item->field;});
$collection->map($item ~> $item->field);
$collection->map(function($item) {

return $item->field;

});
$collection->map(function($item) => $item->field);
RFC targeting PHP 7.1
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
Interested?
• Martin Fowler (martinfowler.com)
• Adam Wathan (adamwathan.me/refactoring-to-collections)
• Documentation and tests to the mentioned libraries
FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
FORGET ABOUT LOOPS
DUŠAN KASAN

Weitere ähnliche Inhalte

Was ist angesagt?

News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.VimLin Yo-An
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsMark Baker
 
Trading with opensource tools, two years later
Trading with opensource tools, two years laterTrading with opensource tools, two years later
Trading with opensource tools, two years laterclkao
 
Class 4 - PHP Arrays
Class 4 - PHP ArraysClass 4 - PHP Arrays
Class 4 - PHP ArraysAhmed Swilam
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)Nikita Popov
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type Systemabrummett
 

Was ist angesagt? (20)

Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
Trading with opensource tools, two years later
Trading with opensource tools, two years laterTrading with opensource tools, two years later
Trading with opensource tools, two years later
 
Introduction to php
Introduction to phpIntroduction to php
Introduction to php
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
Class 4 - PHP Arrays
Class 4 - PHP ArraysClass 4 - PHP Arrays
Class 4 - PHP Arrays
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
ReUse Your (Puppet) Modules!
ReUse Your (Puppet) Modules!ReUse Your (Puppet) Modules!
ReUse Your (Puppet) Modules!
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 

Ähnlich wie Forget about loops

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
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2Elizabeth Smith
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3Nate Abele
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceIvan Chepurnyi
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python DevelopersCarlos Vences
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrowPete McFarlane
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Creating and Maintaining WordPress Plugins
Creating and Maintaining WordPress PluginsCreating and Maintaining WordPress Plugins
Creating and Maintaining WordPress PluginsMark Jaquith
 
Power shell voor developers
Power shell voor developersPower shell voor developers
Power shell voor developersDennis Vroegop
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Ioc container | Hannes Van De Vreken | CODEiD
Ioc container | Hannes Van De Vreken | CODEiDIoc container | Hannes Van De Vreken | CODEiD
Ioc container | Hannes Van De Vreken | CODEiDCODEiD PHP Community
 

Ähnlich wie Forget about loops (20)

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
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Functional programming with php7
Functional programming with php7Functional programming with php7
Functional programming with php7
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 
Intermediate PHP
Intermediate PHPIntermediate PHP
Intermediate PHP
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python Developers
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrow
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Creating and Maintaining WordPress Plugins
Creating and Maintaining WordPress PluginsCreating and Maintaining WordPress Plugins
Creating and Maintaining WordPress Plugins
 
Power shell voor developers
Power shell voor developersPower shell voor developers
Power shell voor developers
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Ioc container | Hannes Van De Vreken | CODEiD
Ioc container | Hannes Van De Vreken | CODEiDIoc container | Hannes Van De Vreken | CODEiD
Ioc container | Hannes Van De Vreken | CODEiD
 

Kürzlich hochgeladen

Input Output Management in Operating System
Input Output Management in Operating SystemInput Output Management in Operating System
Input Output Management in Operating SystemRashmi Bhat
 
Theory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfTheory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfShreyas Pandit
 
Virtual memory management in Operating System
Virtual memory management in Operating SystemVirtual memory management in Operating System
Virtual memory management in Operating SystemRashmi Bhat
 
Novel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsNovel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsResearcher Researcher
 
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONTHE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONjhunlian
 
Main Memory Management in Operating System
Main Memory Management in Operating SystemMain Memory Management in Operating System
Main Memory Management in Operating SystemRashmi Bhat
 
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.elesangwon
 
70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical training70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical trainingGladiatorsKasper
 
11. Properties of Liquid Fuels in Energy Engineering.pdf
11. Properties of Liquid Fuels in Energy Engineering.pdf11. Properties of Liquid Fuels in Energy Engineering.pdf
11. Properties of Liquid Fuels in Energy Engineering.pdfHafizMudaserAhmad
 
Energy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptxEnergy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptxsiddharthjain2303
 
List of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdfList of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdfisabel213075
 
Robotics Group 10 (Control Schemes) cse.pdf
Robotics Group 10  (Control Schemes) cse.pdfRobotics Group 10  (Control Schemes) cse.pdf
Robotics Group 10 (Control Schemes) cse.pdfsahilsajad201
 
Python Programming for basic beginners.pptx
Python Programming for basic beginners.pptxPython Programming for basic beginners.pptx
Python Programming for basic beginners.pptxmohitesoham12
 
Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...
Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...
Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...Erbil Polytechnic University
 
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.pptROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.pptJohnWilliam111370
 
『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书
『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书
『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书rnrncn29
 
Prach: A Feature-Rich Platform Empowering the Autism Community
Prach: A Feature-Rich Platform Empowering the Autism CommunityPrach: A Feature-Rich Platform Empowering the Autism Community
Prach: A Feature-Rich Platform Empowering the Autism Communityprachaibot
 
Artificial Intelligence in Power System overview
Artificial Intelligence in Power System overviewArtificial Intelligence in Power System overview
Artificial Intelligence in Power System overviewsandhya757531
 
Turn leadership mistakes into a better future.pptx
Turn leadership mistakes into a better future.pptxTurn leadership mistakes into a better future.pptx
Turn leadership mistakes into a better future.pptxStephen Sitton
 
CME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTES
CME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTESCME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTES
CME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTESkarthi keyan
 

Kürzlich hochgeladen (20)

Input Output Management in Operating System
Input Output Management in Operating SystemInput Output Management in Operating System
Input Output Management in Operating System
 
Theory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfTheory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdf
 
Virtual memory management in Operating System
Virtual memory management in Operating SystemVirtual memory management in Operating System
Virtual memory management in Operating System
 
Novel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsNovel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending Actuators
 
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONTHE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
 
Main Memory Management in Operating System
Main Memory Management in Operating SystemMain Memory Management in Operating System
Main Memory Management in Operating System
 
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
 
70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical training70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical training
 
11. Properties of Liquid Fuels in Energy Engineering.pdf
11. Properties of Liquid Fuels in Energy Engineering.pdf11. Properties of Liquid Fuels in Energy Engineering.pdf
11. Properties of Liquid Fuels in Energy Engineering.pdf
 
Energy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptxEnergy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptx
 
List of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdfList of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdf
 
Robotics Group 10 (Control Schemes) cse.pdf
Robotics Group 10  (Control Schemes) cse.pdfRobotics Group 10  (Control Schemes) cse.pdf
Robotics Group 10 (Control Schemes) cse.pdf
 
Python Programming for basic beginners.pptx
Python Programming for basic beginners.pptxPython Programming for basic beginners.pptx
Python Programming for basic beginners.pptx
 
Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...
Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...
Comparative study of High-rise Building Using ETABS,SAP200 and SAFE., SAFE an...
 
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.pptROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
 
『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书
『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书
『澳洲文凭』买麦考瑞大学毕业证书成绩单办理澳洲Macquarie文凭学位证书
 
Prach: A Feature-Rich Platform Empowering the Autism Community
Prach: A Feature-Rich Platform Empowering the Autism CommunityPrach: A Feature-Rich Platform Empowering the Autism Community
Prach: A Feature-Rich Platform Empowering the Autism Community
 
Artificial Intelligence in Power System overview
Artificial Intelligence in Power System overviewArtificial Intelligence in Power System overview
Artificial Intelligence in Power System overview
 
Turn leadership mistakes into a better future.pptx
Turn leadership mistakes into a better future.pptxTurn leadership mistakes into a better future.pptx
Turn leadership mistakes into a better future.pptx
 
CME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTES
CME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTESCME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTES
CME 397 - SURFACE ENGINEERING - UNIT 1 FULL NOTES
 

Forget about loops

  • 2. FORGET ABOUT LOOPSDUŠAN KASAN github.com/DusanKasan @DusanKasan me@dusankasan.com
  • 3. FORGET ABOUT LOOPSDUŠAN KASAN What it’ll be about • The problem • Functional programming • Collection pipelines • Collection pipelines in PHP Problem | FP | Collection Pipelines | PHP
  • 4. What’s the problem? $output .= "function {$properties['unifunc']} (Smarty_Internal_Template $_smarty_tpl) {n";
 // include code for plugins
 if (!$cache) {
 if (!empty($_template->compiled->required_plugins[ 'compiled' ])) {
 foreach ($_template->compiled->required_plugins[ 'compiled' ] as $tmp) {
 foreach ($tmp as $data) {
 $file = addslashes($data[ 'file' ]);
 if (is_array($data[ 'function' ])) {
 $output .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';n";
 } else {
 $output .= "if (!is_callable('{$data['function']}')) require_once '{$file}';n";
 }
 }
 }
 }
 if ($_template->caching && !empty($_template->compiled->required_plugins[ 'nocache' ])) {
 $_template->compiled->has_nocache_code = TRUE;
 $output .= "echo '/*%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/<?php $_smarty = $_smarty_tpl->smarty; ";
 foreach ($_template->compiled->required_plugins[ 'nocache' ] as $tmp) {
 foreach ($tmp as $data) {
 $file = addslashes($data[ 'file' ]);
 if (is_array($data[ 'function' ])) {
 $output .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file } else {
 $output .= addslashes("if (!is_callable('{$data['function']}')) require_once '{$file}';n");
 }
 }
 }
 $output .= "?>/*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/';n";
 }
 }
 smarty_internal_runtime_codeframe.php FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 5. Let’s boil it down[
 {
 "id": 1,
 "username": "john",
 "verified": true,
 "posts": [
 {
 "body": "Hi I'm John.",
 "likes": [2, 3, 5]
 },
 {
 "body": "I hate this site.",
 "likes": []
 }
 ]
 },
 {
 "id": 2,
 "username": "tom",
 "verified": false,
 "posts": []
 },
 {
 "id": 3,
 "username": "jane",
 "verified": true,
 "posts": [
 {
 "body": "Hi I'm Jane.",
 "likes": [4, 5]
 }
 ]
 }
 ]
 {
 "1": [
 {
 "body": "Hi I'm John.",
 "likes": [2, 3, 5]
 }
 ],
 "3": [
 {
 "body": "Hi I'm jane.",
 "likes": [4, 5]
 }
 ]
 } => FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 6. Let’s boil it down $likedPosts = [];
 
 foreach ($users as $user) {
 if ($user['verified']) {
 $userId = $user['id'];
 
 foreach ($user['posts'] as $post) {
 if (count($post['likes'])) {
 $likedPosts[$userId][] = $post;
 }
 }
 }
 } 4 levels of nesting Harder to follow / cognitive load Too much memorization Refactoring candidate FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 7. Refactoring - extract more functions $likedPosts = [];
 
 foreach ($users as $user) {
 if ($user['verified']) {
 $userId = $user['id'];
 
 foreach ($user['posts'] as $post) {
 if (count($post['likes'])) {
 $likedPosts[$userId][] = $post;
 }
 }
 }
 } private function getLikedPosts(array $posts)
 {
 $likedPosts = [];
 foreach ($posts as $post) {
 if (count($post['likes'])) {
 $likedPosts[] = $post;
 }
 }
 
 return $likedPosts;
 } FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 8. Refactoring - extract more functions $likedPosts = [];
 
 
 foreach ($users as $user) {
 $likedPosts = $this->getLikedPosts($user['posts']);
 
 if ($user['verified'] && count($likedPosts)) {
 $likedPosts[$user['id']] = $likedPosts;
 }
 } • Pretty good solution • The new function name carries the meaning of the logic • Enough for quick understanding • For real understanding, we’ll hop between functions FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 9. Refactoring - built-in array functions $indexedUsers = [];
 foreach ($users as $user) {
 $indexedUsers[$user['id']] = $user;
 } $verifiedUsers = array_filter(
 $indexedUsers,
 function ($user) {
 return $user['verified'];
 }
 ); $likedPosts = array_map(
 function($verifiedUser) {
 return array_filter(
 $verifiedUser['posts'],
 function($post) {return count($post['likes']);}
 );
 },
 $verifiedUsers
 ); FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 10. Refactoring - built-in array functions ( °□°) ︵ FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 11. Refactoring - built-in array functions $indexedUsers = [];
 foreach ($users as $user) {
 $indexedUsers[$user['id']] = $user;
 } $verifiedUsers = array_filter(
 $indexedUsers,
 function ($user) {
 return $user['verified'];
 }
 ); $likedPosts = array_map(
 function($verifiedUser) {
 return array_filter(
 $verifiedUser['posts'],
 function($post) {return count($post['likes']);}
 );
 },
 $verifiedUsers
 ); FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 12. Functional programming FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 13. Functional programming buzzwords Immutability No side effects Higher-order functions ConcurrencyParallelism FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 14. Functional programming buzzwords Immutability function withName(User $user, $name) {
 $result = User::from($user);
 $result->setName($name);
 
 return $result;
 }
 
 $tim = new User(1, ’tim', ....);
 $tom = withName($tim, 'tom');
 
 echo $tim->getName(); //'tim'
 echo $tom->getName(); //'tom' FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP class User
 {
 ...
 
 public function withName($name)
 {
 return new self($this->getId(), $name, ...);
 }
 }
  • 15. Functional programming buzzwords Immutability No side effects Higher-order functions ConcurrencyParallelism FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 16. Functional programming buzzwords No side effects $anotherTry = function ($a, $b, $c) {
 return $a . $b . $c;
 };
 
 $a = $anotherTry( $randomObscureThing, $_REQUEST['absolutely_safe'], DateTime::ATOM );
 $totallyNoSideEffectsHere = function () use ($randomObscureThing) {
 return $randomObscureThing . $_REQUEST['absolutely_safe'] . DateTime::ATOM;
 };
 
 $a = $totallyNoSideEffectsHere(); FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 17. Functional programming buzzwords Immutability No side effects Higher-order functions ConcurrencyParallelism FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 18. Functional programming buzzwords Higher-order functions function show(callable $c) {
 echo $c();
 }
 
 function style(callable $c) : callable {
 return function () use ($c) {
 return '**' . $c() . '**';
 };
 }
 
 $nameProvider = function () {
 return 'John';
 };
 
 show($nameProvider); //John
 show(style($nameProvider)); //**John**
 FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 19. Functional programming buzzwords Immutability No side effects Higher-order functions ConcurrencyParallelism FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 21. Collection Pipelines ( - ) FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 22. Collection Pipelines • What are collections? • Group of values or key, value pairs • Think arrays or Traversables • Collection pipeline • Design pattern • Sequential operations on collections • Operations e.g.: filter, map or reduce • Used by both FP and OOP languages • Immutable, lazy, concurrent FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 23. Simple explanation map([🌽, 🐮, 🐔], cook) => [🍿, 🍔, 🍳] filter([🍿, 🍔, 🍳], isVegetarian) => [🍿, 🍳] reduce([🍿, 🍳], eat) => 💩 From a tweet by @steveluscher FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 24. Simple explanation [🌽, 🐮, 🐔] .map(cook) // [🍿, 🍔, 🍳] .filter(isVegetarian) // [🍿, 🍳] .reduce(eat) // 💩 FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 25. Collection pipeline operations append, combine, concat, contains, countBy, cycle, diff, distinct, drop, dropLast, dropWhile, each, every, except, extract, filter, find, first, flatten, flip, frequencies, get, getOrDefault, groupBy, groupByKey, has, indexBy, interleave, interpose, intersect, isEmpty, isNotEmpty, keys, last, map, mapcat, only, partition, partitionBy, prepend, realize, reduce, reduceRight, reductions, reject, replace, reverse, second, shuffle, size, slice, some, sort, splitAt, splitWith, take, takeNth, takeWhile, transform, toArray, zip, FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 26. The original problem[
 {
 "id": 1,
 "username": "john",
 "verified": true,
 "posts": [
 {
 "body": "Hi I'm John.",
 "likes": [2, 3, 5]
 },
 {
 "body": "I hate this site.",
 "likes": []
 }
 ]
 },
 {
 "id": 2,
 "username": "tom",
 "verified": false,
 "posts": []
 },
 {
 "id": 3,
 "username": "jane",
 "verified": true,
 "posts": [
 {
 "body": "Hi I'm Jane.",
 "likes": [4, 5]
 }
 ]
 }
 ]
 {
 "1": [
 {
 "body": "Hi I'm John.",
 "likes": [2, 3, 5]
 }
 ],
 "3": [
 {
 "body": "Hi I'm jane.",
 "likes": [4, 5]
 }
 ]
 } => FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 27. Refactoring - Collections $likedPosts = [];
 
 foreach ($users as $user) {
 if ($user['verified']) {
 $userId = $user['id'];
 
 foreach ($user['posts'] as $post) {
 if (count($post['likes'])) {
 $likedPosts[$userId][] = $post;
 }
 }
 }
 } $likedPosts = Collection::from($users)
 ->filter(function ($user) {return $user['verified'];})
 ->indexBy(function($user) {return $user['id'];})
 ->map(function($user) {
 return Collection::from($user['posts'])
 ->filter(function($post) {return count($post['likes']);});
 })
 ->reject(function($posts) {return isEmpty($posts);}); FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 28. When to use collection pipelines • Where you work with collections? • API • Import CSV • Any nontrivial collection based work • Refactoring of current code base to for comprehension Drawbacks? • Function call overhead • You have to understand it :) FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 29. Collection pipelines in PHP • CakePHP Collection (github.com/cakephp/collection) • Laravel Collections (github.com/illuminate/support) • PHP-Collection (github.com/emonkak/php-collection) • Knapsack (github.com/DusanKasan/Knapsack) FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 30. PHP’s shortcomings $collection->map(function($item) {return $item->field;}); $collection->map($item ~> $item->field); $collection->map(function($item) {
 return $item->field;
 }); $collection->map(function($item) => $item->field); RFC targeting PHP 7.1 FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP
  • 31. Interested? • Martin Fowler (martinfowler.com) • Adam Wathan (adamwathan.me/refactoring-to-collections) • Documentation and tests to the mentioned libraries FORGET ABOUT LOOPSDUŠAN KASAN Problem | FP | Collection Pipelines | PHP