tc39 / proposal-set-methods

Proposal for new Set methods in JS
https://tc39.github.io/proposal-set-methods/
Other
657 stars 15 forks source link

Why do some methods copy this.[[SetData]] and others don't? #96

Closed Josh-Cena closed 1 year ago

Josh-Cena commented 1 year ago

union, difference, and symmetricDifference all make copies of this.[[SetData]] before iterating this. This ensures that calling other.has() can never affect this.[[SetData]]. I wonder why we don't use this pattern for other methods—this makes intersection and difference appear very inconsistent, and also makes concurrent modifications hard to explain in docs.

bakkot commented 1 year ago

difference does copy this.[[SetData]], so I assume you're talking only about intersection.

The reason intersection does not copy this.[[SetData]] is because it would make the algorithm O(size of receiver) instead of O(size of result) - in other words, intersecting an extremely large set with an extremely small set would take time proportional to the extremely large set, which would be bad.

I don't think that docs should say anything about concurrent modifications except that they should be avoided. This is unlikely to come up in real life (it is very unusual for a set-like data structure to have a has method which has the side effect of mutating some other set), so it's not something worth going into detail about.

Josh-Cena commented 1 year ago

difference does copy this.[[SetData]], so I assume you're talking only about intersection.

I meant that they are inconsistent, because difference is $\{x\in A\mid x\notin B\}$ while intersection is $\{x\in A\mid x\in B\}$, so I expect them to use very similar algorithms.

The reason intersection does not copy this.[[SetData]] is because it would make the algorithm O(size of receiver) instead of O(size of result) - in other words, intersecting an extremely large set with an extremely small set would take time proportional to the extremely large set, which would be bad.

Thanks, that makes sense 👍

I don't think that docs should say anything about concurrent modifications except that they should be avoided.

I can try to avoid this part, but any holes in the docs look like a bad sign. We do document what happens with array method concurrent modifications. We can attempt to explain it conceptually without referring to algorithmic steps, but it is going to be hard.

bakkot commented 1 year ago

I can try, but any holes in the docs look like a bad sign.

Well, it's up to you, but for my part I would not say anything beyond "This method may produce inconsistent results if the argument's has method or keys iterator has the side effect of mutating the receiver."

We do document what happens with array method concurrent modifications.

Arrays methods callbacks, which often have side effects - that's a pretty different thing from having a data structure where querying that data structure mutates some other data structure.

Josh-Cena commented 1 year ago

Since my question is answered, I'll close this. Thanks!