Object.isEqual

Steve Fink sphink at gmail.com
Mon May 1 23:28:56 UTC 2017


On 05/01/2017 03:15 PM, Alexander Jones wrote:
> No I was not proposing that it actually *be* stringified-comparison... 
> or in any way be related to the JSON global.
>
> * Property order would not be important for equality. Precedent is set 
> by common sense.
> * Reference semantics (i.e. visitation) would be exactly as you'd 
> expect - look at Python's `dict` implementation for IMO the only 
> obvious answer.
> * I acknowledged specifically that JSON does not support all types, 
> just use SameValueZero for primitives and be done with it.
> * Cycles are a subset of all possible reference semantics.
> * Getters should be called. It already works for JSON and I don't hear 
> anyone complaining about it. (Maybe I wasn't listening?) - same for 
> prototype chain questions...

If there is any possibility that anything has a getter, anywhere in the 
tree you're comparing, then you will have to do a full tree traversal. 
Even if you're comparing an object to itself. Both

     isEqual({'foo': giantHugeObject}, {'foo': giantHugeObject});

and

     isEqual(giantHugeObject, giantHugeObject);

have to traverse through giantHugeObject in order to find any getters to 
invoke, which will be far slower than a simple JS function that 
short-circuits if things are ===. But then what's the point?

Arguably, an engine could *know* that neither of the objects has any 
nontrivially-comparable children, but that requires fancy type tracking 
(eg if someone does a setPrototypeOf, you'd better be able to find 
everything affected and invalidate that compares-fast bit.)

As you point out, Maps are simpler. Map keys can't have getters (though 
I guess a Proxy of a Map could?). Maybe there's more hope for a Map.isEqual?

>
> That said, most of these questions evaporate if people would just 
> start using Map for things. AFAIAC the main reason people don't is due 
> to the absence of a Map literal and JSON parsing tending to give you 
> Object back instead of a more appropriate type without such weirdness 
> as prototypes and property descriptors (yes, I went there!).
>
>
>
> On 1 May 2017 at 22:55, Steve Fink <sphink at gmail.com 
> <mailto:sphink at gmail.com>> wrote:
>
>     It would be nice to have *something* for this. Some remaining
>     problems I see with using JSON serialization, let's call it
>     JSON.isEqual:
>      - JS has order, JSON does not
>      - JSON lacks NaN, +/-Infinity (and JSON.stringify maps these to
>     null, which means JSON.isEqual({x: 0/0}, {x: 1/0}))
>      - cycles
>      - ...and everything under your "trivial generalisation"
>
>     It still seems like it'd be unfortunate if !JSON.isEqual({foo:
>     val1}, {foo: val2}) where val1 === val2 (because val1/2 is not
>     serializable, eg it has a cycle).
>
>
>     Also, what is
>
>         var x = 4;
>         JSON.isEqual({get foo() { return x++; }}, {foo: 4})
>
>     ? If you went purely by "whatever JSON.stringify would return",
>     then this would be true once and false afterwards.
>
>     This may seem like nitpicking, but if you don't nail down the
>     exact semantics, then engines will end up doing the JSON
>     serialization and a string compare, which rather defeats the
>     purpose. If you stick to something simple like comparing
>     JSON.stringify output, then they will pretty much *have* to do
>     this, since there are so many observable side effects like getter
>     invocation and proxy traps. You *could* define semantics that
>     cover a large percentage of the interesting cases, but JSON isn't
>     going to be of much help.
>
>     And for the record, JSON does not have an intuitive semantics at
>     all. It has intuitive semantics for a small subset of values, a
>     subset that is rarely adhered to except near interchange points
>     where JSON makes sense. (And even then, it's common to
>     accidentally step outside of it, for example by having something
>     overflow to Infinity or accidentally produce a NaN.)
>
>     On 05/01/2017 02:04 PM, Alexander Jones wrote:
>>     I hear this argument a lot but it strikes me with cognitive
>>     dissonance! JSON defines a very intuitive notion of object
>>     value-semantics - whether the serialized JSON is an equivalent
>>     string. Granted that many value types are not supported by JSON,
>>     but it's a trivial generalisation.
>>
>>     Let's just give the above a name and get on with it. For 99% of
>>     use cases it would be ideal, no?
>>
>>     Thoughts?
>>
>>     On 1 May 2017 at 20:58, Oriol _ <oriol-bugzilla at hotmail.com
>>     <mailto:oriol-bugzilla at hotmail.com>> wrote:
>>
>>         This is not easy to generalize. Comparing objects is one
>>         thing lots of people want, but not everybody needs the same
>>         kind of comparison.
>>         For example, you compare own property strings. But what about
>>         symbols? Somebody might consider two objects to be different
>>         if they have different symbol properties.
>>         Or the opposite, somebody may think that checking enumerable
>>         properties is enough, and non-enumerable ones can be skipped.
>>         Then some property values might be objects. Are they compared
>>         with === or recursively with this algorithm (be aware of cycles)?
>>         Similarly, for the [[Prototype]]. Do inherited properties
>>         matter? Should [[Prototype]]s be compared with === or
>>         recursively?
>>         There is also the problem of getters: each time you read a
>>         property, it might give a different value! You might want to
>>         get the property descriptor and compare the values or the
>>         getter functions.
>>         And then there are proxies. Taking them into account, I don't
>>         think there is any reasonable way to compare objects.
>>
>>         So I think it's better if each person writes the code that
>>         compares objects according to their needs.
>>
>>         --Oriol
>>
>
>
>     _______________________________________________
>     es-discuss mailing list
>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     https://mail.mozilla.org/listinfo/es-discuss
>     <https://mail.mozilla.org/listinfo/es-discuss>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170501/f0c010aa/attachment.html>


More information about the es-discuss mailing list