SlideShare a Scribd company logo
The Art of
Transduction
ZendCon 2016 - Oct 19
PHP Toolbox
The Art of Foreach
A Silly Example
$grades = [98, 77, 100, 62, 90, 95, 82, 68];



$sum = 0;

$count = 0;

foreach ($grades as $grade) {

$sum += $grade;

$count ++;

}

echo "Avg: " . $sum / $count . "n";
A Less Silly Example
$grades = [98, 77, 100, 62, 90, 95, 82, 68];



$sum = 0;

foreach ($grades as $grade) {

$sum += $grade;

}

echo "Avg: " . $sum / count($grades) . "n";
Less Sillier
$grades = [98, 77, 100, 62, 90, 95, 82, 68];



$sum = array_sum($grades);

echo "Avg: " . $sum / count($grades) . "n";
Grade Buckets
$grades = [98, 77, 100, 62, 90, 95, 82, 68];



$gradeBuckets = ["A" => 0, "B" => 0, "C" => 0, "F" => 0];

foreach ($grades as $grade) {

switch (true) {

case $grade >= 90:

$gradeBuckets['A']++;

break;

case $grade >= 80:

$gradeBuckets['B']++;

break;

case $grade >= 70:

$gradeBuckets['C']++;

break;

default:

$gradeBuckets['F']++;

}

}



Phone Tree
function getNonManagerNumbers(Employee ...$employees)

{

$phoneNumbers = [];

foreach ($employees as $employee) {

if ($employee->isManager()) {

continue;

}

$phoneNumbers[] = $employee->getPhoneNumber();

}

return $phoneNumbers;

}

Nav Builder
function buildNav($links)

{

$html = '<ul>';

foreach ($links as $link) {

$html .= '<li><a href="' .
$link->getUrl() . '">' .

$link->getTitle() . '</a></li>';

}

$html .= '</ul>';

return $html;

}
Reduce
function reduce(array $items, callable $callback,
$initial)

{

$carryOver = $initial;

foreach ($items as $item) {

$carryOver = $callback(
$carryOver,
$item
);

}

return $carryOver;

}
Functional Programming
• Map
• Filter
• Reduce
Grades as Reduce
$avg = reduce(

$grades,

function ($carry, $item) {

$total = $carry['count'] * $carry['avg'] + $item;

$carry['count']++;

$carry['avg'] = $total / $carry['count'];

return $carry;

},

['count' => 0, 'avg' => 0]

)['avg'];

Phone Tree as Reduce
function getNonManagerNumbers($employees)

{

return reduce(

$employees,

function ($numbers, $employee) {

return $employee->isManager() ?

$numbers :

array_merge(

$numbers, 

[$employee->getPhoneNumber()]

);

},

[]

);

}
Nav Builder as Reduce
function buildNav($links) 

{

return '<ul>' .

reduce(

$links,

function ($html, $link) {

return $html . '<li><a href="' .
$link->getUrl() .

'">' . $link->getTitle() .

'</a></li>';

}

)

. '</ul>';

}
What About
Transducers?
What are
Transducers?
Collection Pipeline
$numbers = collect($employeeService->getAllEmployees())

->filter(function ($employee) {

return ! $employee->isManager();

})->map(function ($employee) {

return $employee->getPhoneNumber();

});
Installation
composer require mtdowling/transducers
Phone Tree as Transducer
use Transducers as t;



$employees = (new EmployeeService)->getAllEmployees();

$getNonManagerPhones = tcomp(

tfilter(function ($employee) { 

return ! $employee->isManager(); 

}),

tmap(function ($employee) { 

return $employee->getPhoneNumber(); 

})

);

$numbers = tto_array($getNonManagerPhones, $employees);
The Data
Name Number Manager
Bob 303-555-1212 Yes
Sue 303-555-1234 No
Barb 303-555-1111 No
Spongebob 303-555-1001 Yes
Arnold 303-555-1313 No
Collection Data Pipeline
Name Number Manager
Bob 303-555-1212 Yes
Sue 303-555-1234 No
Barb 303-555-1111 No
Spongebob 303-555-1001 Yes
Arnold 303-555-1313 No
Filter
Name Number Manager
Sue 303-555-1234 No
Barb 303-555-1111 No
Arnold 303-555-1313 No
Map
Number
303-555-1234
303-555-1111
303-555-1313
Transducer Data Flow
Name Number Manager
Bob 303-555-1212 Yes
Sue 303-555-1234 No
Barb 303-555-1111 No
Spongebob 303-555-1001 Yes
Arnold 303-555-1313 No
Number
303-555-1234
303-555-1111
303-555-1313
filter
map
NO
Transducer Data Sources
• Anything that you can use foreach on
• Arrays
• Iterators
• Traversables
• Generators
Transducer Output
• Eager
• transduce()
• into()
• to_array()
• to_assoc()
• to_string()
Transducer Output
• Lazy
• to_iter()
• xform()
• stream filters
A Bigger Example
• Incoming TSV, but should be CSV
• Date format is wrong
• Names are not capitalized
• We need days from or until birthdate, for reasons
Transformer
use transducers as t;

