Claus Reinke (2013-07-25T15:44:53.000Z)
domenic at domenicdenicola.com (2013-08-01T17:18:13.446Z)
I do not understand why (1) iterators are specified using a self-updating API when a functional API would seem preferable, or why (2) generators are linked to functions, when block-level generators would seem to be sufficient and less complex. In some more detail: 1. Why do iterators have an imperative API? As currently specified, an Iterator's next returns a {done,value} pair (ItrResult), updating the Iterator in place. A functional alternative would have next return a {done,value,next} triple, leaving the original Iterator unmodified. It seems a lot easier to implement the imperative API in terms of the functional one than the other way round, if one needed both. In practice, I do not see any advantage to forcing an imperative API. 2. Why are generators linked to functions, and not to blocks? It is not difficult to implement a form of generators in ES5. Here is one using TypeScript for classes and arrow functions (it uses a functional Iterator API, and .then-chained expressions instead of ;-chained statements): definition: https://gist.github.com/clausreinke/5984869#file-monadic-ts-L91-L125 usage examples: https://gist.github.com/clausreinke/5984869#file-monadic-ts-L492-L529 The main source-level disadvantages of these user-defined generators wrt built-in generators are: (a) lack of syntax sugar for .then-chaining (b) no coverage of statement blocks and their built-in control structures (a) would be cheap to fix (monad comprehensions have been suggested here multiple times), (b) could be fixed by introducing block-level generators as built-ins. Block-level generators are shallower than function-level ones (continuation reaches to the end of the current block), expression-level generators are even shallower (continuation reaches to the end of the current .then-chained expression). This would allow us to introduce shallow generators without messing with "function" - generators would simply be another class of object that "function" allows us to write abstraction over. Composing shallow continuations could be left to user- level functions, not built-ins, so everything but the block-level generators would remain (re-)programmable.