SlideShare a Scribd company logo
1 of 51
Download to read offline
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

Object Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPObject Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPChad 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. - PHPKonfRafael Dohms
 
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 technologyDaniel Knell
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace 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 introductionIban 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 ProgrammingFabio Akita
 
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 askAndrea 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
R57shellady36
 

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 AvoidanceJason 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-enoughRenaud 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. - #PHPSRB16Rafael Dohms
 
Real World React Native & ES7
Real World React Native & ES7Real World React Native & ES7
Real World React Native & ES7joestanton1
 
Expériencer les objets connectés
Expériencer les objets connectésExpériencer les objets connectés
Expériencer les objets connectésekino
 
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-likeTristan 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 studyGaetano Giunta
 
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 symfonyXavier Leune
 
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 Krenndistributed 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 BehatRyan 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 FunctionPhil Calçado
 
Finagle @ SoundCloud
Finagle @ SoundCloudFinagle @ SoundCloud
Finagle @ SoundCloudPhil Calçado
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7julien 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 PatternsHugo Hamon
 
Document Classification In PHP
Document Classification In PHPDocument Classification In PHP
Document Classification In PHPIan 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 TownRoss 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 2014Amazon Web Services
 
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-2011Alessandro 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 PHPersistenceHugo 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 CodeAbbas 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 OldRoss 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 UnConRafael Dohms
 

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 phpDavid 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 applicationDavid Stockton
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHPDavid 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 2David Stockton
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHPDavid Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profitDavid Stockton
 
Common design patterns in php
Common design patterns in phpCommon design patterns in php
Common design patterns in phpDavid Stockton
 
Intermediate oop in php
Intermediate oop in phpIntermediate oop in php
Intermediate oop in phpDavid Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profitDavid Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profitDavid 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 SSHDavid Stockton
 
Mercurial Distributed Version Control
Mercurial Distributed Version ControlMercurial Distributed Version Control
Mercurial Distributed Version ControlDavid Stockton
 
Regular expressions and php
Regular expressions and phpRegular expressions and php
Regular expressions and phpDavid 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

Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...Pooja Bhuva
 
Unit-V; Pricing (Pharma Marketing Management).pptx
Unit-V; Pricing (Pharma Marketing Management).pptxUnit-V; Pricing (Pharma Marketing Management).pptx
Unit-V; Pricing (Pharma Marketing Management).pptxVishalSingh1417
 
How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxCeline George
 
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...Nguyen Thanh Tu Collection
 
Wellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptxWellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptxJisc
 
Sociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning ExhibitSociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning Exhibitjbellavia9
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jisc
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfagholdier
 
Google Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxGoogle Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxDr. Sarita Anand
 
80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...
80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...
80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...Nguyen Thanh Tu Collection
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsMebane Rash
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxRamakrishna Reddy Bijjam
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...Poonam Aher Patil
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.pptRamjanShidvankar
 
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdfUnit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdfDr Vijay Vishwakarma
 
Fostering Friendships - Enhancing Social Bonds in the Classroom
Fostering Friendships - Enhancing Social Bonds  in the ClassroomFostering Friendships - Enhancing Social Bonds  in the Classroom
Fostering Friendships - Enhancing Social Bonds in the ClassroomPooky Knightsmith
 
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxHMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxmarlenawright1
 
Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Association for Project Management
 
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxHMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxEsquimalt MFRC
 

Recently uploaded (20)

Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
 
Unit-V; Pricing (Pharma Marketing Management).pptx
Unit-V; Pricing (Pharma Marketing Management).pptxUnit-V; Pricing (Pharma Marketing Management).pptx
Unit-V; Pricing (Pharma Marketing Management).pptx
 
Spatium Project Simulation student brief
Spatium Project Simulation student briefSpatium Project Simulation student brief
Spatium Project Simulation student brief
 
How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptx
 
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
 
Wellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptxWellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptx
 
Sociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning ExhibitSociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning Exhibit
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
Google Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxGoogle Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptx
 
80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...
80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...
80 ĐỀ THI THỬ TUYỂN SINH TIẾNG ANH VÀO 10 SỞ GD – ĐT THÀNH PHỐ HỒ CHÍ MINH NĂ...
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docx
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.ppt
 
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdfUnit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
 
Fostering Friendships - Enhancing Social Bonds in the Classroom
Fostering Friendships - Enhancing Social Bonds  in the ClassroomFostering Friendships - Enhancing Social Bonds  in the Classroom
Fostering Friendships - Enhancing Social Bonds in the Classroom
 
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxHMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
 
Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...
 
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxHMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
 

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