Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Generators: All About the Yield

Generators: All About the Yield

Generators presentation given at PHP Detriot 2018

5485e66eefca3e321e605c56157514c4?s=128

Justin Yost

July 27, 2018
Tweet

Transcript

  1. Generators: All About the Yield Justin Yost Senior Software Engineer

    at Wirecutter CC BY-NC 4.0 Justin Yost 1
  2. What is a Generator? Think Iterators without the overhead of

    writing an Iterator. CC BY-NC 4.0 Justin Yost 2
  3. What is an Iterator? An Iterator, is a PHP object

    or iterator, that can be iterated itself internally. so; arrays, generators and \Traversable foreach ($iterator as $key => $value) {} CC BY-NC 4.0 Justin Yost 3
  4. What is a Generator? The big trick here is that

    Generators and Iterators provide for a looping mechanism without the memory overhead of the thing you are looping over. CC BY-NC 4.0 Justin Yost 4
  5. Iterator vs. Array vs. Generator — Iterators - Object Based,

    current/key/next/rewind/ valid(), Advanced SPL Iterators, Limited memory usage — Array - Simple, One way, Direct Access, Memory constrained — Generator - Simple, One way, current/key/next(), Limited memory usage CC BY-NC 4.0 Justin Yost 5
  6. Generators: All About the Yield yield - acts as the

    return from a generator CC BY-NC 4.0 Justin Yost 6
  7. Simple Example function getRange($max = 15) { for ($i =

    1; $i < $max; $i++) { yield $i; // PHP pauses here, passes $i back to the consumer } } foreach(getRange(4) as $value) { echo "value: {$value} "; } // value: 1 value: 2 value: 3 CC BY-NC 4.0 Justin Yost 7
  8. 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 8
  9. 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 9
  10. 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 10
  11. Return function getRange($max = 15) { for ($i = 1;

    $i < $max; $i++) { yield $i; } return $max; } foreach($gen = getRange(4) as $key => $value) { echo "key: {$key} value: {$value} "; } echo $gen->getReturn(); // key: 0 value: 1 key: 1 value: 2 key: 2 value: 3 4 CC BY-NC 4.0 Justin Yost 11
  12. Early Return function getRange($max = 15) { for ($i =

    1; $i < $max; $i++) { yield $i; return; } } foreach($gen = getRange(4) as $key => $value) { echo "key: {$key} value: {$value} "; } echo $gen->getReturn(); // key: 0 value: 1 CC BY-NC 4.0 Justin Yost 12
  13. Code Samples CC BY-NC 4.0 Justin Yost 13

  14. Generators — Generators are Iterators without the Iterator overhead —

    Generators can be interrupted in processing via yield — return ends a generator — You can operate a Generator using Iterator current, next, key methods — Except for rewind, Generators are forward only Iterators CC BY-NC 4.0 Justin Yost 14
  15. Coroutines — Coroutines are programs that allow for non- preemptive

    multitasking via multiple entry points for suspending and returning. CC BY-NC 4.0 Justin Yost 15
  16. 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 16
  17. More knowledge of Generators CC BY-NC 4.0 Justin Yost 17

  18. Generators yield from function gen() { yield 1; yield 2;

    yield from gen2(); yield 5; } function gen2() { yield 3; yield 4; } foreach (gen() as $val) { echo $val . " "; } // 1 2 3 4 5 CC BY-NC 4.0 Justin Yost 18
  19. 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 19
  20. Send and Receive function genPrint() { while (true) { $sent

    = (yield 'return-val '); echo $sent . PHP_EOL; } } $print = genPrint(); echo $print->send('fizz'); echo $print->send('buzz'); // fizz // return-val buzz // return-val CC BY-NC 4.0 Justin Yost 20
  21. Generators::send function genPrint() { for ($i = 1; $i <

    15; $i++) { $string = (yield $i); echo $string . " "; } } $print = genPrint(); // (instanceof Iterator && Generator) echo $print->send('fizz'); echo $print->send('buzz'); // fizz 2buzz 3 CC BY-NC 4.0 Justin Yost 21
  22. 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 22
  23. Send and Receive and Current function genPrint() { while (true)

    { $sent = (yield 'return-val '); echo $sent . PHP_EOL; } } $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 23
  24. Send and Receive and Current function genPrint() { for ($i

    = 1; $i < 15; $i++) { $sent = (yield $i); echo $sent . PHP_EOL; } } $print = genPrint(); echo $print->current(); echo $print->send('fizz'); echo $print->send('buzz'); // 1fizz // 2buzz // 3 CC BY-NC 4.0 Justin Yost 24
  25. 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 25
  26. Multiple Yields with Send and Receive and Current function genPrint()

    { while (true) { $sent = (yield 'return-val '); echo $sent . PHP_EOL; $sent = (yield 'return-val2 '); echo $sent . PHP_EOL; } } $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 26
  27. 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 27
  28. Code Example CC BY-NC 4.0 Justin Yost 28

  29. 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 29
  30. Thanks/Questions? — twitter.com/justinyost — github.com/justinyost — justinyost.com — thewirecutter.com —

    linkedin.com/learning/instructors/justin-yost — https://joind.in/talk/7688b CC BY-NC 4.0 Justin Yost 30