The initializing generator arguments thread and related discussions has got me 
questioning our use of function declaration/expression syntax as our basis for 
defining generators.  Changing this would be a departure from what Firefox has 
supported in recent years, but in ES6 we have more constructs to build upon 
than FF did in 2006. The conclusion I reach is that it might be better to build 
generator definition upon a foundation of arrow functions rather than classic 
JS function definitions.  What follow is an attempt to sketch the thought 
process that lead to that conclusion:


On Sep 9, 2012, at 11:32 PM, Brendan Eich wrote:

> 
> function dataSnapshot(aCollection) {
>  let snapshot = aCollection.clone();
>  return function*() {
>    for (let i = 0; i < snapshot.length; i++){
>      yield snapshot[i];
>    }
>  }();
> }
> 


Issues:
If a generator needs to capture creation time state  it needs to be wrapped in 
a factory function/method, similar to Brendan's example above.
If the factory is a method the wrapping creates confusion about this/super 
binding.  For example:
class MyClass {
   dataSnapshot(aCollection) {
        let snapshot = aCollection.clone();
        return function*() {
               for (let i = 0; i < snapshot.length; i++){
                    yield thls.doSomething(snapshot[i]);   //this is not what 
was probably expected, super would be illegal
               }
         }();
    }
}

Generator function definitions need to be called to create an actual iterator 
object (a generator instance)
It is likely that a common error will be forgetting the invocation of the 
generator in return statements such as the above.
There is a potential for confusion about the evaluation time of generator 
parameter default value expression. If a parameterized generator needs default 
value initialization it is probably  better practice to accomplish that via a 
wrapper factory: 
function IteratorCol(col =  CollectionManager.default()) {
   return function*() {for (let i = 0; i < col.length; i++) yield col[i]}();
}

is argubaly clearer and more likely to be correct than

function *IteratorCol(col =  CollectionManager.default()) {
   for (let i = 0; i < col.length; i++) yield col[i];
}
But the wrapper form is less concise  than the unwrappered form. 
Concise method declarations for generators are misleading about the interface 
of the containing class/object because they place emphasis on an implementation 
detail (use of a generator to provide an Iterator implementation) rather than 
the more important fact that the method returns a object that can be used as an 
iterator.

A different approach:
eliminate formal parameters from generator definitions -- if arguments are 
needed use a wrapper function/method
eliminate the need to call a generator before before using it as an iterator.  
Generator definitions create generator instances rather than generator 
constructor functions.
use lexical this/super binding within generator definitions
base generator definition syntax off of arrow function syntax rather than 
function definition syntax
eliminate concise generator methods

Examples:

function dataSnapshot(aCollection) {
 let snapshot = aCollection.clone();
 return *=>{
   for (let i = 0; i < snapshot.length; i++){
     yield snapshot[i];
   }
 };
}

or more concisely:

function dataSnapshot(aCollection) {
 let snapshot = aCollection.clone();
 return *=>for (let i = 0; i < snapshot.length; i++) yield snapshot[i];
}

as a method:

class MyClass {
   dataSnapshot(aCollection = CollectionManager.default()) {
        let snapshot = aCollection.clone();
        return *=>for (let i = 0; i < this.length; i++) yield this[i];
    }
}



Proposal summary:
Generator literals -- Base generators syntax on arrow functions rather than 
function declarations/expressions
lexical this/super
expression or curly body
Generator literals don't have formal parameters 
Generators aren't called -- generator literals create generator instances (a 
kind of iterator) when evaluated
No concise generator methods -- use a concise method returning a generator 
literal 

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to