/* SNIP Definition of the functions used below */
$transformer = tcomp(

tdrop(1), // Get rid of the header

tmap($convertToArray), // Turn TSV to Array

tmap($convertToDate), // Change to DateTimeImmutable Object

tmap($addDaysFromBirthday), // Date math

tmap($fixDateFormat), // Format DateTimeImmutable
// to Y-m-d string
$fixNames, // Capitalize names

);
Convert TSV to Array
$convertToArray = function ($tsvRow) {

$arrayRow = explode("t", $tsvRow);

$columns = ['id', 'first', 'last', 'dob'];

return array_combine($columns, $arrayRow);

};
What it does
42 t david t stockton t 1/1/1999
[

'id' => 42,

'first' => 'david',

'last' => 'stockton',

'dob' => '1/1/1999'

]
Convert Date to Object
$convertToDate = function ($row) {

$date =
DateTimeImmutable::createFromFormat(

'm/d/Y',

trim($row['dob']
)

);

$row['dob'] = $date;

return $row;

};
Add Days from Birthday
$now = new DateTimeImmutable();

$thisYear = $now->format('Y');



$addDaysFromBirthday = function($row) use ($now, $thisYear) {

$dob = $row['dob'];

$birthday = DateTimeImmutable::createFromFormat(

'Y-m-d',

$dob->format("$thisYear-m-d")

);



$timeUntilBirthday = $now->diff($birthday);



$row['time_until_bday'] = $timeUntilBirthday->invert

? $timeUntilBirthday->format('%m months, %d days ago')

: $timeUntilBirthday->format('%m months, %d days');



return $row;

};
Fix Date Formatting
$fixDateFormat = function ($row) {

$row['dob'] = $row['dob']->format('Y-m-d');

return $row;

};
Uppercasing Names
$capFirst = function ($row) {

$row['first'] = ucfirst($row['first']);

return $row;

};

$capLast = function ($row) {

$row['last'] = ucfirst($row['last']);

return $row;

};
Function to Build a Function
// Function to return a function

$ucField = function($field) {

return function ($row) use ($field) {

$row[$field] = ucfirst($row[$field]);

return $row;

};

};
Functionally Functional
$mungeField = function ($field, $munger) {

return function ($row) use ($field, $munger) {

$row[$field] = $munger($row[$field]);

return $row;

};

};
Name Capitalization
$fixNames = tcomp(

tmap($ucField('first')),

tmap($ucField('last'))

);



$fixNamesMunge = tcomp(

tmap($mungeField('first', 'ucfirst')),

tmap($mungeField('last', 'ucfirst'))

);
Revisit Transformer
use transducers as t;

/* SNIP Definition of the functions used below */
$transformer = tcomp(

tdrop(1), // Get rid of the header

tmap($convertToArray), // Turn TSV to Array

tmap($convertToDate), // Change to DateTimeImmutable Object

tmap($addDaysFromBirthday), // Date math

tmap($fixDateFormat), // Format DateTimeImmutable
// to Y-m-d string
$fixNames, // Capitalize names

);
Where We Are
Data converted from TSV to Array
Where We Are
function array_to_csv($data)

{

$fh = fopen('php://temp', 'rw');

fputcsv($fh, $data);

rewind($fh);

$csv = stream_get_contents($fh);

fclose($fh);



return $csv;

}
Reuse


$transformToCsv = tcomp(

$transformer,

tmap('array_to_csv')

);
Data Source
$fh = fopen(__DIR__ . '/ZendconData.tsv', 'r');



$reader = function () use ($fh) {

while ($row = fgets($fh)) {

yield $row;

}

};
Output
$write = fopen(__DIR__ . '/../data/Zendcon.csv', 'w');
TRANSFORM!!!11!
tinto($write, $reader(), $transformToCsv);
Included Transducer
Functions
• map($f) - Apply $f function to each value in a
collection
• filter($predicate) - If predicate returns true, retain
the value, otherwise discard
• remove($predicate) - Removes items that satisfy the
predicate function
• cat() - Concatenates items from nested lists
More Included Functions
• partition($size) - Splits the source into arrays of the
specified size
• partition_by($predicate) - Splits input into arrays
when value returned by $predicate changes
• take($n) - Takes $n items from the collection
• take_while($predicate) - Takes items from the
collection while the $predicate is true
Even Moar!
• take_nth($n) - Takes every $n values from the
collection
• drop($n) - Drops $n items from the start of a
sequence
• drop_while($predicate) - Drops items from the
collection as long as $predicate returns true
• replace(array $map) - Replaces values in the
sequence according to the $map
Ermegerhd, even more?!
• keep($f) - Keeps items when $f does not
return null
• keep_indexed($f) - Returns the non-null
results of calling $f($index, $value)
• dedupe - Removes values that are the same
as the previous value in an ordered
sequence
• interpose($separator) - Adds the separator
between each value in a sequence
Last list, I promise
• tap($interceptor) - "Taps" into the chain, in
order to do something with the intermediate
result. Does not change the sequence
• compact() - Trims out all "falsey" values from
the sequence
• words() - Splits input into words
• lines() - Splits input by lines
Transducers
• Compose powerful data processing functions
• Interact with streams of data
• Easy to understand
• Simple to test
Questions?

