Brendan Eich (2014-10-06T16:37:04.000Z)
Brendan Eich wrote:
> This meansMap.prototype.mapetc. -- or %ItereablePrototype%.map if not 
> Array.prototype.map etc. -- are the eager collection-generic companions.

Bear with me, trying to develop a half-thought. To say it with code:

```js
Object.defineProperty(%IteratorPrototype%, 'map', {
     value: function (fun) {
         return function* (iter) {
             for (let [key, val] of iter) {
                 yield fun(val, key);
             }
         }(this.clone());
     },
     configurable: true,
     enumerable: false,
     writable: true
});
```

Note the this.clone() call. This is novel, and required to avoid 
exhausting the receiver iterator.

Rather than %IterablePrototype%, which is too generic a name (it does 
not imply a key/value map), we need something such as %MaplikePrototype% 
or %CollectionPrototype%:

```js
Object.defineProperty(%CollectionPrototype%, 'map', {
     value: function (fun) {
         let result = new this.constructor();
         for (let [key, val] of this) {
             result.set(key, val);
         }
         return result;
     },
     configurable: true,
     enumerable: false,
     writable: true
});
```

The Collection protocol thus consists of at least .constructor, 
@@iterator, .set. (Is there a better way to clone? Don't want a new 
protocol where an old one will suffice!) This Collection protocol would 
include Map and maplikes but leaves out Set, Array, Object -- appropriately.

We could just use FP-style map, filter, etc. APIs, but as argued among 
TC39ers, OOP wins in JS: (a) it matches built-ins; (b) it composes left 
to right, not inside out.

This argument implies a %CollectionPrototype% object full of 
protocol-generic methods, to avoid rewriting collection methods all over 
the place (wherever there is a maplike), or borrowing Map.prototype.* 
references by hand and monkeypatching them into maplike prototypes.

Unless I'm mistaken, the OOP-ness also implies other stuff, like a way 
to clone an iterator.

I hope this makes sense. Comments welcome.

/be
forbes at lindesay.co.uk (2016-02-01T13:02:53.869Z)
Bear with me, trying to develop a half-thought. To say it with code:

```js
Object.defineProperty(%IteratorPrototype%, 'map', {
     value: function (fun) {
         return function* (iter) {
             for (let [key, val] of iter) {
                 yield fun(val, key);
             }
         }(this.clone());
     },
     configurable: true,
     enumerable: false,
     writable: true
});
```

Note the `this.clone()` call. This is novel, and required to avoid exhausting the receiver iterator.

Rather than `%IterablePrototype%`, which is too generic a name (it does 
not imply a key/value map), we need something such as `%MaplikePrototype%`
or `%CollectionPrototype%`:

```js
Object.defineProperty(%CollectionPrototype%, 'map', {
     value: function (fun) {
         let result = new this.constructor();
         for (let [key, val] of this) {
             result.set(key, val);
         }
         return result;
     },
     configurable: true,
     enumerable: false,
     writable: true
});
```

The Collection protocol thus consists of at least `.constructor`, 
`@@iterator`, `.set`. (Is there a better way to clone? Don't want a new 
protocol where an old one will suffice!) This Collection protocol would 
include Map and maplikes but leaves out Set, Array, Object -- appropriately.

We could just use FP-style map, filter, etc. APIs, but as argued among 
TC39ers, OOP wins in JS: (a) it matches built-ins; (b) it composes left 
to right, not inside out.

This argument implies a `%CollectionPrototype%` object full of 
protocol-generic methods, to avoid rewriting collection methods all over 
the place (wherever there is a maplike), or borrowing `Map.prototype.*` 
references by hand and monkeypatching them into maplike prototypes.

Unless I'm mistaken, the OOP-ness also implies other stuff, like a way 
to clone an iterator.

I hope this makes sense. Comments welcome.