Iterator.filter counts every source value examined by its predicate, including values that never appear in the output. Because the helper is lazy, one request for a selected value may trigger several source pulls. This guide separates predicate index, output position and source state with reproducible event ledgers.
This specialist guide belongs to the Websites root. It also connects to The Gold Standard of Education | Learning That Transfers into Life and the How X Works hub. The worked cases are original teaching examples; their numbers are stipulated so that the reasoning can be checked.
eduKateSG · Websites
Find your next learning step
Trace lazy Iterator.filter predicate indices across rejected values, selected yields, helper composition, abrupt completion and iterator closing.
ROUTE 2 · CHAPTERS 4–6
Follow the decisive mechanism
Work through counters, pulls, calls and yields in their observable order.
ROUTE 3 · CHAPTERS 7–9
Change the context
Change one condition and rebuild the trace from the changed premise.
ROUTE 4 · CHAPTERS 10–12
Handle limits and evidence
Test closing, errors, shared state and evidence that separates rival explanations.
ROUTE 5 · CHAPTERS 13–15
Use and explain the result
Turn the mechanism into dependable tests, reviews and learner explanations.
Chapter contents
Build the first model · Chapters 1–3
1. Separate source index from output position
Follow the decisive mechanism · Chapters 4–6
4. Advance the counter through rejection
Change the context · Chapters 7–9
Handle limits and evidence · Chapters 10–12
10. Close after consumer return
Use and explain the result · Chapters 13–15
CHAPTER 1 OF 15 · Build the first model
1. Separate source index from output position
Iterator.filter passes each source value and a zero-based source counter to its predicate. The counter advances after every predicate call, including calls that reject a value, while the helper yields only selected values. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. A source yields 4, 7, 8 and the predicate keeps even values. Calls are (4,0), (7,1), (8,2); outputs are 4 then 8, at output positions zero and one. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Insert rejected value 5 before 8. The second output remains 8 but its predicate index becomes three. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Output position cannot reconstruct predicate index when any earlier value was rejected. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
Calling filter validates the receiver and predicate and returns a helper; it does not immediately pull the first source value or call the predicate. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Create a generator that logs before each yield, call filter, and observe an empty log until helper.next is requested. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Request only one selected value. The helper may inspect several source values but stops once it can yield that selected value. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Do not describe filter as having already scanned the source merely because the helper object exists. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
One helper next request can perform multiple source pulls because rejected values are skipped internally until a selected value, exhaustion or error appears. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. The source yields 1, 3, 4; an even predicate makes the first helper.next pull and test indices zero, one and two before yielding 4. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Change 3 to 2. The first helper result is now 2 after two predicate calls, leaving 4 unconsumed. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. One consumer pull does not imply one source pull for a filtering helper. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
CHAPTER 4 OF 15 · Follow the decisive mechanism
4. Advance the counter through rejection
The counter increments after a normal false predicate result just as it does after a true result and completed yield. Rejection affects output, not whether the source event is counted. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Values A, B, C return false, false, true. The predicate sees indices zero, one, two and the first output is C. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Change B to true. It becomes the first output at predicate index one; C waits for the next helper request. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Never increment an output counter only when the predicate succeeds and call it the predicate index. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
The predicate result is converted to Boolean. Values such as zero, empty string and null reject; objects, including empty arrays, select. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Return index modulo two: zero rejects A, one selects B, zero rejects C. Record raw callback results before Boolean conversion. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Return an object containing the decision instead. Every object is truthy, so every value is selected unless a Boolean property is returned explicitly. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. A descriptive object is not automatically interpreted by its fields. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
When the underlying iterator reports done, the helper completes without another predicate call. Later next requests remain done and do not restart the source. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. After selected values 2 and 4, the next source step reports done; the helper returns done and the predicate log contains only two entries. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Use an empty source. The first helper next reports done with no predicate calls. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. The final done pull is an iterator step but has no value or predicate index. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
Indices belong to source events, not value identity. Repeated equal values receive different counters when they are produced at different times. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. A source yields 5 three times and the predicate selects only index one. The middle 5 is yielded even though all values compare equal. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Select by value instead; all three equal values now share the same decision while their indices remain zero, one and two. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Searching the source for a value cannot recover which repeated occurrence the callback saw. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
A downstream take can stop after a bounded number of selected outputs. Rejected source values still count for filter, and early downstream completion can close the filter and its source. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Filter positive values from -2, -1, 3, 4, then take one. The selected 3 arrives with filter index two; 4 need not be pulled. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Take two instead. The source advances to 4 and the filter predicate receives index three. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. The take limit counts yielded helper values, not values examined by the filter predicate. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
When map follows filter, the filter predicate counter counts source values while the map callback counter counts values that passed the filter. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Source 1,2,3,4; filter evens sees indices zero through three; map sees 2 at zero and 4 at one. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Move map before filter. Map now sees all four source values and the downstream predicate examines mapped results. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Counters in adjacent helpers are local to their own closures and need not match. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
Returning from the helper before exhaustion invokes helper return behaviour and closes the underlying iterator through the helper protocol. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. A generator with finally yields 2 then 4. After consuming one selected value, call helper.return and record the generator cleanup. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Fully exhaust the helper instead. Cleanup follows normal source completion rather than an early return request. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Dropping a JavaScript reference is not the same observable operation as calling return. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
An abrupt predicate completion closes the underlying iterator and propagates the error; no normal selected result is produced for that value. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. The predicate accepts 2 and throws on 3. The first helper next yields 2; the second pull logs 3, the throw and generator finally. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Throw on the first value. No helper value is yielded before closing. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Do not catch the error and present a partial output as a completed filtering result without an explicit recovery policy. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
CHAPTER 12 OF 15 · Handle limits and evidence
12. Separate source failure from predicate failure
A failing next operation occurs before the predicate for that step, so no callback index is observed for a value that was never obtained. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. The source yields A at index zero, then its next method throws. Record one predicate call and the source error. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Move the failure after yielding B. The predicate receives index one for B before the later failure. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. A count of next attempts can exceed the count of predicate calls. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
A helper consumes the same underlying iterator record. Other consumers that advance the source can change which value and counter the helper sees next. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Create filter over an iterator, consume one raw value directly, then request the helper. Its counter starts with the next available source value even though that value was originally second. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Let the helper consume first, then call the raw iterator. The raw call observes the value left after the helper found a selection. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. The helper counter is local to helper consumption, not a permanent ordinal stored on each record. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
A strong fixture includes rejected values before and between accepted values, repeated values, a return method and a possible throw. It asserts events as well as outputs. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Log next:1, pred:1:0:false, next:2, pred:2:1:true, yield:2, then stop early and log return. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Change only the predicate decision for 1 and confirm that the first output and remaining source state both change. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. An all-true fixture cannot reveal the difference between source index and output position. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
A complete account names laziness, source pulls, predicate value/index pairs, Boolean decisions, yielded values, stopping reason and cleanup. Begin with the exact receiver, the underlying iterator and the operation that advances it. A familiar array analogy can help with vocabulary, but the event order must come from the iterator-helper contract being studied.
Worked case. Report that 1 and 3 were rejected at indices zero and one before 4 was selected at index two, then the consumer returned and the source closed. Write a ledger with one row for every source pull, callback call, result, yield, completion and return. This makes the counter and stopping point observable instead of leaving them hidden inside a final array or Boolean.
Trace the case from left to right. Validate the callback first, create or enter the helper, request the next source value, apply the callback with the stated counter, and only then decide whether a value is yielded or the operation stops. Do not skip a rejected value or a non-yielding event in the ledger.
Changed-context check. Changed report: 3 becomes selected, so the first request stops earlier and 4 remains unconsumed. Rebuild the entire trace from the changed premise. Compare the first event that differs, the values that were already consumed and the state left in the underlying iterator; those facts show whether the first explanation transfers.
Limit and misconception check. Do not reduce the mechanism to filter removes false items; that phrase omits timing, counters and closure. State the narrow claim supported by the fixture. A result from a finite generator does not by itself establish behaviour for an infinite source, a throwing callback, a shared iterator or a consumer that stops early.
For a practical evidence check, add logging to next, return and the callback. Assert the ordered log as well as the returned value. A snapshot of final output can hide rejected values, extra pulls, early closing and counter changes, so it is weak evidence for protocol behaviour.
A useful review asks three separate questions: what did the source produce, what did the callback receive, and what did the consumer observe? Keep those answers separate. When they are collapsed into one idea of position, subtle off-by-one and cleanup errors become difficult to see.
Transfer this chapter into a short Websites explanation with four parts: the starting state, the decisive protocol step, the changed-context result and the remaining caveat. That structure gives a learner a reusable model without turning one invented fixture into a universal rule.
Continue with connected lessons
Trace Iterator.take limits and closing
Trace Iterator.take limits and closing. See how a downstream limit stops a lazy pipeline and closes its source.
Trace Iterator.drop before the first yield
Trace Iterator.drop before the first yield. Compare a helper that consumes source values without a predicate.
Trace Iterator.flatMap inner iterators
Trace Iterator.flatMap inner iterators. Extend the event ledger to a helper that can yield several values per outer pull.
Frequently asked questions
Does a rejected value increment the predicate index?
Yes. The counter advances after every normal predicate call, whether its result is truthy or falsey.
Is the callback index the output position?
Only in special all-selected fixtures. Rejections make the two positions diverge.
Does filter run when I create the helper?
No. Source pulls and predicate calls begin when the helper is advanced.
Can one helper next call pull several source values?
Yes. It continues until it finds a selected value, reaches exhaustion or encounters an error.
What happens when the predicate throws?
The underlying iterator is closed and the error propagates.
What should a test log?
Log source next and return calls, predicate value/index pairs, helper results and errors.
Authoritative sources and further reading
ECMAScript: Iterator.prototype.filter. Normative lazy closure, predicate arguments, selection and counter progression.
ECMAScript: Iterator Helper Objects. Helper next, return and underlying-iterator behaviour.
ECMAScript: IteratorClose. Normative cleanup for early or abrupt completion.
Return to the Websites subject guide, The Gold Standard of Education, or the How X Works hub.