More Related Content

What's hot

画像Hacks
画像Hacks画像Hacks
画像Hacks
Yusuke Wada
 
Object Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPObject Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHP
Chad Gray
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Rafael Dohms
 
Daily notes
Daily notesDaily notes
Daily notes
meghendra168
 
Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"
Fwdays
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
Presentation1
Presentation1Presentation1
Presentation1
Rahadyan Gusti
 
BEAR DI
BEAR DIBEAR DI
Laravel
LaravelLaravel
Laravel
Sayed Ahmed
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
Jace Ju
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionAdam Trachtenberg
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
Iban Martinez
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented Programming
Fabio Akita
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
Bernhard Schussek
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
Andrea Giuliano
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
Rafael Dohms
 
R57shell
R57shellR57shell
R57shell
ady36
 

What's hot (20)

画像Hacks
画像Hacks画像Hacks
画像Hacks
 
Object Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPObject Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHP
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
 
Daily notes
Daily notesDaily notes
Daily notes
 
Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"Pim Elshoff "Technically DDD"
Pim Elshoff "Technically DDD"
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Presentation1
Presentation1Presentation1
Presentation1
 
BEAR DI
BEAR DIBEAR DI
BEAR DI
 
Laravel
LaravelLaravel
Laravel
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Shell.php
Shell.phpShell.php
Shell.php
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented Programming
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 
linieaire regressie
linieaire regressielinieaire regressie
linieaire regressie
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
 
R57shell
R57shellR57shell
R57shell
 
tutorial7
tutorial7tutorial7
tutorial7
 

Viewers also liked

Confidentail Avoidance
Confidentail AvoidanceConfidentail Avoidance
Confidentail Avoidance
Jason Hamm
 
CORPORATE CV_ADV AJAY SHARMA
CORPORATE CV_ADV AJAY SHARMACORPORATE CV_ADV AJAY SHARMA
CORPORATE CV_ADV AJAY SHARMAajay sharma
 
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...Phil Calçado
 
Pg nordic-day-2014-2 tb-enough
Pg nordic-day-2014-2 tb-enoughPg nordic-day-2014-2 tb-enough
Pg nordic-day-2014-2 tb-enough
Renaud Bruyeron
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16
“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16
“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16
Rafael Dohms
 
Real World React Native & ES7
Real World React Native & ES7Real World React Native & ES7
Real World React Native & ES7
joestanton1
 
Expériencer les objets connectés
Expériencer les objets connectésExpériencer les objets connectés
Expériencer les objets connectés
ekino
 
SfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-like
SfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-likeSfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-like
SfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-like
Tristan Maindron
 
Symfony2 for legacy app rejuvenation: the eZ Publish case study
Symfony2 for legacy app rejuvenation: the eZ Publish case studySymfony2 for legacy app rejuvenation: the eZ Publish case study
Symfony2 for legacy app rejuvenation: the eZ Publish case study
Gaetano Giunta
 
5 Facts You Should Know About Cloud Telephony
5 Facts You Should Know About Cloud Telephony5 Facts You Should Know About Cloud Telephony
5 Facts You Should Know About Cloud Telephony
Altura Communication Solutions
 
Industrialisation PHP - Canal+
Industrialisation PHP - Canal+Industrialisation PHP - Canal+
Industrialisation PHP - Canal+
ekino
 
Performance au quotidien dans un environnement symfony
Performance au quotidien dans un environnement symfonyPerformance au quotidien dans un environnement symfony
Performance au quotidien dans un environnement symfony
Xavier Leune
 
Leadership 1122
Leadership 1122Leadership 1122
Leadership 1122
Tariq Rashid
 
A tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp Krenn
A tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp KrennA tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp Krenn
A tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp Krenn
distributed matters
 
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with BehatGrand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Ryan Weaver
 
ScalaItaly 2015 - Your Microservice as a Function
ScalaItaly 2015 - Your Microservice as a FunctionScalaItaly 2015 - Your Microservice as a Function
ScalaItaly 2015 - Your Microservice as a Function
Phil Calçado
 
Finagle @ SoundCloud
Finagle @ SoundCloudFinagle @ SoundCloud
Finagle @ SoundCloud
Phil Calçado
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7
julien pauli
 

