diff --git a/README.md b/README.md
index d12d515..bcedf7a 100644
--- a/README.md
+++ b/README.md
@@ -335,6 +335,17 @@ const wrapper = Iterator.from(iter);
wrapper.next() // { value: 1, done: false }
```
+## Iterator helpers and the generator protocol
+
+The generator protocol facilitates coordination between a producer and a
+consumer, which is necessarily broken by iteration-based transforms. There is
+no way to properly preserve or re-establish this coordination. We've taken the
+philosophy that any iterators produced by the helpers this proposal adds only
+implement the iterator protocol and make no attempt to support generators which
+use the remainder of the generator protocol. Specifically, such iterators do
+not implement `.throw` and do not forward the parameter of `.next` or `.return`
+to an underlying or "source" iterator.
+
## More Example Usage
### Lazy Iteration over sets
diff --git a/spec.html b/spec.html
index 9a267b6..7e52e6b 100644
--- a/spec.html
+++ b/spec.html
@@ -149,27 +149,6 @@
1. Return _iteratorRecord_.
-
-
-
- IteratorStep (
- _iteratorRecord_: an Iterator Record,
- optional _value_: an ECMAScript language value,
- ): either a normal completion containing either an Object or *false*, or a throw completion
-
-
-
- 1. Let _result_ be ? IteratorNext(_iteratorRecord_).
- 1. If _value_ is present, then
- 1. Let _result_ be ? IteratorNext(_iteratorRecord_, _value_).
- 1. Else,
- 1. Let _result_ be ? IteratorNext(_iteratorRecord_).
- 1. Let _done_ be ? IteratorComplete(_result_).
- 1. If _done_ is *true*, return *false*.
- 1. Return _result_.
-
-
@@ -252,38 +231,23 @@ The %WrapForValidIteratorPrototype% Object
- %WrapForValidIteratorPrototype%.next ( _value_ )
+ %WrapForValidIteratorPrototype%.next ( )
1. Let _O_ be *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Iterated]]).
- 1. If _value_ is not present, then
- 1. Return ? IteratorNext(_O_.[[Iterated]]).
- 1. Else,
- 1. Return ? IteratorNext(_O_.[[Iterated]], _value_).
+ 1. Return ? IteratorNext(_O_.[[Iterated]]).
- %WrapForValidIteratorPrototype%.return ( _v_ )
+ %WrapForValidIteratorPrototype%.return ( )
1. Let _O_ be *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Iterated]]).
- 1. Let _result_ be ? IteratorClose(_O_.[[Iterated]], NormalCompletion(_v_)).
+ 1. Let _result_ be ? IteratorClose(_O_.[[Iterated]], NormalCompletion(*undefined*)).
1. Return CreateIterResultObject(_result_, true).
-
-
- %WrapForValidIteratorPrototype%.throw ( _v_ )
-
- 1. Let _O_ be *this* value.
- 1. Perform ? RequireInternalSlot(_O_, [[Iterated]]).
- 1. Let _iterator_ be _O_.[[Iterated]].[[Iterator]].
- 1. Let _throw_ be ? GetMethod(_iterator_, *"throw"*).
- 1. If _throw_ is *undefined*, return ThrowCompletion(_v_).
- 1. Otherwise, return ? Call(_throw_, _iterator_, « _v_ »).
-
-
@@ -352,16 +316,13 @@ The %WrapForValidAsyncIteratorPrototype% Object
- %WrapForValidAsyncIteratorPrototype%.next ( _value_ )
+ %WrapForValidAsyncIteratorPrototype%.next ( )
1. Let _O_ be *this* value.
1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
1. Let _check_ be Completion(RequireInternalSlot(_O_, [[AsyncIterated]])).
1. IfAbruptRejectPromise(_check_, _promiseCapability_).
- 1. If _value_ is not present, then
- 1. Let _result_ be Completion(IteratorNext(_O_.[[AsyncIterated]])).
- 1. Else,
- 1. Let _result_ be Completion(IteratorNext(_O_.[[AsyncIterated]], _value_)).
+ 1. Let _result_ be Completion(IteratorNext(_O_.[[AsyncIterated]])).
1. IfAbruptRejectPromise(_result_, _promiseCapability_).
1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _result_ »).
1. Return _promiseCapability_.[[Promise]].
@@ -369,39 +330,19 @@ %WrapForValidAsyncIteratorPrototype%.next ( _value_ )
- %WrapForValidAsyncIteratorPrototype%.return ( _v_ )
+ %WrapForValidAsyncIteratorPrototype%.return ( )
1. Let _O_ be *this* value.
1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
1. Let _check_ be Completion(RequireInternalSlot(_O_, [[AsyncIterated]])).
1. IfAbruptRejectPromise(_check_, _promiseCapability_).
- 1. Let _result_ be Completion(AsyncIteratorClose(_O_.[[AsyncIterated]], NormalCompletion(_v_))).
+ 1. Let _result_ be Completion(AsyncIteratorClose(_O_.[[AsyncIterated]], NormalCompletion(*undefined*))).
1. IfAbruptRejectPromise(_result_, _promiseCapability_).
1. Let _iterResult_ be CreateIterResultObject(_result_, *true*).
1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _iterResult_ »).
1. Return _promiseCapability_.[[Promise]].
-
-
- %WrapForValidAsyncIteratorPrototype%.throw ( _v_ )
-
- 1. Let _O_ be *this* value.
- 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
- 1. Let _check_ be Completion(RequireInternalSlot(_O_, [[AsyncIterated]])).
- 1. IfAbruptRejectPromise(_check_, _promiseCapability_).
- 1. Let _iterator_ be _O_.[[AsyncIterated]].[[Iterator]].
- 1. Let _throw_ be Completion(GetMethod(_iterator_, *"throw"*)).
- 1. IfAbruptRejectPromise(_throw_, _promiseCapability_).
- 1. If _throw_ is *undefined*, then
- 1. Perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _v_ »).
- 1. Return _promiseCapability_.[[Promise]].
- 1. Let _result_ be Completion(Call(_throw_, _iterator_, « _v_ »)).
- 1. IfAbruptRejectPromise(_result_, _promiseCapability_).
- 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _result_ »).
- 1. Return _promiseCapability_.[[Promise]].
-
-
@@ -422,24 +363,16 @@ The %IteratorHelperPrototype% Object
- %IteratorHelperPrototype%.next ( _value_ )
+ %IteratorHelperPrototype%.next ( )
- 1. Return ? GeneratorResume(*this* value, _value_, ~Iterator Helper~).
+ 1. Return ? GeneratorResume(*this* value, *undefined*, ~Iterator Helper~).
- %IteratorHelperPrototype%.return ( _value_ )
-
- 1. Let _C_ be Completion { [[Type]]: ~return~, [[Value]]: _value_, [[Target]]: ~empty~ }.
- 1. Return ? GeneratorResumeAbrupt(*this* value, _C_, ~Iterator Helper~).
-
-
-
-
- %IteratorHelperPrototype%.throw ( _exception_ )
+ %IteratorHelperPrototype%.return ( )
- 1. Let _C_ be ThrowCompletion(_exception_).
+ 1. Let _C_ be Completion { [[Type]]: ~return~, [[Value]]: *undefined*, [[Target]]: ~empty~ }.
1. Return ? GeneratorResumeAbrupt(*this* value, _C_, ~Iterator Helper~).
@@ -467,25 +400,17 @@ The %AsyncIteratorHelperPrototype% Object
- %AsyncIteratorHelperPrototype%.next ( _value_ )
+ %AsyncIteratorHelperPrototype%.next ( )
- 1. Let _C_ be NormalCompletion(_value_).
+ 1. Let _C_ be NormalCompletion(*undefined*).
1. Return ! AsyncGeneratorEnqueue(*this* value, _C_, ~Async Iterator Helper~).
- %AsyncIteratorHelperPrototype%.return ( _value_ )
+ %AsyncIteratorHelperPrototype%.return ( )
- 1. Let _C_ be Completion { [[Type]]: ~return~, [[Value]]: _value_, [[Target]]: ~empty~ }.
- 1. Return ! AsyncGeneratorEnqueue(*this* value, _C_, ~Async Iterator Helper~).
-
-
-
-
- %AsyncIteratorHelperPrototype%.throw ( _exception_ )
-
- 1. Let _C_ be ThrowCompletion(_exception_).
+ 1. Let _C_ be Completion { [[Type]]: ~return~, [[Value]]: *undefined*, [[Target]]: ~empty~ }.
1. Return ! AsyncGeneratorEnqueue(*this* value, _C_, ~Async Iterator Helper~).
@@ -518,15 +443,14 @@ Iterator.prototype.map ( _mapper_ )
1. Let _iterated_ be ? GetIteratorDirect(*this* value).
1. If IsCallable(_mapper_) is *false*, throw a *TypeError* exception.
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and _mapper_ and performs the following steps when called:
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? IteratorStep(_iterated_, _lastValue_).
+ 1. Let _next_ be ? IteratorStep(_iterated_).
1. If _next_ is *false*, return *undefined*.
1. Let _value_ be ? IteratorValue(_next_).
1. Let _mapped_ be Completion(Call(_mapper_, *undefined*, « _value_ »)).
1. IfAbruptCloseIterator(_mapped_, _iterated_).
- 1. Set _lastValue_ to Completion(Yield(_mapped_)).
- 1. IfAbruptCloseIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(_mapped_)).
+ 1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Return CreateIteratorFromClosure(_closure_, ~Iterator Helper~, %IteratorHelperPrototype%).
@@ -537,16 +461,15 @@ Iterator.prototype.filter ( _filterer_ )
1. Let _iterated_ be ? GetIteratorDirect(*this* value).
1. If IsCallable(_filterer_) is *false*, throw a *TypeError* exception.
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and _filterer_ and performs the following steps when called:
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? IteratorStep(_iterated_, _lastValue_).
+ 1. Let _next_ be ? IteratorStep(_iterated_).
1. If _next_ is *false*, return *undefined*.
1. Let _value_ be ? IteratorValue(_next_).
1. Let _selected_ be Completion(Call(_filterer_, *undefined*, « _value_ »)).
1. IfAbruptCloseIterator(_selected_, _iterated_).
1. If ToBoolean(_selected_) is *true*, then
- 1. Set _lastValue_ to Completion(Yield(_value_)).
- 1. IfAbruptCloseIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(_value_)).
+ 1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Return CreateIteratorFromClosure(_closure_, ~Iterator Helper~, %IteratorHelperPrototype%).
@@ -561,16 +484,15 @@ Iterator.prototype.take ( _limit_ )
1. If _integerLimit_ < 0, throw a *RangeError* exception.
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and _integerLimit_ and performs the following steps when called:
1. Let _remaining_ be _integerLimit_.
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
1. If _remaining_ is 0, then
1. Return ? IteratorClose(_iterated_, NormalCompletion(*undefined*)).
1. If _remaining_ is not +∞, then
1. Set _remaining_ to _remaining_ - 1.
- 1. Let _next_ be ? IteratorStep(_iterated_, _lastValue_).
+ 1. Let _next_ be ? IteratorStep(_iterated_).
1. If _next_ is *false*, return *undefined*.
- 1. Set _lastValue_ to Completion(Yield(? IteratorValue(_next_))).
- 1. IfAbruptCloseIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(? IteratorValue(_next_))).
+ 1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Return CreateIteratorFromClosure(_closure_, ~Iterator Helper~, %IteratorHelperPrototype%).
@@ -590,12 +512,11 @@ Iterator.prototype.drop ( _limit_ )
1. Set _remaining_ to _remaining_ - 1.
1. Let _next_ be ? IteratorStep(_iterated_).
1. If _next_ is *false*, return *undefined*.
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? IteratorStep(_iterated_, _lastValue_).
+ 1. Let _next_ be ? IteratorStep(_iterated_).
1. If _next_ is *false*, return *undefined*.
- 1. Set _lastValue_ to Completion(Yield(? IteratorValue(_next_))).
- 1. IfAbruptCloseIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(? IteratorValue(_next_))).
+ 1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Return CreateIteratorFromClosure(_closure_, ~Iterator Helper~, %IteratorHelperPrototype%).
@@ -606,15 +527,14 @@ Iterator.prototype.indexed ( )
1. Let _iterated_ be ? GetIteratorDirect(*this* value).
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and performs the following steps when called:
1. Let _index_ be 0.
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? IteratorStep(_iterated_, _lastValue_).
+ 1. Let _next_ be ? IteratorStep(_iterated_).
1. If _next_ is *false*, return *undefined*.
1. Let _value_ be ? IteratorValue(_next_).
1. Let _pair_ be CreateArrayFromList(« _index_, _value_ »).
1. Set _index_ to _index_ + 1.
- 1. Set _lastValue_ to Completion(Yield(_pair_)).
- 1. IfAbruptCloseIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(_pair_)).
+ 1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Return CreateIteratorFromClosure(_closure_, ~Iterator Helper~, %IteratorHelperPrototype%).
@@ -635,11 +555,10 @@ Iterator.prototype.flatMap ( _mapper_ )
1. IfAbruptCloseIterator(_innerIterator_, _iterated_).
1. Let _innerAlive_ be *true*.
1. Repeat, while _innerAlive_ is *true*,
- 1. Let _innerNext_ be Completion(IteratorNext(_innerIterator_)).
+ 1. Let _innerNext_ be Completion(IteratorStep(_innerIterator_)).
1. IfAbruptCloseIterator(_innerNext_, _iterated_).
- 1. Let _innerComplete_ be Completion(IteratorComplete(_innerNext_)).
- 1. IfAbruptCloseIterator(_innerComplete_, _iterated_).
- 1. If _innerComplete_ is *true*, set _innerAlive_ to *false*.
+ 1. If _innerNext_ is *false*, then
+ 1. Set _innerAlive_ to *false*.
1. Else,
1. Let _innerValue_ be Completion(IteratorValue(_innerNext_)).
1. IfAbruptCloseIterator(_innerValue_, _iterated_).
@@ -772,17 +691,16 @@ AsyncIterator.prototype.map ( _mapper_ )
1. Let _iterated_ be ? GetIteratorDirect(*this* value).
1. If IsCallable(_mapper_) is *false*, throw a *TypeError* exception.
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and _mapper_ and performs the following steps when called:
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? Await(? IteratorNext(_value_, _lastValue_)).
+ 1. Let _next_ be ? Await(? IteratorNext(_value_)).
1. If ? IteratorComplete(_next_) is *true*, return *undefined*.
1. Let _value_ be ? IteratorValue(_next_).
1. Let _mapped_ be Completion(Call(_mapper_, *undefined*, « _value_ »)).
1. IfAbruptCloseAsyncIterator(_mapped_, _iterated_).
- 1. Set _mapped_ to Await(_mapped_).
+ 1. Set _mapped_ to Completion(Await(_mapped_)).
1. IfAbruptCloseAsyncIterator(_mapped_, _iterated_).
- 1. Set _lastValue_ to Completion(Yield(_mapped_)).
- 1. IfAbruptCloseAsyncIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(_mapped_)).
+ 1. IfAbruptCloseAsyncIterator(_completion_, _iterated_).
1. Return CreateAsyncIteratorFromClosure(_closure_, ~Async Iterator Helper~, %AsyncIteratorHelperPrototype%).
@@ -793,18 +711,17 @@ AsyncIterator.prototype.filter ( _filterer_ )
1. Let _iterated_ be ? GetIteratorDirect(*this* value).
1. If IsCallable(_filterer_) is *false*, throw a *TypeError* exception.
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and _filterer_ and performs the following steps when called:
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? Await(? IteratorNext(_value_, _lastValue_)).
+ 1. Let _next_ be ? Await(? IteratorNext(_value_)).
1. If ? IteratorComplete(_next_) is *true*, return *undefined*.
1. Let _value_ be ? IteratorValue(_next_).
1. Let _selected_ be Completion(Call(_filterer_, *undefined*, « _value_ »)).
1. IfAbruptCloseAsyncIterator(_selected_, _iterated_).
- 1. Set _selected_ to Await(_selected_).
+ 1. Set _selected_ to Completion(Await(_selected_)).
1. IfAbruptCloseAsyncIterator(_selected_, _iterated_).
1. If ToBoolean(_selected_) is *true*, then
- 1. Set _lastValue_ to Completion(Yield(_value_)).
- 1. IfAbruptCloseAsyncIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(_value_)).
+ 1. IfAbruptCloseAsyncIterator(_completion_, _iterated_).
1. Return CreateAsyncIteratorFromClosure(_closure_, ~Async Iterator Helper~, %AsyncIteratorHelperPrototype%).
@@ -819,16 +736,15 @@ AsyncIterator.prototype.take ( _limit_ )
1. If _integerLimit_ < 0, throw a *RangeError* exception.
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and _integerLimit_ and performs the following steps when called:
1. Let _remaining_ be _integerLimit_.
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
1. If _remaining_ is 0, then
1. Return ? AsyncIteratorClose(_iterated_, NormalCompletion(*undefined*)).
1. If _remaining_ is not +∞, then
1. Set _remaining_ to _remaining_ - 1.
- 1. Let _next_ be ? Await(? IteratorNext(_iterated_, _lastValue_)).
+ 1. Let _next_ be ? Await(? IteratorNext(_iterated_)).
1. If ? IteratorComplete(_next_) is *true*, return *undefined*.
- 1. Set _lastValue_ to Completion(Yield(? IteratorValue(_next_))).
- 1. IfAbruptCloseAsyncIterator(_lastValue_, _iterated_).
+ 1. Set _completion_ to Completion(Yield(? IteratorValue(_next_))).
+ 1. IfAbruptCloseAsyncIterator(_completion_, _iterated_).
1. Return CreateAsyncIteratorFromClosure(_closure_, ~Async Iterator Helper~, %AsyncIteratorHelperPrototype%).
@@ -848,12 +764,11 @@ AsyncIterator.prototype.drop ( _limit_ )
1. Set _remaining_ to _remaining_ - 1.
1. Let _next_ be ? Await(? IteratorNext(_iterated_)).
1. If ? IteratorComplete(_next_) is *true*, return *undefined*.
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? Await(? IteratorNext(_iterated_, _lastValue_)).
+ 1. Let _next_ be ? Await(? IteratorNext(_iterated_)).
1. If ? IteratorComplete(_next_) is *true*, return *undefined*.
- 1. Set _lastValue_ to Completion(Yield(? IteratorValue(_next_))).
- 1. IfAbruptCloseAsyncIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(? IteratorValue(_next_))).
+ 1. IfAbruptCloseAsyncIterator(_completion_, _iterated_).
1. Return CreateAsyncIteratorFromClosure(_closure_, ~Async Iterator Helper~, %AsyncIteratorHelperPrototype%).
@@ -864,15 +779,14 @@ AsyncIterator.prototype.indexed ( )
1. Let _iterated_ be ? GetIteratorDirect(*this* value).
1. Let _closure_ be a new Abstract Closure with no parameters that captures _iterated_ and performs the following steps when called:
1. Let _index_ be 0.
- 1. Let _lastValue_ be *undefined*.
1. Repeat,
- 1. Let _next_ be ? Await(? IteratorNext(_iterated_, _lastValue_)).
+ 1. Let _next_ be ? Await(? IteratorNext(_iterated_)).
1. If ? IteratorComplete(_next_) is *true*, return *undefined*.
1. Let _value_ be ? IteratorValue(_next_).
1. Let _pair_ be CreateArrayFromList(« _index_, _value_ »).
1. Set _index_ to _index_ + 1.
- 1. Set _lastValue_ to Completion(Yield(_pair_)).
- 1. IfAbruptCloseAsyncIterator(_lastValue_, _iterated_).
+ 1. Let _completion_ be Completion(Yield(_pair_)).
+ 1. IfAbruptCloseAsyncIterator(_completion_, _iterated_).
1. Return CreateAsyncIteratorFromClosure(_closure_, ~Async Iterator Helper~, %AsyncIteratorHelperPrototype%).
@@ -890,7 +804,7 @@ AsyncIterator.prototype.flatMap ( _mapper_ )
1. Let _value_ be ? IteratorValue(_next_).
1. Let _mapped_ be Completion(Call(_mapper_, *undefined*, « _value_ »)).
1. IfAbruptCloseAsyncIterator(_mapped_, _iterated_).
- 1. Set _mapped_ to Await(_mapped_).
+ 1. Set _mapped_ to Completion(Await(_mapped_)).
1. IfAbruptCloseAsyncIterator(_mapped_, _iterated_).
1. Let _innerIterator_ be Completion(GetIterator(_mapped_, ~async~)).
1. IfAbruptCloseAsyncIterator(_innerIterator_, _iterated_).
@@ -898,11 +812,12 @@ AsyncIterator.prototype.flatMap ( _mapper_ )
1. Repeat, while _innerAlive_ is *true*,
1. Let _innerNextPromise_ be Completion(IteratorNext(_innerIterator_)).
1. IfAbruptCloseAsyncIterator(_innerNextPromise_, _iterated_).
- 1. Let _innerNext_ be Await(_innerNextPromise_).
+ 1. Let _innerNext_ be Completion(Await(_innerNextPromise_)).
1. IfAbruptCloseAsyncIterator(_innerNext_, _iterated_).
1. Let _innerComplete_ be Completion(IteratorComplete(_innerNext_)).
1. IfAbruptCloseAsyncIterator(_innerComplete_, _iterated_).
- 1. If _innerComplete_ is *true*, set _innerAlive_ to *false*.
+ 1. If _innerComplete_ is *true*, then
+ 1. Set _innerAlive_ to *false*.
1. Else,
1. Let _innerValue_ be Completion(IteratorValue(_innerNext_)).
1. IfAbruptCloseAsyncIterator(_innerValue_, _iterated_).