Re: [RFC Discuss] Generator Delegation
| From: | Rowan Collins | Date: | Tue, 03 Mar 2015 12:27:48 +0000 |
| Subject: | Re: [RFC Discuss] Generator Delegation | ||
| References: | 1 2 3 4 5 6 7 8 9 10 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-84231@lists.php.net to get a copy of this message | ||
Bob Weinand wrote on 03/03/2015 12:08:
Hm, I didn't realise that. I suppose it makes sense that you'd want a way to do that, but it does make it very hard to see if something's going to behave as a function or a coroutine if they use the same keywords to mean different things.Am 03.03.2015 um 12:34 schrieb Rowan Collins <rowan.collins@gmail.com>: Niklas Keller wrote on 03/03/2015 10:55:Hey, We currently already have "return;" (without value) as allowed syntax to terminate Generator execution. Thus, the logical consequence is just adding a value to that return."yield final" would mark the final result of the coroutine, as opposed to the intermediate values passed out with a normal "yield".Gr, top-posting...Sorry, was on mobile. ;-)However, since the existence of the word "yield" is the only thing that marks a coroutine now, how about using a variant of that for the final value, e.g. "yield final $foo"?What's the final value? The last "yield"ed value or a return?Just to give you some real world example: If you're using "return", it would look like that: public function getSession ($sessionId) {My suggestion is simply to change the keyword: public function getSession ($sessionId) {$result = yield $this->redis->get("session.{$sessionId}")); // We're waiting here until redis responded. return json_decode($result);}$result = yield $this->redis->get("session.{$sessionId}")); // We're waiting here until redis responded. yield final json_decode($result);} The reasoning being that when you run getSession(42), it *doesn't* return the result of json_decode(), it returns a pointer to the coroutine's state, which you can resume later. Actually, I don't think that example makes sense, because JSON gets sent out at the first yield, and then sent back in, so the caller would look something like this: $foo = getSession(42); $json_data = $foo->current(); $foo->send($json_data); $decoded = $foo->getReturn(); But never mind, I think we both get the idea. I understand the desire for a "final result", but I don't like reusing the word "return", because it's never "returned" as the result of running the function, it's just made available through some specific method/syntax. Regards, -- Rowan Collins [IMSoP]
When we want to *return*, it should be also a real *return". Yes, it is just accessible through special syntax (or a method), but it's still *return*ing into the calling frame.Well, so is "yield" - it just leaves the Generator in a state that can be resumed, whereas "return"/"yield final" leaves it in a final, non-resumable state.
Why should the word "return" be unique to methods or functions?It just doesn't feel like the same thing as a return value to me, for the same reason a generator doesn't feel like the same thing as a function. In "function foo() { return 42; }", "return" means "this is what you'll get when you run foo()"; in "function foo() { return 42; yield; }", what you get when you run foo() is a pointer to the resumable state, and return means "this is what you'll get if you ask the generator/coroutine instance you get by running foo() for its final result". Regards, -- Rowan Collins [IMSoP]