Viewers also liked (20)

AjishP-2016
AjishP-2016AjishP-2016
AjishP-2016
 
Justicia informatica subilo slishpare
Justicia informatica subilo slishpareJusticia informatica subilo slishpare
Justicia informatica subilo slishpare
 
Confidentail Avoidance
Confidentail AvoidanceConfidentail Avoidance
Confidentail Avoidance
 
CORPORATE CV_ADV AJAY SHARMA
CORPORATE CV_ADV AJAY SHARMACORPORATE CV_ADV AJAY SHARMA
CORPORATE CV_ADV AJAY SHARMA
 
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
(ThoughtWorks Away Day 2009) one or two things you may not know about typesys...
 
Pg nordic-day-2014-2 tb-enough
Pg nordic-day-2014-2 tb-enoughPg nordic-day-2014-2 tb-enough
Pg nordic-day-2014-2 tb-enough
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16
“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16
“Writing code that lasts” … or writing code you won’t hate tomorrow. - #PHPSRB16
 
Real World React Native & ES7
Real World React Native & ES7Real World React Native & ES7
Real World React Native & ES7
 
Expériencer les objets connectés
Expériencer les objets connectésExpériencer les objets connectés
Expériencer les objets connectés
 
SfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-like
SfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-likeSfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-like
SfPot Lille 07/2015 - Utiliser Symfony sur des environnements Heroku-like
 
Symfony2 for legacy app rejuvenation: the eZ Publish case study
Symfony2 for legacy app rejuvenation: the eZ Publish case studySymfony2 for legacy app rejuvenation: the eZ Publish case study
Symfony2 for legacy app rejuvenation: the eZ Publish case study
 
5 Facts You Should Know About Cloud Telephony
5 Facts You Should Know About Cloud Telephony5 Facts You Should Know About Cloud Telephony
5 Facts You Should Know About Cloud Telephony
 
Industrialisation PHP - Canal+
Industrialisation PHP - Canal+Industrialisation PHP - Canal+
Industrialisation PHP - Canal+
 
Performance au quotidien dans un environnement symfony
Performance au quotidien dans un environnement symfonyPerformance au quotidien dans un environnement symfony
Performance au quotidien dans un environnement symfony
 
Leadership 1122
Leadership 1122Leadership 1122
Leadership 1122
 
A tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp Krenn
A tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp KrennA tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp Krenn
A tale of queues — from ActiveMQ over Hazelcast to Disque - Philipp Krenn
 
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with BehatGrand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
 
ScalaItaly 2015 - Your Microservice as a Function
ScalaItaly 2015 - Your Microservice as a FunctionScalaItaly 2015 - Your Microservice as a Function
ScalaItaly 2015 - Your Microservice as a Function
 
Finagle @ SoundCloud
Finagle @ SoundCloudFinagle @ SoundCloud
Finagle @ SoundCloud
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7
 

Similar to The Art of Transduction

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
Hugo Hamon
 
Document Classification In PHP
Document Classification In PHPDocument Classification In PHP
Document Classification In PHP
Ian Barber
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Masahiro Nagano
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
Ross Tuck
 
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
Amazon Web Services
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
Konstantin Kudryashov
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Alessandro Nadalin
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)
Jeff Eaton
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
Hugo Hamon
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHPTaras Kalapun
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
Abbas Ali
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
Ross Tuck
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked aboutTatsuhiko Miyagawa
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
Rafael Dohms
 
Php functions
Php functionsPhp functions
Php functions
JIGAR MAKHIJA
 

Similar to The Art of Transduction (20)

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Document Classification In PHP
Document Classification In PHPDocument Classification In PHP
Document Classification In PHP
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
(DEV305) Building Apps with the AWS SDK for PHP | AWS re:Invent 2014
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Database api
Database apiDatabase api
Database api
 
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011 Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
Be lazy, be ESI: HTTP caching and Symfony2 @ PHPDay 2011 05-13-2011
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
wget.pl
wget.plwget.pl
wget.pl
 
distill
distilldistill
distill
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Php functions
Php functionsPhp functions
Php functions
 

More from David Stockton

Phone calls and sms from php
Phone calls and sms from phpPhone calls and sms from php
Phone calls and sms from php
David Stockton
 
Using queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your applicationUsing queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your application
David Stockton
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
David Stockton
 
Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2
David Stockton
 
API All the Things!
API All the Things!API All the Things!
API All the Things!
David Stockton
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
David Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
David Stockton
 
Beginning OOP in PHP
Beginning OOP in PHPBeginning OOP in PHP
Beginning OOP in PHP
David Stockton
 
Common design patterns in php
Common design patterns in phpCommon design patterns in php
Common design patterns in php
David Stockton
 
Intermediate oop in php
Intermediate oop in phpIntermediate oop in php
Intermediate oop in php
David Stockton
 
