Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify list and map equality rules #208

Closed
pyr opened this issue Oct 4, 2021 · 3 comments
Closed

Clarify list and map equality rules #208

pyr opened this issue Oct 4, 2021 · 3 comments

Comments

@pyr
Copy link

pyr commented Oct 4, 2021

The reasoning for the behavior of list equality is a bit surprising, indeed:

[1] == [1.0]

yields to no such overload while

[1] == [1.0, 2.0]
// or
[1,2] == [1.0]

yields false.

There are tests in this repository which assert the different behavior. It's unclear which exact rule to apply here, to decide whether false or an error should be returned and feels like the spec could be inheriting some of the underlying implementation properties.

In a similar fashion these two tests feel like they are contradicting each other:

{'k1': 1, 'k2': 'dos', 'k3': 3} == {'k1': 1, 'k2': 2, 'k3': 4} // expects false
{'k':'v', 1:1} == {'k':'v', 1:'v1'} // expects a "no such overload" error

Is there a description of which behavior to apply I have missed in the spec?

@pyr
Copy link
Author

pyr commented Oct 4, 2021

As a follow-up question, would it be possible to make the requirement be a boolean return for all equality tests? (or at least across equality tests of the same types, I suppose there is a case for returning an overload error when equality isn't asserted on the same types).

This should yield not concrete issue since an error has the same semantic meaning than false (in an or or and chain for instance) unless I'm mistaken.

@TristonianJones
Copy link
Collaborator

What you're observing is a property of homogeneous equality where 1 == 1.0 is an error, thus [1] == [1.0] will also error. It's a pain point, particularly for numeric comparisons. The rules for list and map equality are per-entry, so if the lists and maps are not the same size, then the lists cannot be equal. You can think of the logic as follows:

listA.size() == listB.size() && listA[0] == listB[0] && ... listA[N] == listB[N]

Since CEL's logical operators will return false for && as long as one branch is false, the logic is consistent despite how it feels. There's more information here as well: https://github.com/google/cel-spec/blob/master/doc/langdef.md#equality-and-ordering

That said, expect some updates regarding equality behavior shortly. I'm in the process of writing up a proposal to support numeric equality at runtime (type-checker will still complain) and numeric comparisons generally (<, <=, >=, >). I think with these updates, then we can start to talk about heterogeneous comparisons at runtime which would work more like you might expect.

@pyr
Copy link
Author

pyr commented Oct 6, 2021

Thanks for the clarification on lists and map! And sorry for overlooking things, I'll be looking out for your proposal.

@pyr pyr closed this as completed Oct 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants