| 00:23 | <Michael Ficarra> | ecmarkup should check that all agorithms either end with a return step or an assertion that it's unreachable |
| 00:25 | <Michael Ficarra> | also ACs |
| 02:06 | <Michael Ficarra> | @shu FYI I want to discuss https://github.com/tc39/proposal-joint-iteration/pull/30 tomorrow and you may want to read the conversation beforehand if you have time |
| 21:24 | <bakkot> | brief summary of that issue:
Recall that for a syntactic generator, a return statement provides the value to be used alongside the first { done: true }, as in let g = (function* (){ yield 0; return 1; })(); console.log(g.next(), g.next(), g.next())
this is accomplished by, GeneratorStart evaluates the function body to completion, after which it checks whether it ends up with a return completion (in which case its value is used to give the value of the final iterator result) or a normal completion (in which case there was no explicit return statement, and it ignores the value of the normal completion and uses undefined)
built-in generators use the GeneratorStart machinery with an abstract closure instead of a function body, but I don't think it makes sense for them to use the "check for return vs normal completion" logic. there's a few ways to accomplish this.
one way is to have GeneratorStart assert that the AC produces either a throw completion or a normal completion containing unused, which would mean that GeneratorStart would go down the path for implicit returns from syntactic generators. then built-in generators could never have { done: true, value: "something other than undefined" }, which seems fine though it's kind of an odd restriction to build in.
another would be to assert that the AC produces either a throw completion or a return completion, and require the AC to explicitly return ReturnCompletion(*undefined*) instead of NormalCompletion(~unused~). Then GeneratorStart would go down the path for explicit returns from syntactic generators, and use the value of the return completion to provide the value slot.
I'd mildly prefer the second but am fine either way. Currently we have no asserts in either direction, such that the AC used to define a built-in generator can return both normal and return completions and go down either path, which seems unnecessarily complicated.
|
| 21:25 | <bakkot> | (I was considering joining the call to explain this but I have a sleeping baby on top of me currently so that's not happening) |
| 21:25 | <Michael Ficarra> | just whisper 😛 |
| 21:26 | <bakkot> | also Michael Ficarra I addressed your comments on the remaining ecmarkup PRs |
| 21:27 | <Michael Ficarra> | @bakkot I still don't like that it's a skip annotation instead of an xfail... |
| 21:27 | <bakkot> | oh I thought of a way to do the xfail without requiring me to do much work, I'll see about making that change |
| 21:28 | <Michael Ficarra> | 🙇♂️ |
| 21:29 | <Michael Ficarra> | brief summary of that issue:
Recall that for a syntactic generator, a return statement provides the value to be used alongside the first { done: true }, as in let g = (function* (){ yield 0; return 1; })(); console.log(g.next(), g.next(), g.next())
this is accomplished by, GeneratorStart evaluates the function body to completion, after which it checks whether it ends up with a return completion (in which case its value is used to give the value of the final iterator result) or a normal completion (in which case there was no explicit return statement, and it ignores the value of the normal completion and uses undefined)
built-in generators use the GeneratorStart machinery with an abstract closure instead of a function body, but I don't think it makes sense for them to use the "check for return vs normal completion" logic. there's a few ways to accomplish this.
one way is to have GeneratorStart assert that the AC produces either a throw completion or a normal completion containing unused, which would mean that GeneratorStart would go down the path for implicit returns from syntactic generators. then built-in generators could never have { done: true, value: "something other than undefined" }, which seems fine though it's kind of an odd restriction to build in.
another would be to assert that the AC produces either a throw completion or a return completion, and require the AC to explicitly return ReturnCompletion(*undefined*) instead of NormalCompletion(~unused~). Then GeneratorStart would go down the path for explicit returns from syntactic generators, and use the value of the return completion to provide the value slot.
I'd mildly prefer the second but am fine either way. Currently we have no asserts in either direction, such that the AC used to define a built-in generator can return both normal and return completions and go down either path, which seems unnecessarily complicated.
I pretty strongly prefer the former until we have a need for the latter, and I've updated all my iterator proposals to do this |
| 21:55 | <Michael Ficarra> | @bakkot after talking about it, I'm neutral on the two approaches and @shu is leaning toward the latter |