Grokking regex
Grokking regexGrokking regex
Grokking regex
David Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
David Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
David Stockton
 
Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)David Stockton
 
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSHTame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
David Stockton
 
Mercurial Distributed Version Control
Mercurial Distributed Version ControlMercurial Distributed Version Control
Mercurial Distributed Version Control
David Stockton
 
Regular expressions and php
Regular expressions and phpRegular expressions and php
Regular expressions and php
David Stockton
 
PHP 5 Magic Methods
PHP 5 Magic MethodsPHP 5 Magic Methods
PHP 5 Magic Methods
David Stockton
 
FireBug And FirePHP
FireBug And FirePHPFireBug And FirePHP
FireBug And FirePHP
David Stockton
 

More from David Stockton (19)

Phone calls and sms from php
Phone calls and sms from phpPhone calls and sms from php
Phone calls and sms from php
 
Using queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your applicationUsing queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your application
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2
 
API All the Things!
API All the Things!API All the Things!
API All the Things!
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
 
Beginning OOP in PHP
Beginning OOP in PHPBeginning OOP in PHP
Beginning OOP in PHP
 
Common design patterns in php
Common design patterns in phpCommon design patterns in php
Common design patterns in php
 
Intermediate oop in php
Intermediate oop in phpIntermediate oop in php
Intermediate oop in php
 
Grokking regex
Grokking regexGrokking regex
Grokking regex
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
 
Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)
 
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSHTame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
 
Mercurial Distributed Version Control
Mercurial Distributed Version ControlMercurial Distributed Version Control
Mercurial Distributed Version Control
 
Regular expressions and php
Regular expressions and phpRegular expressions and php
Regular expressions and php
 
PHP 5 Magic Methods
PHP 5 Magic MethodsPHP 5 Magic Methods
PHP 5 Magic Methods
 
FireBug And FirePHP
FireBug And FirePHPFireBug And FirePHP
FireBug And FirePHP
 

Recently uploaded

The approach at University of Liverpool.pptx
The approach at University of Liverpool.pptxThe approach at University of Liverpool.pptx
The approach at University of Liverpool.pptx
Jisc
 
Digital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion DesignsDigital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion Designs
chanes7
 
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
EugeneSaldivar
 
Azure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHatAzure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHat
Scholarhat
 
Unit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdfUnit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdf
Thiyagu K
 
Normal Labour/ Stages of Labour/ Mechanism of Labour
Normal Labour/ Stages of Labour/ Mechanism of LabourNormal Labour/ Stages of Labour/ Mechanism of Labour
Normal Labour/ Stages of Labour/ Mechanism of Labour
Wasim Ak
 
MASS MEDIA STUDIES-835-CLASS XI Resource Material.pdf
MASS MEDIA STUDIES-835-CLASS XI Resource Material.pdfMASS MEDIA STUDIES-835-CLASS XI Resource Material.pdf
MASS MEDIA STUDIES-835-CLASS XI Resource Material.pdf
goswamiyash170123
 
South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)
Academy of Science of South Africa
 
How to Make a Field invisible in Odoo 17
How to Make a Field invisible in Odoo 17How to Make a Field invisible in Odoo 17
How to Make a Field invisible in Odoo 17
Celine George
 
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptxChapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
Mohd Adib Abd Muin, Senior Lecturer at Universiti Utara Malaysia
 
JEE1_This_section_contains_FOUR_ questions
JEE1_This_section_contains_FOUR_ questionsJEE1_This_section_contains_FOUR_ questions
JEE1_This_section_contains_FOUR_ questions
ShivajiThube2
 
CACJapan - GROUP Presentation 1- Wk 4.pdf
CACJapan - GROUP Presentation 1- Wk 4.pdfCACJapan - GROUP Presentation 1- Wk 4.pdf
CACJapan - GROUP Presentation 1- Wk 4.pdf
camakaiclarkmusic
 
Pride Month Slides 2024 David Douglas School District
Pride Month Slides 2024 David Douglas School DistrictPride Month Slides 2024 David Douglas School District
Pride Month Slides 2024 David Douglas School District
David Douglas School District
 
The Diamond Necklace by Guy De Maupassant.pptx
The Diamond Necklace by Guy De Maupassant.pptxThe Diamond Necklace by Guy De Maupassant.pptx
The Diamond Necklace by Guy De Maupassant.pptx
DhatriParmar
 
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat  Leveraging AI for Diversity, Equity, and InclusionExecutive Directors Chat  Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
TechSoup
 
The Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official PublicationThe Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official Publication
Delapenabediema
 
Operation Blue Star - Saka Neela Tara
Operation Blue Star   -  Saka Neela TaraOperation Blue Star   -  Saka Neela Tara
Operation Blue Star - Saka Neela Tara
Balvir Singh
 
The Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptxThe Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptx
DhatriParmar
 
