See #1468, this is failing:
type OTest(a) = member val A = a with get, set
testCase "hash with objects works" <| fun () ->
(hash (OTest(3))) = (hash (OTest(3))) |> equal false
Perhaps reference types should also derive from a SystemObject type in Types.js, so they can have a default implementation of GetHashCode/Equals/CompareTo/ToString (just a suggestion).
Hmm, the original idea was that F# classes would become equivalent to JS classes (same way as F# and C# classes). I guess in Fable 2 this is not so important because we're not using JS classes so the semantics can be different (besides members not being attached to the class). However, we're still using classes to inherit from React.Component so assuming there's a common base type can be problematic in some situations.
I tried to fix the hash in this commit. Can you please check it and let me know if it looks right? (tests are passing). I left the structural option in the Util/hash helper, but probably we don't need because records, unions, structs already implement GetHashCode.
I'm not convinced that the hashing is correct in all corner cases or in deep hashing, but I'll close it for now as it's passing the current tests.
@alfonsogarciacaro
I keep finding corner cases that need fixing. I'm sure with enough testing we can find most of them, but the foundation is leaky and fragile, and the benefit of no inherited parent for classes as stated above is not that clear to me (but perhaps I'm wrong). We would be in much better shape if we start with the same semantics as used in .net (parent class for objects that defines identity hashing and equality for objects, that can be overloaded for whoever needs that). We're already doing that for everything else (records, unions, structs, etc.) and classes are not even the main use case in F# (they're quite common but not the default).
Let me know what you think.
Probably you're right, @ncave. It would make things more consistent to have controlled bases for all F# types, and it should be simpler to keep just interfaces for JS interop. I just need to check how this will work to declare React components, and also ask the ts2fable maintainers whether they're still using F# classes to declare JS types.
But these shouldn't insurmountable obstacles, so if you want to give it a go, please do it and there should be no problems to merge the PR.