Slide 1

Slide 1 text

yield PHP5.5

Slide 2

Slide 2 text

K. k47.cz @kaja47 Karel Čížex funkcionalne.cz

Slide 3

Slide 3 text

"The title means exactly what the words say: naked lunch, a frozen moment when everyone sees what is on the end of every fork." William S. Burroughs, Naked Lunch

Slide 4

Slide 4 text

Let’s get right to the heart of this thing.

Slide 5

Slide 5 text

Coroutines generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations.

Slide 6

Slide 6 text

cooperative tasks, exceptions, event loop, iterators, infinite lists and pipes.

Slide 7

Slide 7 text

/* enter */ → function () { return 1; /* exit */ → } /* enter */ → function () { $i = 0; yield $i++; /* exit */ → /* entrée */ → yield $i++; /* sortie */ → /* entrata */ → yield $i++; /* uscita */ → /* entrada */ → yield $i++; /* salida */ → }

Slide 8

Slide 8 text

Delimited continuation

Slide 9

Slide 9 text

function () { // delimitation ← yield 1; // continuation ← }

Slide 10

Slide 10 text

State machine

Slide 11

Slide 11 text

Programs and interpreters

Slide 12

Slide 12 text

// program $prog = function () { $i = 0; while (true) { yield $i++; } }; // interpreter foreach ($prog() as $i) { echo "$i\n"; }

Slide 13

Slide 13 text

// program $prog = function () { $user = (yield fetchUser(1)); $data = (yield fetchData($user->id)); yield [$user, $data]; }; // interpreter Async::flow($prog());

Slide 14

Slide 14 text

// program $prog = function () { for ($id = 0; $id < 9001; $id++) { yield fetchId($id) } }; // interpreter Async::concurrently(100, $prog());

Slide 15

Slide 15 text

Promise

Slide 16

Slide 16 text

Deferred / Resolved / Rejected

Slide 17

Slide 17 text

IO

Slide 18

Slide 18 text

// fetch all followers $profile = syncFetchProfile('kaja47'); $ids = []; $cursor = '-1'; do { $fs = syncFetchFollowers($profile->id, $cursor); $ids = array_merge($ids, $fs->ids); $cursor = $fs->next_cursor_str; } while ($cursor != "0") return [$profile, $ids];

Slide 19

Slide 19 text

// async clusterfuck fetchProfile($userName)->then(function ($profile) { $fetch = function($userId, $cursor) use (&$fetch) { return fetchFollowers($userId, $cursor)->then(function ($fs) use ($userId, $fetch) { $cursor = $fs->next_cursor_str; if ($cursor == "0") return When::resolve($fs->ids); else return $fetch($userId, $cursor)->then(function($ids) use($fs) { return array_merge($fs->ids, ids); }); }); }; $fetch($profile->id, '-1')->then(function($ids) use($ids) { return [$profile, $ids]; }) });

Slide 20

Slide 20 text

// async $promise = Async::flow(function() { $profile = (yield fetchProfile('kaja47')); $ids = []; $cursor = '-1'; do { $fs = (yield fetchFollowers($profile->id, $cursor)); $ids = array_merge($ids, $fs->ids); $cursor = $fs->next_cursor_str; } while ($cursor != "0") yield [$profile, $ids]; });

Slide 21

Slide 21 text

// https://github.com/kaja47/flow function flow($f) { $gen = ($f instanceof Generator) ? $f : $f(); $throw = function ($ex) use ($gen) { $gen->throw($ex); }; $fst = true; $recur = function($pureValue) use($gen, &$recur, &$fst) { try { $x = $fst ? $gen->current() : $gen->send($pureValue); } catch (Exception $e) { return When::reject($e); } $fst = false; if (!$gen->valid()) return When::resolve($pureValue); return When::resolve($x)->then($recur, $throw); }; return $recur(null); }

Slide 22

Slide 22 text

full closure

Slide 23

Slide 23 text

Async::flow(function () { $conn = (yield connect()); $res = (yield $conn->query('...'); yield $conn->close(); yield $res; });

Slide 24

Slide 24 text

throw / catch

Slide 25

Slide 25 text

Async::flow(function () { try { $conn = (yield connect()); } catch (DatabaseIsDeadException $e) { if (canWePretendLikeItsNotHappening()) { yield fakeData(); } else { throw new OurStartupIsBusted(AND_NOW_FOR_REAL); } } yield $conn->fetchPicturesOfCats(MOAR); });

Slide 26

Slide 26 text

yield is monadic

Slide 27

Slide 27 text

yield is sequential

Slide 28

Slide 28 text

// seq Async::flow(function () { $v1 = (yield p1()); $v2 = (yield p2()); yield f($v1, $v2); });

Slide 29

Slide 29 text

// par Async::flow(function () { list($p1, $p2) = yield When::all([p1(), p2()]); yield f($p1, $p2); });

Slide 30

Slide 30 text

// par Async::flow(function () { $p1 = p1(); $p1 = p2(); $v1 = (yield $p1); $v2 = (yield $p2); });

Slide 31

Slide 31 text

yield is pull-based

Slide 32

Slide 32 text

Rx?

Slide 33

Slide 33 text

Promise ~ /.?/ Observable ~ /.*/

Slide 34

Slide 34 text

// ??? $newObservable = Async::stream(function () use ($observable) { $count = 0; while (true) { $val = (yield $observable); yield $count += $val->count; } });

Slide 35

Slide 35 text

callbacks promises →

Slide 36

Slide 36 text

Atrox\Async\HTTP

Slide 37

Slide 37 text

The only hope now, I felt, was the possibility that we'd gone to such excess, with our gig, that nobody in a position to bring the hammer down on us could possibly believe it. Hunter S. Thompson, Fear and Loathing in Las Vegas

Slide 38

Slide 38 text

Promise([$value, $nextPromise])

Slide 39

Slide 39 text

Chain::seq($gen)

Slide 40

Slide 40 text

Chain::concurrently($count, $gen)

Slide 41

Slide 41 text

This is the end Beautiful friend This is the end My only friend, the end Of our elaborate plans, the end Of everything that stands, the end No safety or surprise, the end I'll never look into your eyes...again Can you picture what will be So limitless and free Desperately in need...of some...stranger's hand In a...desperate land Lost in a Roman...wilderness of pain And all the children are insane All the children are insane Waiting for the summer rain, yeah

Slide 42

Slide 42 text

http://reactphp.org/ https://github.com/reactphp https://github.com/kaja47/flow https://github.com/kaja47/async-mysql https://github.com/kaja47/async-http http://conference.phpnw.org.uk/phpnw12/schedule/igor-wiedler/#video http://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-fu nctional-nodes-biggest-missed-opportunity/ http://blog.jcoglan.com/2013/04/01/callbacks-promises-and-simplicity/ https://gist.github.com/domenic/3889970 http://blog.parse.com/2013/01/29/whats-so-great-about-javascript-promises/ http://brianmckenna.org/blog/category_theory_promisesaplus http://www.dartlang.org/articles/using-future-based-apis/ http://marakana.com/s/post/1453/redemption_from_callback_hell_michael_ja ckson_domenic_denicola_video https://gist.github.com/hellerbarde/2843375

Slide 43

Slide 43 text