Overview on Edible Vaccine: Pros & Cons with Mechanism
Overview on Edible Vaccine: Pros & Cons with MechanismOverview on Edible Vaccine: Pros & Cons with Mechanism
Overview on Edible Vaccine: Pros & Cons with Mechanism
DeeptiGupta154
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
Peter Windle
 

Recently uploaded (20)

The approach at University of Liverpool.pptx
The approach at University of Liverpool.pptxThe approach at University of Liverpool.pptx
The approach at University of Liverpool.pptx
 
Digital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion DesignsDigital Artifact 2 - Investigating Pavilion Designs
Digital Artifact 2 - Investigating Pavilion Designs
 
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...TESDA TM1 REVIEWER  FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
TESDA TM1 REVIEWER FOR NATIONAL ASSESSMENT WRITTEN AND ORAL QUESTIONS WITH A...
 
Azure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHatAzure Interview Questions and Answers PDF By ScholarHat
Azure Interview Questions and Answers PDF By ScholarHat
 
Unit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdfUnit 2- Research Aptitude (UGC NET Paper I).pdf
Unit 2- Research Aptitude (UGC NET Paper I).pdf
 
Normal Labour/ Stages of Labour/ Mechanism of Labour
Normal Labour/ Stages of Labour/ Mechanism of LabourNormal Labour/ Stages of Labour/ Mechanism of Labour
Normal Labour/ Stages of Labour/ Mechanism of Labour
 
MASS MEDIA STUDIES-835-CLASS XI Resource Material.pdf
MASS MEDIA STUDIES-835-CLASS XI Resource Material.pdfMASS MEDIA STUDIES-835-CLASS XI Resource Material.pdf
MASS MEDIA STUDIES-835-CLASS XI Resource Material.pdf
 
South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)
 
How to Make a Field invisible in Odoo 17
How to Make a Field invisible in Odoo 17How to Make a Field invisible in Odoo 17
How to Make a Field invisible in Odoo 17
 
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptxChapter 4 - Islamic Financial Institutions in Malaysia.pptx
Chapter 4 - Islamic Financial Institutions in Malaysia.pptx
 
JEE1_This_section_contains_FOUR_ questions
JEE1_This_section_contains_FOUR_ questionsJEE1_This_section_contains_FOUR_ questions
JEE1_This_section_contains_FOUR_ questions
 
CACJapan - GROUP Presentation 1- Wk 4.pdf
CACJapan - GROUP Presentation 1- Wk 4.pdfCACJapan - GROUP Presentation 1- Wk 4.pdf
CACJapan - GROUP Presentation 1- Wk 4.pdf
 
Pride Month Slides 2024 David Douglas School District
Pride Month Slides 2024 David Douglas School DistrictPride Month Slides 2024 David Douglas School District
Pride Month Slides 2024 David Douglas School District
 
The Diamond Necklace by Guy De Maupassant.pptx
The Diamond Necklace by Guy De Maupassant.pptxThe Diamond Necklace by Guy De Maupassant.pptx
The Diamond Necklace by Guy De Maupassant.pptx
 
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat  Leveraging AI for Diversity, Equity, and InclusionExecutive Directors Chat  Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
 
The Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official PublicationThe Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official Publication
 
Operation Blue Star - Saka Neela Tara
Operation Blue Star   -  Saka Neela TaraOperation Blue Star   -  Saka Neela Tara
Operation Blue Star - Saka Neela Tara
 
The Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptxThe Accursed House by Émile Gaboriau.pptx
The Accursed House by Émile Gaboriau.pptx
 
Overview on Edible Vaccine: Pros & Cons with Mechanism
Overview on Edible Vaccine: Pros & Cons with MechanismOverview on Edible Vaccine: Pros & Cons with Mechanism
Overview on Edible Vaccine: Pros & Cons with Mechanism
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
 

