4 ms·
It works fine on objects. const set = new Set(); const x = { id: 'some object' }; foo.add(x); foo.has(x); > true I'm guessing you're taking issue wi
by wk_end 3y ago
It works fine on objects.
const set = new Set();
const x = { id: 'some object' };
foo.add(x);
foo.has(x);
> true
I'm guessing you're taking issue with the fact that it uses reference equality instead of structural equality, which can definitely be a pain point. There's a proposal to improve the situation with "Records and Tuples" [0], but it's been stuck in committee hell for years.
[0] https://github.com/tc39/proposal-record-tuple https://github.com/tc39/proposal-record-tuple
- leosanchez 3y ago> I'm guessing you're taking issue with the fact that it uses reference equality instead of structural equality That and other programming languages provide a mechanism to specify a property to check for value equality.
- solardev 3y ago(Not directed at you, but the JS implementation) I don't understand the point of this. What good is an object in a Set if it can't be deduped? With this and so much else in the core language, I wish they just incorporated lodash into Ecmascript and called it a day. https://lodash.com/docs/4.17.15#uniqWith https://lodash.com/docs/4.17.15#uniqWith (the example is specifically for comparing objects by value) > but it's been stuck in committee hell for years. It's been like this for more than a decade, too. I've never seen a popular language evolve SO slowly, whether it's with Sets, or things like the Temporal API or TypeScript or JSX or bundlers. Almost all the innovation in JS seems to come from third parties forced to hack them in, whether through vendor prefixes, jQuery, or later ecosystems like npm libs and React. In that same time period, PHP improved by leaps and bounds, entire languages like Rust came out of nowhere and gained a foothold, WASM was developed, etc. And lodash is STILL around and still useful. It's so frustrating to watch.
- Gare 3y agoThat's the curse of a language that has to be supported by several competing implementations, and therefore all have to agree on any additions. Also, it's important not to "break the web".
- solardev 3y agoWould it really break the web to have a basic, standard implementation of "compare object by value"? Or a first-party type system? I think the inverse can also be true, where the core language / TC39 is over-cautious with feature adoption, leading to extreme ecosystem fragmentation and eighteen vendors reinventing the same three wheels every year.
- ameliaquining 3y agoMy understanding of the problem with records-and-tuples (which is what "objects comparable by value" would look like) that's kept it stalled out is that it breaks all the engines' internal assumptions about how things work, so they'd have to do a large amount of refactoring, and they'd have to do it in a way that doesn't regress performance for code that doesn't use the new features. Given how complicated modern JS engines are, this is just a lot of work and a big ask. I do hope that it happens eventually. As for a first-party type system, would you want it to basically be TypeScript, or something else? If the former, then we'd lose a lot of features and such, because the core language, not being a single vendor, can't move as fast as TypeScript does. If the latter, then it would be necessary to define what, and in all likelihood different people would want different and incompatible things.
- TurningCanadian 3y agoIt seems like they're worried that interning of objects/records would be too expensive to do generally. It's hard to predict though: that overhead would only apply to new code using R&T and has to be weighed against the elimination of recursion for deep comparisons and freezing, fewer re-renderings when value-equal but not reference-equal objects are encountered, the greater possibility of memory reuse across deep clones, and other performance optimizations that would be unlocked by true immutability. Aside from performance, true native immutability would bring huge improvements to how JS programmers can reason about their code. Not having to worry about mutation makes a whole class of possible bugs disappear. Having to rely on third party libraries (or deep freezing manually) for immutability is really holding back the language.
- slibhb 3y agoJS sets are plenty useful. Sometimes you want reference equality for objects (though letting programmers choose would be ideal). As far as the pace, I think they do it about right. JS has hard requirements to be backwards compatible and has several canonical implementations, so adding new features should only be done after careful consideration. Letting users add features themselves and ensuring they have staying power and wide adoption is a good test.
- joe_guy 3y ago> JS sets are plenty useful. Sometimes you want reference equality for objects An example of where I've found this useful is object cycle detection.
- shadowgovt 3y agoIt's probably about the right speed for a language with an implementation as complicated as this that's unfortunately stumbled backwards into enabling all web page dynamic behavior on the planet. JavaScript is a secure language and therefore doesn't have the luxury of a language like C++ where you can mash two features in and declare their interaction "undefined behavior." Every new feature must eventually be considered in the context of every other feature.
- seniorsassycat 3y agoInstead, or in addition to records and tuples I want Symbol.equals or some other interface for equality.
- The_Colonel 3y agoYou'd also need Symbol.hashCode, since you wouldn't be able to implement a fast lookup just with equals method.
- spion 3y agoWhile that could help, I don't see why records and tuples are necessary. We added symbols precisely to deal with this issue in a backward compatible way. We could add symbols for set/map protocols using `equals` and `getHashCode` which would enable any objects to get set/map deduplication functionality. Those implementation could then be the mechanism how its implemented for records and tuples. If this is a bad way to do it, then why isn't TC39 working on a better way to implement protocols / traits in JS?
- spion 3y agorelevant issue, which is at the crux of this problem: https://github.com/tc39/proposal-record-tuple/issues/387 https://github.com/tc39/proposal-record-tuple/issues/387 and which shows that a symbol based protocol was the kind of approach that could've worked from the start. See `Symbol.keyEquality` - although that still shows what I feel is a misunderstanding about the direction at which the protocol should work. I don't want to be creating new types of maps and sets, I want existing ones to have controllable key equality. If it was for new types of maps and sets, I'd just implement a new Set class independent of JS builtins and be done with it. (Its not like the built in Set offers any rich features that I'd have a hard time replicating anyway) Protocols (traits) should really be the cornerstone of TC39 work, IMO. They'll help with JavaScript's serious ecosystem compatibility issues.