Re: add Fiber (sackful coroutine) support

From: Date: Fri, 01 Sep 2017 13:02:29 +0000
Subject: Re: add Fiber (sackful coroutine) support
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-100343@lists.php.net to get a copy of this message
> On 1 Sep 2017, at 20:45, Rowan Collins <rowan.collins@gmail.com> wrote: > > Is this your own invention, or is the name and semantics based on some existing language or > computer science theory? "Fiber" makes me think of strings, rather than coroutines, so > maybe I'm missing a key metaphor here. Fiber is a lightweight thread. Please see https://en.wikipedia.org/wiki/Fiber_(computer_science) And ruby support Fiber. Please see https://ruby-doc.org/core-2.4.1/Fiber.html > >>> <?php >>> function foo($a) >>> { >>> $b = await $a + 1; >>> echo $b; >>> } > > Should "await" be "yield" here? If not, what happens if I call foo() > without being inside a Fiber? No. A function with a yield will always return a Generator object. A fiber with await will return any value. You can see the await as a resumable return. The value after it will be returned and the function will be paused. > > Similarly, if I run bar() and it runs foo(), what result will I get outside a Fiber, since > bar() has no yield, so is not itself a generator? > > >> So the Fiber API is a little like the Generator API, but is more simple >> yet powerful. So there >> is no need to distinct $generator->current(), $generator->send(), and >> $generator->getReturn(). > > Your ->resume() doesn't seem to do anything a normal generator can't, except that > the yield is nested deeper. The await is a nested deeper yield! > Nor does it seem to replace getReturn(). <?php $f = new Fiber(function ($a) { return 1; }); echo $f->resume(); // will output 1 > Meanwhile, how does this relate to other ways of combining generators, such as "yield > from"? You can use Fiber to implement a more simple generator, because fiber can be paused/resumed in its deeper call. <?php function bar() { foreach ([5,6] as $i) { await $i; } } function foo() { foreach ([3,4] as $i) { await $i; } bar(); } $f = new Fiber(function ($a) { await 1; foo(); }); echo $f->resume(); // will output 1 echo $f->resume(); // will output 2 echo $f->resume(); // will output 3 echo $f->resume(); // will output 4 echo $f->resume(); // will output 5 echo $f->resume(); // will output 6

« previous php.internals (#100343) next »