The Art of Transduction

  • 3. The Art of Foreach
  • 4. A Silly Example $grades = [98, 77, 100, 62, 90, 95, 82, 68];
 
 $sum = 0;
 $count = 0;
 foreach ($grades as $grade) {
 $sum += $grade;
 $count ++;
 }
 echo "Avg: " . $sum / $count . "n";
  • 5. A Less Silly Example $grades = [98, 77, 100, 62, 90, 95, 82, 68];
 
 $sum = 0;
 foreach ($grades as $grade) {
 $sum += $grade;
 }
 echo "Avg: " . $sum / count($grades) . "n";
  • 6. Less Sillier $grades = [98, 77, 100, 62, 90, 95, 82, 68];
 
 $sum = array_sum($grades);
 echo "Avg: " . $sum / count($grades) . "n";
  • 7. Grade Buckets $grades = [98, 77, 100, 62, 90, 95, 82, 68];
 
 $gradeBuckets = ["A" => 0, "B" => 0, "C" => 0, "F" => 0];
 foreach ($grades as $grade) {
 switch (true) {
 case $grade >= 90:
 $gradeBuckets['A']++;
 break;
 case $grade >= 80:
 $gradeBuckets['B']++;
 break;
 case $grade >= 70:
 $gradeBuckets['C']++;
 break;
 default:
 $gradeBuckets['F']++;
 }
 }
 

  • 8. Phone Tree function getNonManagerNumbers(Employee ...$employees)
 {
 $phoneNumbers = [];
 foreach ($employees as $employee) {
 if ($employee->isManager()) {
 continue;
 }
 $phoneNumbers[] = $employee->getPhoneNumber();
 }
 return $phoneNumbers;
 }

  • 9. Nav Builder function buildNav($links)
 {
 $html = '<ul>';
 foreach ($links as $link) {
 $html .= '<li><a href="' . $link->getUrl() . '">' .
 $link->getTitle() . '</a></li>';
 }
 $html .= '</ul>';
 return $html;
 }
  • 10. Reduce function reduce(array $items, callable $callback, $initial)
 {
 $carryOver = $initial;
 foreach ($items as $item) {
 $carryOver = $callback( $carryOver, $item );
 }
 return $carryOver;
 }
  • 12. Grades as Reduce $avg = reduce(
 $grades,
 function ($carry, $item) {
 $total = $carry['count'] * $carry['avg'] + $item;
 $carry['count']++;
 $carry['avg'] = $total / $carry['count'];
 return $carry;
 },
 ['count' => 0, 'avg' => 0]
 )['avg'];

  • 13. Phone Tree as Reduce function getNonManagerNumbers($employees)
 {
 return reduce(
 $employees,
 function ($numbers, $employee) {
 return $employee->isManager() ?
 $numbers :
 array_merge(
 $numbers, 
 [$employee->getPhoneNumber()]
 );
 },
 []
 );
 }
  • 14. Nav Builder as Reduce function buildNav($links) 
 {
 return '<ul>' .
 reduce(
 $links,
 function ($html, $link) {
 return $html . '<li><a href="' . $link->getUrl() .
 '">' . $link->getTitle() .
 '</a></li>';
 }
 )
 . '</ul>';
 }
  • 16.
  • 18. Collection Pipeline $numbers = collect($employeeService->getAllEmployees())
 ->filter(function ($employee) {
 return ! $employee->isManager();
 })->map(function ($employee) {
 return $employee->getPhoneNumber();
 });
  • 20. Phone Tree as Transducer use Transducers as t;
 
 $employees = (new EmployeeService)->getAllEmployees();
 $getNonManagerPhones = tcomp(
 tfilter(function ($employee) { 
 return ! $employee->isManager(); 
 }),
 tmap(function ($employee) { 
 return $employee->getPhoneNumber(); 
 })
 );
 $numbers = tto_array($getNonManagerPhones, $employees);
  • 21. The Data Name Number Manager Bob 303-555-1212 Yes Sue 303-555-1234 No Barb 303-555-1111 No Spongebob 303-555-1001 Yes Arnold 303-555-1313 No
  • 22. Collection Data Pipeline Name Number Manager Bob 303-555-1212 Yes Sue 303-555-1234 No Barb 303-555-1111 No Spongebob 303-555-1001 Yes Arnold 303-555-1313 No Filter Name Number Manager Sue 303-555-1234 No Barb 303-555-1111 No Arnold 303-555-1313 No Map Number 303-555-1234 303-555-1111 303-555-1313
  • 23. Transducer Data Flow Name Number Manager Bob 303-555-1212 Yes Sue 303-555-1234 No Barb 303-555-1111 No Spongebob 303-555-1001 Yes Arnold 303-555-1313 No Number 303-555-1234 303-555-1111 303-555-1313 filter map NO
  • 24. Transducer Data Sources • Anything that you can use foreach on • Arrays • Iterators • Traversables • Generators
  • 25. Transducer Output • Eager • transduce() • into() • to_array() • to_assoc() • to_string()
  • 26. Transducer Output • Lazy • to_iter() • xform() • stream filters
  • 27. A Bigger Example • Incoming TSV, but should be CSV • Date format is wrong • Names are not capitalized • We need days from or until birthdate, for reasons
  • 28. Transformer use transducers as t;
 /* SNIP Definition of the functions used below */ $transformer = tcomp(
 tdrop(1), // Get rid of the header
 tmap($convertToArray), // Turn TSV to Array
 tmap($convertToDate), // Change to DateTimeImmutable Object
 tmap($addDaysFromBirthday), // Date math
 tmap($fixDateFormat), // Format DateTimeImmutable // to Y-m-d string $fixNames, // Capitalize names
 );
  • 29. Convert TSV to Array $convertToArray = function ($tsvRow) {
 $arrayRow = explode("t", $tsvRow);
 $columns = ['id', 'first', 'last', 'dob'];
 return array_combine($columns, $arrayRow);
 };
  • 30. What it does 42 t david t stockton t 1/1/1999 [
 'id' => 42,
 'first' => 'david',
 'last' => 'stockton',
 'dob' => '1/1/1999'
 ]
  • 31. Convert Date to Object $convertToDate = function ($row) {
 $date = DateTimeImmutable::createFromFormat(
 'm/d/Y',
 trim($row['dob'] )
 );
 $row['dob'] = $date;
 return $row;
 };
  • 32. Add Days from Birthday $now = new DateTimeImmutable();
 $thisYear = $now->format('Y');
 
 $addDaysFromBirthday = function($row) use ($now, $thisYear) {
 $dob = $row['dob'];
 $birthday = DateTimeImmutable::createFromFormat(
 'Y-m-d',
 $dob->format("$thisYear-m-d")
 );
 
 $timeUntilBirthday = $now->diff($birthday);
 
 $row['time_until_bday'] = $timeUntilBirthday->invert
 ? $timeUntilBirthday->format('%m months, %d days ago')
 : $timeUntilBirthday->format('%m months, %d days');
 
 return $row;
 };
  • 33. Fix Date Formatting $fixDateFormat = function ($row) {
 $row['dob'] = $row['dob']->format('Y-m-d');
 return $row;
 };
  • 34. Uppercasing Names $capFirst = function ($row) {
 $row['first'] = ucfirst($row['first']);
 return $row;
 };
 $capLast = function ($row) {
 $row['last'] = ucfirst($row['last']);
 return $row;
 };
  • 35. Function to Build a Function // Function to return a function
 $ucField = function($field) {
 return function ($row) use ($field) {
 $row[$field] = ucfirst($row[$field]);
 return $row;
 };
 };
  • 36. Functionally Functional $mungeField = function ($field, $munger) {
 return function ($row) use ($field, $munger) {
 $row[$field] = $munger($row[$field]);
 return $row;
 };
 };
  • 37. Name Capitalization $fixNames = tcomp(
 tmap($ucField('first')),
 tmap($ucField('last'))
 );
 
 $fixNamesMunge = tcomp(
 tmap($mungeField('first', 'ucfirst')),
 tmap($mungeField('last', 'ucfirst'))
 );
  • 38. Revisit Transformer use transducers as t;
 /* SNIP Definition of the functions used below */ $transformer = tcomp(
 tdrop(1), // Get rid of the header
 tmap($convertToArray), // Turn TSV to Array
 tmap($convertToDate), // Change to DateTimeImmutable Object
 tmap($addDaysFromBirthday), // Date math
 tmap($fixDateFormat), // Format DateTimeImmutable // to Y-m-d string $fixNames, // Capitalize names
 );
  • 39. Where We Are Data converted from TSV to Array
  • 40. Where We Are function array_to_csv($data)
 {
 $fh = fopen('php://temp', 'rw');
 fputcsv($fh, $data);
 rewind($fh);
 $csv = stream_get_contents($fh);
 fclose($fh);
 
 return $csv;
 }
  • 42. Data Source $fh = fopen(__DIR__ . '/ZendconData.tsv', 'r');
 
 $reader = function () use ($fh) {
 while ($row = fgets($fh)) {
 yield $row;
 }
 };
  • 43. Output $write = fopen(__DIR__ . '/../data/Zendcon.csv', 'w');
  • 45. Included Transducer Functions • map($f) - Apply $f function to each value in a collection • filter($predicate) - If predicate returns true, retain the value, otherwise discard • remove($predicate) - Removes items that satisfy the predicate function • cat() - Concatenates items from nested lists
  • 46. More Included Functions • partition($size) - Splits the source into arrays of the specified size • partition_by($predicate) - Splits input into arrays when value returned by $predicate changes • take($n) - Takes $n items from the collection • take_while($predicate) - Takes items from the collection while the $predicate is true
  • 47. Even Moar! • take_nth($n) - Takes every $n values from the collection • drop($n) - Drops $n items from the start of a sequence • drop_while($predicate) - Drops items from the collection as long as $predicate returns true • replace(array $map) - Replaces values in the sequence according to the $map
  • 48. Ermegerhd, even more?! • keep($f) - Keeps items when $f does not return null • keep_indexed($f) - Returns the non-null results of calling $f($index, $value) • dedupe - Removes values that are the same as the previous value in an ordered sequence • interpose($separator) - Adds the separator between each value in a sequence
  • 49. Last list, I promise • tap($interceptor) - "Taps" into the chain, in order to do something with the intermediate result. Does not change the sequence • compact() - Trims out all "falsey" values from the sequence • words() - Splits input into words • lines() - Splits input by lines
  • 50. Transducers • Compose powerful data processing functions • Interact with streams of data • Easy to understand • Simple to test