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 <[email protected] <mailto:[email protected]>> 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 _ <[email protected]
    <mailto:[email protected]>> 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
    [email protected] <mailto:[email protected]>
    https://mail.mozilla.org/listinfo/es-discuss
    <https://mail.mozilla.org/listinfo/es-discuss>



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to