You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
List.Equals performs full structural comparison for the same object. #14672
changed the title [-]List.Equals performs full structural comparison for the same object.[/-][+]`List.Equals` performs full structural comparison for the same object.[/+]on Jan 28, 2023
This has been a point of discussion in the LISP, SML, OCaml, ... communities from the day I joined them :) It will still be being discussed in 3022 I'm sure.
For many practical purposes it is wise to add shortcut equality to an equality algorithm and other traversals (e.g. we use pointer equality in many places in the compiler).
However, adding it by default for a generic structural equality can make the structural equality semantically "dubious" (e.g. unreliable, subtle) and performance very sensitive to code changes.
For example, we generally expect
let result = ([x] = [x])
and
let xs = [x]
let result = (xs = xs)
to give the same result. But it's possible to have objects where "x.Equals(x)" will return false, raise an exception or not terminate. So adding shortcutting makes equality return true more often. Further in F#, some object identity is "up to the compiler", e.g. allocations of closures, tuples or, potentially, static constant lists like [x] above.
The arguments about this go back a very long way and there's no really perfect position. We decided in F# 1/2 that we didn't want optimization to affect execution wherever possible - unless you explicitly opt-in to using Object.ReferenceEquals or equivalent - and there's something in language spec about that.
So all in all I think this is in the category of "decided in F# 2.0" - we chose a point on the spectrum, fixed it, and that's that - changing it would help performance in some situations but it might be better to simply write a good guide to equality in the F# docs. The topic is big and important one and could cover things like how to implement your own equality (both explicit and .Equals), what the expected semantics should be for different kinds of equality, how and when to use Object.ReferenceEquals.
Activity
[-]List.Equals performs full structural comparison for the same object.[/-][+]`List.Equals` performs full structural comparison for the same object.[/+]dsyme commentedon Feb 1, 2023
This has been a point of discussion in the LISP, SML, OCaml, ... communities from the day I joined them :) It will still be being discussed in 3022 I'm sure.
For many practical purposes it is wise to add shortcut equality to an equality algorithm and other traversals (e.g. we use pointer equality in many places in the compiler).
However, adding it by default for a generic structural equality can make the structural equality semantically "dubious" (e.g. unreliable, subtle) and performance very sensitive to code changes.
For example, we generally expect
and
to give the same result. But it's possible to have objects where "x.Equals(x)" will return false, raise an exception or not terminate. So adding shortcutting makes equality return true more often. Further in F#, some object identity is "up to the compiler", e.g. allocations of closures, tuples or, potentially, static constant lists like
[x]above.The arguments about this go back a very long way and there's no really perfect position. We decided in F# 1/2 that we didn't want optimization to affect execution wherever possible - unless you explicitly opt-in to using Object.ReferenceEquals or equivalent - and there's something in language spec about that.
So all in all I think this is in the category of "decided in F# 2.0" - we chose a point on the spectrum, fixed it, and that's that - changing it would help performance in some situations but it might be better to simply write a good guide to equality in the F# docs. The topic is big and important one and could cover things like how to implement your own equality (both explicit and .Equals), what the expected semantics should be for different kinds of equality, how and when to use Object.ReferenceEquals.
psfinaki commentedon Jan 10, 2024
So I will close this as by design.
For reference - for those who are just diving into this topic, here is an example to illustrate what Don's saying: