Repository navigation
Define identity/equality operators - #710
Conversation
annevk
left a comment
There was a problem hiding this comment.
Do we really need three types? I don't understand why we can't define equals for lists. I also think that giving "equivalent" a normative meaning will be quite awkward as we often use it in notes and such to mean something else.
I also somewhat strongly prefer "is" over "identical". As it becomes more common having to scan over the long form will be annoying.
I was going by the discourse on the issue... I am not sure if deep-equals/equivalent is necessary or if it currently would be used by anyone. I am ok with dropping it for the time being. Sure we can define equals for lists/maps etc, I was going by the discourse.
"Identical to" was already defined for strings and in some sentences it fits more naturally, as in "a and b are identical". Both forms are exported so perhaps it's ok to leave the choice to embedders? |
|
Okay, thinking about this some more I think we want to borrow more of the original issue's ideas:
I'm not sure how we should deal with cyclic references or whether lists/maps/structs should have a default equality that's not null. Perhaps we should start out with them not having a default and asserting until we get a bit more comfortable with it. |
This seems unnecessary. It should fall back to shallow-equals/identity. E.g a map of map of structs where one of the struct items is a platform object - it's ok if those are compared by reference and everything else is deep-equals.
|
|
For platform objects it seems okay to default (or enforce?) all of them to identity for their equality, but that should probably be in Web IDL. |
Not sure I like this model. Maybe it is better to defer deep equality for now? Not sure if it has existing users? |
|
I think Sanitizer essentially wants something like that? Not having equals for lists or maps at all probably won't work. |
Sanitizer just needs to define equality for the SanitizerConfig dictionaries such as SanitizerElement, and then all the map/list algorithms (mainly contains) should refer to that. It doesn't need to deeply compare entire lists. |
|
I guess we don't have to define (unordered) deep equals for v1, but I think the point around equals and equality still stands. And so we'd still have to define somewhere what equality means for platform objects since I don't think we want it to default to is. |
In what scenario wouldn't we want to default to 'is'? Looks to me like unless there is a special equality operator like in URLs or structs it's probably the natural fallback? |
nevermind, I've looked at this again and was convinced. See new revision. |
annevk
left a comment
There was a problem hiding this comment.
I still miss a clear distinction between how you define equality for a concept and then how you compare it. Currently we do things like <dfn for=url>equals</dfn> but maybe it should actually be something like
A URL's equality, given a URL a and a URL b, is:
or maybe the <dfn> pattern is okay, but I don't see you employing that here for list and set (although you do for unordered).
Also for sets the unordered definition is the same as the ordered one, which seems wrong.
Yes, we need to add that to the URL spec. Thinking to do there what we do here for strings, where there is still a
I think you missed this line, which accounts for both A list A is equal to a list B if A has the same size as B and A[i] is equal to B[i] for all indices i of A.
Removed the extra one. |
|
I think this is ready for another review? |
|
Heads up: there is a similar/related proposal going in TC39 ( |
- `Identical` (or `is`) is for primitives or by-reference comparisons - `Equal` is for shallow comparison of structs or custom data types - `Equivalent` is for deep comparison of maps/list/etc or custom data types Closes #664
Co-authored-by: Addison Phillips <addison@lab126.com>
identity/equality now have an exported algorithm as well as a type-specific
"overload".
When using the equality algorithms, a private "visited" list ("equality context") is forwarded,
to avoid cyclical references.
Replace the identity check, equality check, and equality context machinery with three concepts: * "is" (or "identical to"): values of primitive data types are identical when they have the same contents; other values only when they are the same instance. * "equality": every data type has one, which is identity unless defined otherwise. * "equals": a is b, or a and b are of the same data type and its equality returns true for them. Lists, maps, and tuples define their equality by comparing their contents in order using equals. Other structs only equal themselves unless their definition specifies otherwise, e.g., using the new itemwise equality. This keeps the identity semantics specifications implicitly rely on for structs in lists and sets today. Drop the cyclic reference detection. It asserted on acyclic input (e.g., when comparing « « » » with a list containing it) and was not passed through contains or other equalities. Instead, an example cautions against comparing values that contain themselves. Furthermore: * Make map contains and get use equals, to match the requirement that no two keys are equal. Phrase the ordered set requirement the same way. * Rename set's "equal" to "unordered equal", keeping "equal" and the set-equal ID for compatibility, and add an example contrasting it with equals. * Drop the null and boolean identity statements and a stale string TODO, and clarify the number and byte sequence ones. * Rename the section to "Identity and equality", as its old ID would clash with the equality definition. * Add notes on using structs as map keys or set items and on changing a tuple into a struct. * Fix formatting and add Noam Rosenthal to the Acknowledgments.
annevk
left a comment
There was a problem hiding this comment.
I significantly reworked this as explained in the commit I added. I'm now happy with it. If this looks good to you as well Noam I can do some more work on ensuring we have PRs for the specifications that need changes as a result.
I'm not 100% sure about giving structs and tuples different equality by default, but it does make sense I think.
Yea looks great! Thanks |
|
Follow-up PRs created: |
Identical to(oris) is for primitives or by-reference comparisonsEqualis for shallow comparison of structs/lists/maps or custom data types, and is used by internal map/lists algorithms such aslist/contains. It checks for cyclical references internally, using a private-type visited list.Closes #664
Preview | Diff