In Set, what's decompose?

I wrote a function which computes something using a SortedSet of a type I defined, which is a fixed-size SVector with no variable-size fields. I thought that maybe using a Set would make it faster, so I changed SortedSet to Set and ran the function. It threw a MethodError trying to call decompose on my type. The stacktrace indicates that decompose is called from hash. How should I define decompose on my type, or should I define hash?

1 Like

decompose is an implementation detail internal to Base. Define equality and hashing for your type.

3 Likes

I believe you’d only hit this if your type subsets Number (or some subtype thereof). Note that it can be tricky to extend numeric types — you can often find yourself deep in internals like these pretty quickly.

2 Likes

Also, equality and hashing must be consistent. In particular this holds even when comparing values of two different types. This basically means that hash for custom Number types needs to be implemented by converting to a Number type defined by Base (or Core), and then hashing that. E.g., if YourType(7) == 7, then hash(YourType(7), h) === hash(7, h) must hold too, for any h::UInt.

1 Like

It is a subtype of Real, and can be multiplied and divided, but it’s not exported, == is not defined between this type and anything else, and it’s never used in a Union. So I defined a hash with no relation to the hash of floats and integers, and the algorithm runs three times as fast as it did with SortedSet.