Questions/issues regarding generators

Claus Reinke claus.reinke at talk21.com
Thu Mar 7 08:29:39 PST 2013


> But, in order to (hopefully) let Brandon calm down a bit, I am NOT making
> yet another proposal for a two-method protocol. Instead I propose
> simply _delivering_ a sentinel object as end-of-iteration marker
> instead of _throwing_ one. The zip function above would then be written as:
> 
>  function zip(iterable1, iterable2) {
>    let it1 = iterable1.iterator()
>    let it2 = iterable2.iterator()
>    let result = []
>    while (true) {
>      let x1 = it1.next(), x2 = it2.next()
>      if (isStopIteration(x1) || isStopIteration(x2)) return result
>      result.push([x1, x2])
>    }
>  }

'it.next()' needs to serve two purposes: yielding an arbitrary object
or signaling end of iteration. Using exceptions gives a second channel, 
separate from objects, but now there is potential for confusion with
other exceptions (and using exceptions comes with unwanted cost).

So, really, both the arbitrary object channel and the exception channel
are already taken and not freely available for iteration end.

How about lifting the result, to separate yielded objects and end
iteration signalling?

    { yields: obj }    // iteration yields obj
    {} // iteration ends

Then we could use refutable patterns to generate end exceptions

   while (true) {
     let { yields: x1 } = it1.next(), { yields: x2 } = it2.next() // throw if no match
     ...    

or test for end without exceptions

   while (true) {
     let x1 = it1.next(), x2 = it2.next()
     if ((!x1.yields) || (!x2.yields)) return result
     result.push([x1.yields, x2.yields])
   }

Claus
 


More information about the es-discuss mailing list