Bergi (2015-03-25T19:19:49.000Z)
Axel Rauschmayer wrote:
> Given that redundant calls to `return()` don’t make a difference (h/t Bergi)

I'm sorry, that was not 100% accurate. I only referred to `.return(x)` 
returning {done:true, value:x} and `.throw(e)` being equivalent to 
`throw e;` when the generator was never started or is already completed 
(http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresumeabrupt).
In fact, there are generators that behave differently when being 
prematurely aborted and attempted to be closed multiple times.
A contrived example:

   function* unstoppableCounter(n) {
        try {
            while (true)
                yield n++;
        } finally {
            console.log("unclosable!");
            yield* unstoppableCounter(n);
        }
    }

    var counter = unstoppableCounter(0);
    var i=5;
    for (var x of counter) {
        console.log(x);
        if (!--i) break;
    }
    i=4;
    for (var x of counter) {
        console.log(x);
        if (!--i) break;
    }

Every call of `counter.return()` here would actually log "unclosable!", 
increase the counter and yield {done:false, value:…} - in general, might 
have side effects. So we shouldn't do it arbitrarily often.

 > couldn’t the iteration protocol be simpler if iterators were always 
closed. “Manually implemented” iterators could be written without the 
check in line (A)

I don't think that's how an explicit iterator would be written. 
Shouldn't it look more like

   …
   next() {
       if (iterationIsDone()) {
           cleanUp();
           return {done: true};
       } else {
           return {value: nextValue(), done: false};
       }
   }

Of course that assumes that we don't have a return value, and `next()` 
is no more called after it returned `done: true` once (otherwise we'd 
clean up multiple times).
Maybe better:

   …
   next() {
       if (iterationIsDone()) {
           return {done: true};
       } else {
           let result = {value: nextValue(), done: iterationIsDone()};
           if (result.done) cleanUp(); // (B)
           return result;
       }
   }

Admittedly, that has the line you argued against again…

  Bergi
d at domenic.me (2015-04-14T22:10:18.650Z)
Axel Rauschmayer wrote:
> Given that redundant calls to `return()` don’t make a difference (h/t Bergi)

I'm sorry, that was not 100% accurate. I only referred to `.return(x)` 
returning {done:true, value:x} and `.throw(e)` being equivalent to 
`throw e;` when the generator was never started or is already completed 
(http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresumeabrupt).
In fact, there are generators that behave differently when being 
prematurely aborted and attempted to be closed multiple times.
A contrived example:

```js
function* unstoppableCounter(n) {
    try {
        while (true)
            yield n++;
    } finally {
        console.log("unclosable!");
        yield* unstoppableCounter(n);
    }
}

var counter = unstoppableCounter(0);
var i=5;
for (var x of counter) {
    console.log(x);
    if (!--i) break;
}
i=4;
for (var x of counter) {
    console.log(x);
    if (!--i) break;
}
```

Every call of `counter.return()` here would actually log "unclosable!", 
increase the counter and yield {done:false, value:…} - in general, might 
have side effects. So we shouldn't do it arbitrarily often.

 > couldn’t the iteration protocol be simpler if iterators were always  closed. “Manually implemented” iterators could be written without the  check in line (A)

I don't think that's how an explicit iterator would be written. 
Shouldn't it look more like

```js
   …
   next() {
       if (iterationIsDone()) {
           cleanUp();
           return {done: true};
       } else {
           return {value: nextValue(), done: false};
       }
   }
```

Of course that assumes that we don't have a return value, and `next()` 
is no more called after it returned `done: true` once (otherwise we'd 
clean up multiple times).
Maybe better:

```js
   …
   next() {
       if (iterationIsDone()) {
           return {done: true};
       } else {
           let result = {value: nextValue(), done: iterationIsDone()};
           if (result.done) cleanUp(); // (B)
           return result;
       }
   }
```

Admittedly, that has the line you argued against again…
d at domenic.me (2015-04-14T22:09:53.904Z)
Axel Rauschmayer wrote:
> Given that redundant calls to `return()` don’t make a difference (h/t Bergi)

I'm sorry, that was not 100% accurate. I only referred to `.return(x)` 
returning {done:true, value:x} and `.throw(e)` being equivalent to 
`throw e;` when the generator was never started or is already completed 
(http://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresumeabrupt).
In fact, there are generators that behave differently when being 
prematurely aborted and attempted to be closed multiple times.
A contrived example:

```js
function* unstoppableCounter(n) {
    try {
        while (true)
            yield n++;
    } finally {
        console.log("unclosable!");
        yield* unstoppableCounter(n);
    }
}

var counter = unstoppableCounter(0);
var i=5;
for (var x of counter) {
    console.log(x);
    if (!--i) break;
}
i=4;
for (var x of counter) {
    console.log(x);
    if (!--i) break;
}
```

Every call of `counter.return()` here would actually log "unclosable!", 
increase the counter and yield {done:false, value:…} - in general, might 
have side effects. So we shouldn't do it arbitrarily often.

 > couldn’t the iteration protocol be simpler if iterators were always  closed. “Manually implemented” iterators could be written without the  check in line (A)

I don't think that's how an explicit iterator would be written. 
Shouldn't it look more like

   …
   next() {
       if (iterationIsDone()) {
           cleanUp();
           return {done: true};
       } else {
           return {value: nextValue(), done: false};
       }
   }

Of course that assumes that we don't have a return value, and `next()` 
is no more called after it returned `done: true` once (otherwise we'd 
clean up multiple times).
Maybe better:

   …
   next() {
       if (iterationIsDone()) {
           return {done: true};
       } else {
           let result = {value: nextValue(), done: iterationIsDone()};
           if (result.done) cleanUp(); // (B)
           return result;
       }
   }

Admittedly, that has the line you argued against again…