Mark S. Miller (2015-06-24T22:17:49.000Z)
>
>> Jason Orendorff wrote:
>>
>>> Quick question about function.sent:
>>>
>>> As of ES6, there's this parallel between functions and generators:
>>>
>>>      // how to wrap a function
>>>      // f2 is equivalent to f, if f doesn't use `this`.
>>>      function f(...) { ... }
>>>      function f2(...args) { return f(...args); }
>>>
>>>      // how to wrap a generator
>>>      // g2 is equivalent to g, if g doesn't use `this`.
>>>      function* g(...) { ... }
>>>      function* g2(...args) { return yield* g(...args); }
>>>
>>> That is, λx.f(x) = f, a sort of beta-equivalence rule, and for
>>> generators, you just need to add `yield*` to get an analogous rule. My
>>> understanding is that this is one reason we have `yield*`. (Writing a
>>> wrapping function/generator that also covers `this` is left as an easy
>>> exercise.)
>>>
>>> Given function.sent, is there still a way to "wrap" a generator?
>>>
>>


> On Wed, Jun 24, 2015 at 2:17 PM, Brendan Eich <brendan at mozilla.org> wrote:
>
>> Hrm, the meeting notes don't quite capture it (
>> https://github.com/tc39/tc39-notes/blob/bf5190257d22d1c700e203b28edc8d85ee3aadcc/es6/2015-05/may-27.md
>> is one view; my fault for not editing after), but we have discussed passing
>> function.sent into the sub-generator in the past. Ben Newman first raised
>> the idea the other year, but we finally all came to see at the last (May)
>> meeting that there's no good way to do it in general.
>>
>> When you write a delegating generator that does nothing else, it's
>> tempting to want function.sent delegation. But in general the yield* could
>> want a different first-next param than what was passed down, especially
>> when the delegator looks like this:
>>
>>   function *g2(...args) { prolog code here; maybe-return yield*
>> g(...args); optional epilog here }
>>
>> See the discussion from the May meeting, I'll cite it here:"""
>>
>> MM: But it's passing something from before when yield * is evaluated.
>>
>> DH: I'm beginning to think that this is the wrong path (passing in
>> function.next via yield *).
>>
>> AWB: You could create some kind of wrapper if you wanted to pass in the
>> first value to the subgenerator.
>>
>> MM: Libraries could do this.
>>
>> yield  *  wrap(g,function.next);
>>
>> MM: "wrap" returns an iterator which wraps the generator which primes the
>> subgenerator with the supplied value.
>> """
>>
>> Does this make sense? Sorry again for sparse notes.
>>
>> /be
>>
>>
Something strange and bizarre that Jafar and I just discovered after the
TC39 meeting:

We all know that there are a set of conventional combinators, like flatMap,
that work fine for iterators.

Iterators are uni-directional. Generators are bi-directional. (As Jara
observes: Generator implements Iterator, Observer)

We thought that these combinators did not apply to generators in their full
bidirectional glory. We were wrong.

Flatmap of generators can approximately be modeled in terms of "yield*
wrap" as follows:

flatMap([g1, g2]) is equivalent to

(function*() {
  yield* wrap(g1, function.sent); // result of g1 ignored!
  return yield* wrap(g2, function.sent);
}())



On Wed, Jun 24, 2015 at 3:04 PM, Jason Orendorff <jason.orendorff at gmail.com>
 wrote:

> On Wed, Jun 24, 2015 at 2:17 PM, Brendan Eich <brendan at mozilla.org> wrote:
> > MM: Libraries could do this.
> >
> > yield  *  wrap(g,function.next);
> >
> > MM: "wrap" returns an iterator which wraps the generator which primes the
> > subgenerator with the supplied value.
>
> Thanks for finding this discussion. This is exactly what I'm
> interested in. What does "wrap" look like? It seems like it would be
> pretty involved.
>

Just showing the next method:

function wrap(g, prime) {
  let first = true;
  return {
    next(val) {
      if (first) {
        first = false;
        return g.next(prime);
      } else {
        return g.next(val);
      }
    }
    //...
  };
}


ALL CODE I WROTE ABOVE IS UNTESTED.

Does this make sense? If anyone tests it, does it work?


-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150624/27c4dea5/attachment-0001.html>
d at domenic.me (2015-07-07T02:07:22.330Z)
Something strange and bizarre that Jafar and I just discovered after the
TC39 meeting:

We all know that there are a set of conventional combinators, like flatMap,
that work fine for iterators.

Iterators are uni-directional. Generators are bi-directional. (As Jara
observes: Generator implements Iterator, Observer)

We thought that these combinators did not apply to generators in their full
bidirectional glory. We were wrong.

Flatmap of generators can approximately be modeled in terms of "`yield*` wrap" as follows:

```js
flatMap([g1, g2])
```

is equivalent to

```js
(function*() {
  yield* wrap(g1, function.sent); // result of g1 ignored!
  return yield* wrap(g2, function.sent);
}())
```


On Wed, Jun 24, 2015 at 3:04 PM, Jason Orendorff <jason.orendorff at gmail.com> wrote:

> Thanks for finding this discussion. This is exactly what I'm
> interested in. What does "wrap" look like? It seems like it would be
> pretty involved.

Just showing the next method:

```js
function wrap(g, prime) {
  let first = true;
  return {
    next(val) {
      if (first) {
        first = false;
        return g.next(prime);
      } else {
        return g.next(val);
      }
    }
    //...
  };
}
```

ALL CODE I WROTE ABOVE IS UNTESTED.

Does this make sense? If anyone tests it, does it work?