Slide 1

Slide 1 text

Generators: All About the Yield Justin Yost Web Developer at Loadsys CC BY-NC 4.0 Justin Yost 1

Slide 2

Slide 2 text

What is a Generator? Think Iterators without the overhead of writing an Iterator. CC BY-NC 4.0 Justin Yost 2

Slide 3

Slide 3 text

What is a Generator? The big trick here is that Generators provide for a looping mechanism without the memory overhead of the thing you are looping over. CC BY-NC 4.0 Justin Yost 3

Slide 4

Slide 4 text

Iterator vs. Array vs. Generator » Iterators - Object Based, Rewind/Forward/Filter/etc, Limited memory usage » Array - Simple, One way, Direct Access, Memory constrained » Generator - Simple, One way, Limited memory usage CC BY-NC 4.0 Justin Yost 4

Slide 5

Slide 5 text

Generators: All About the Yield yield - acts as the return from a generator CC BY-NC 4.0 Justin Yost 5

Slide 6

Slide 6 text

Simple Example function getRange($max = 15) { for ($i = 1; $i < $max; $i++) { yield $i; } } foreach(getRange(4) as $value) { echo "value: {$value} "; } // value: 1 value: 2 value: 3 CC BY-NC 4.0 Justin Yost 6

Slide 7

Slide 7 text

Key and Value Yield Example function getRange($max = 15) { for ($i = 1; $i < $max; $i++) { yield $i => $max; } } foreach(getRange(4) as $key => $value) { echo "key: {$key} value: {$value} "; } // key: 1 value: 4 key: 2 value: 4 key: 3 value: 4 CC BY-NC 4.0 Justin Yost 7

Slide 8

Slide 8 text

Empty Yield function getRange($max = 15) { for ($i = 1; $i < $max; $i++) { yield; } } foreach(getRange(4) as $value) { echo "value: {$value} "; } // value: value: value: CC BY-NC 4.0 Justin Yost 8

Slide 9

Slide 9 text

Yield by Reference function &getRange($max = 15) { for ($i = 1; $i < $max; $i++) { yield $i => $max; } } foreach(getRange(4) as &$key => $value) { echo "key: {$key} value: {$value} "; ($key++); } // key: 1 value: 4 key: 3 value: 4 CC BY-NC 4.0 Justin Yost 9

Slide 10

Slide 10 text

Return function getRange($max = 15) { for ($i = 1; $i < $max; $i++) { return; } } foreach(getRange(4) as $key => $value) { echo "key: {$key} value: {$value} "; } // CC BY-NC 4.0 Justin Yost 10

Slide 11

Slide 11 text

Non Empty Return function getRange($max = 15) { for ($i = 1; $i < $max; $i++) { return $i; } } foreach(getRange(4) as $key => $value) { echo "key: {$key} value: {$value} "; } // !!!! Error !!!! CC BY-NC 4.0 Justin Yost 11

Slide 12

Slide 12 text

Code Samples CC BY-NC 4.0 Justin Yost 12

Slide 13

Slide 13 text

Generators » Generators are Iterators without the Iterator overhead » Generators can be interrupted in processing via yield » Empty return ends a generator » You can operate a Generator using Iterator current, next, etc » Except for rewind, Generators are forward only Iterators CC BY-NC 4.0 Justin Yost 13

Slide 14

Slide 14 text

Coroutines » Coroutines are programs that allow for nonpreemptive multitasking via multiple entry points for suspending and returning. CC BY-NC 4.0 Justin Yost 14

Slide 15

Slide 15 text

Generators and Coroutines » yield is the trick here, we can pause executing of one method and continue on in a different method CC BY-NC 4.0 Justin Yost 15

Slide 16

Slide 16 text

More knowledge of Generators CC BY-NC 4.0 Justin Yost 16

Slide 17

Slide 17 text

Generators::send function genPrint() { while (true) { $string = yield; echo $string . " "; } } $print = genPrint(); // (instanceof Iterator && Generator) $print->send('fizz'); $print->send('buzz'); // fizz buzz CC BY-NC 4.0 Justin Yost 17

Slide 18

Slide 18 text

Send and Receive function genPrint() { while (true) { $sent = (yield 'return-val '); echo $sent . " "; } } $print = genPrint(); echo $print->send('fizz'); echo $print->send('buzz'); // fizz return-val buzz return-val CC BY-NC 4.0 Justin Yost 18

Slide 19

Slide 19 text

Send and Receive » send executes the generator by passing the input » then yields the return value of the generator CC BY-NC 4.0 Justin Yost 19

Slide 20

Slide 20 text

Send and Receive and Current function genPrint() { while (true) { $sent = (yield 'return-val '); echo $sent . " "; } } $print = genPrint(); echo $print->current(); echo $print->send('fizz'); echo $print->send('buzz'); // return-val fizz return-val buzz return-val CC BY-NC 4.0 Justin Yost 20

Slide 21

Slide 21 text

Send and Receive and Current » send executes the generator by passing the input » then yields the return value of the generator » current just yields the return value of the generator CC BY-NC 4.0 Justin Yost 21

Slide 22

Slide 22 text

Multiple Yields with Send and Receive and Current function genPrint() { while (true) { $sent = (yield 'return-val '); echo $sent . " "; $sent = (yield 'return-val2 '); echo $sent . " "; } } $print = genPrint(); echo $print->current(); echo $print->send('fizz'); echo $print->send('buzz'); // return-val fizz return-val2 buzz return-val CC BY-NC 4.0 Justin Yost 22

Slide 23

Slide 23 text

Multiple Yields with Send and Receive and Current » send executes the generator by passing the input » then yields the return value of the generator » current just yields the return value of the generator » each yield means we have another exit depending on where in the iteration we are » each iteration - first yield then second, then loop, repeat CC BY-NC 4.0 Justin Yost 23

Slide 24

Slide 24 text

Code Example CC BY-NC 4.0 Justin Yost 24

Slide 25

Slide 25 text

Sourced from: » https://scotch.io/tutorials/understanding-php-generators » https://nikic.github.io/2012/12/22/Cooperative-multitasking- using-coroutines-in-PHP.html CC BY-NC 4.0 Justin Yost 25

Slide 26

Slide 26 text

Thanks/Questions? » twitter.com/justinyost » github.com/justinyost » justinyost.com » loadsys.com » lynda.com/justinyost CC BY-NC 4.0 Justin Yost 26