SlideShare ist ein Scribd-Unternehmen logo
1 von 51
Downloaden Sie, um offline zu lesen
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
lter
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
specied 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?

Weitere ähnliche Inhalte

Was ist angesagt?

画像Hacks
画像Hacks画像Hacks
画像HacksYusuke Wada
 
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
 
Shell.php
Shell.phpShell.php
Shell.phpDado Antik
 
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
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 FormsBernhard 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 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
 

Was ist angesagt? (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
 

Andere mochten auch

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
 
Leadership 1122
Leadership 1122Leadership 1122
Leadership 1122Tariq 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 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
 

Andere mochten auch (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Mehr von 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
 
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 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
 
Beginning OOP in PHP
Beginning OOP in PHPBeginning OOP in PHP
Beginning OOP in PHPDavid 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
 
PHP 5 Magic Methods
PHP 5 Magic MethodsPHP 5 Magic Methods
PHP 5 Magic MethodsDavid Stockton
 
FireBug And FirePHP
FireBug And FirePHPFireBug And FirePHP
FireBug And FirePHPDavid Stockton
 

Mehr von 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
 

KĂźrzlich hochgeladen

Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxthorishapillay1
 
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONHumphrey A BeĂąa
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for BeginnersSabitha Banu
 
DATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginnersDATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginnersSabitha Banu
 
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxiammrhaywood
 
Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptxSherlyMaeNeri
 
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Celine George
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parentsnavabharathschool99
 
ENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomnelietumpap1
 
How to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPHow to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPCeline George
 
Karra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptxKarra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptxAshokKarra1
 
ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4MiaBumagat1
 
USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...Postal Advocate Inc.
 
Gas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxGas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxDr.Ibrahim Hassaan
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Celine George
 
Roles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceRoles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceSamikshaHamane
 
Grade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptxGrade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptxChelloAnnAsuncion2
 
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPTECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPTiammrhaywood
 

KĂźrzlich hochgeladen (20)

Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptx
 
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for Beginners
 
DATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginnersDATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginners
 
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
 
Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptx
 
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parents
 
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
 
ENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choom
 
How to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPHow to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERP
 
Karra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptxKarra SKD Conference Presentation Revised.pptx
Karra SKD Conference Presentation Revised.pptx
 
ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4
 
USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPSÂŽ Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
 
Gas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxGas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptx
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17
 
Roles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceRoles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in Pharmacovigilance
 
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptxLEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
 
Grade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptxGrade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptx
 
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPTECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
ECONOMIC CONTEXT - LONG FORM TV DRAMA - PPT
 

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 lter 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 lters
  • 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 • lter($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 specied 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