Closed js-choi closed 3 years ago
It would be good to understand how this proposal works on the following example:
for (let key of map.keys()) {
}
Right now it looks like it would be rewritten using this proposals as
for (let key of {[Symbol.iterator]: map->(Map.prototype.keys)}) {
}
This in turn exposes the mutable Map Iterator instance that doesn't really have a way to protect against .next
mutation. E.G.
// stops the loops
Object.getPrototypeOf(new Map().entries()).next = function () {return {done: true, value: 'hi'};};
const myMap = new Map([[1,1],[2,2]]);
for (const x of myMap) {
console.log({x})
}
for (const x of myMap) {
console.log({x})
}
for (const x of myMap) {
console.log({x})
}
I do agree for functional approaches that this proposal does enhance the ability to write robust code but it seems difficult / unlikely to actually protect against OO robustness and could lead to confusion.
Yes, due to the design of MapIterator this proposal doesn't address it directly.
However, you could do const mapKeys = new Map().keys()[Symbol.iterator]; map→keys()→mapKeys()
just fine, so i'm not sure what the concern is.
That would still fail to execute the loops. I'm stating that this proposal should be wary of OO patterns which are often off of Symbol protocols since it does cause problems. These OO problems are much harder to mitigate than the existing bind pattern. I'm unclear a bit on the claims of robustness holding up as a goal if it leads to pitfalls like this. The issue was about problems, which still exists. Wether it is in scope or not is not really easy to discern without going to plenary, but I would state at least from the readme this is a concern given that it gives a false sense of robustness.
Aside from Symbol.iterator, Symbol protocols are hardly ever used - but I’m still very confused here. Symbols and strings are identical.
I see how it gets tricky if the code you’re writing uses one method access (string or symbol) to produce a new object, on which you then do another method access (string or symbol) - but that’s the same problem no matter what kind of property key is used.
Maybe we can just rename this to interoperability with OO based protocols?
It’s not just OO-based tho - that’s what Array slice is. It’s the specific pattern of one method in an X returning a new kind of object Y, which then needs its own methods saved with this operator.
This is a rare pattern other than the builtin iterator types, but again, for those, i think you could still do the same things - it’s just trickier to get at them since they’re not globals in the first place. Luckily there’s another proposal for getting intrinsics :-p
Perhaps interoperability with things that return Objects?
Much better, but it’s even a tiny subset of that - things that return objects that aren’t directly accessible (globally, or importable/requireable).
@ljharb I don't think indirect access is necessary since Map.prototype for example is directly accessible and since this proposal predicates early access anyway you can just call it eagerly to get the stuff.
Right but there’s no ergonomics issue with Map.prototype - only with, eg, MapIterator.prototype, unless I’m misunderstanding something. (this all ofc assumes first-run code)
I’m going to close this problem as out of scope. Although improving the Node primordials situation is one of the goals of this proposal, I’ve refocused its greater thrust onto “bind/call/apply are very common but they are clunky” (#8). This problem seems to be pretty rare even within the primordials use case, anyway. Let me know if there’s anything else actionable that we can do here.
In tc39/proposal-extensions#11, @bmeck wrote the following:
Because this repository is meant as a simplified successor to the old bind-operator proposal and as an alternative to tc39/proposal-extensions, I opened an issue here.
Having said that, I am not quite sure I understand the quoted concerns. This proposal works with symbol-based protocols. And, in this proposal, no arguments (other than the
this
value) are bound.Either of these would simply work:
CC: @ljharb