The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

supotuco (32) [Avatar] Offline
The first point that isn't clear from the text is that if two objects/structs are equal they should have the same hash value. The example with custom hash functions does not cover this. It important since hashing is built on the assumption that equality implies same hash code. If you violate this then you will not necessarily get correct results from dictionaries and sets.

In general if two things are equal they should behave the same.

Second point is that in general the quality of the hash function depends on the distribution of the sample set. Maybe not something to go into detail but something to call out. When the author says XOR is not a good hash function it has an implicit assumption about the distribution of the Pairs to be used.
Tjeerd in 't Veen (23) [Avatar] Offline
Good point, I will clarify about two equal objects needing to be properly equal!

About the xor, I agree and I will see how I can better rephrase it. I was hoping to convey that Pair shouldn't dictate which hashing method you need, hence making it configurable. But, I will see how I can make it extra clear. Also, the generics chapter has been updated today because of conditional conformance. Not sure if you've already read the updated chapter? I hope that it fits better.

Thanks for sharing!
supotuco (32) [Avatar] Offline
Conditional conformance is a good idea but not sure how it plays out in practice beyond Equatable and Hashable. Do you have any insight?

What happens in the following example?

protocol Foo {
    func getBar() -> Int

struct FooOne: Foo {
     func getBar() -> Int { return 1 }

struct FooTwo: Foo {
    func getBar() -> Int { return 2 }

struct FooPair<T: Foo, U: Foo> {
    let f1: T
    let f2: U

let fooOne = FooOne()
let fooTwo = FooTwo()

let fooPairOne = FooPair(f1, f2)
let fooPairTwo = FooPair(f2, f1)
let fooPairThree = FooPair(f1, f1)

print(fooPairOne.getBar())  //what happens here?
print(fooPairTwo.getBar())  //what happens here?
print(fooPairThree.getBar())  //what happens here?
Tjeerd in 't Veen (23) [Avatar] Offline
You get a conditional-conformance implementation for free with Hashable and Equatable, but with custom protocols you need to extend a type yourself. I did realize that the wording is wrong in the generics chapter and I already updated it for next MEAP. Also, in one of the protocols chapters I will explain Conditional Conformance in depth.

In your situation you would have to manually implement the getBar method so that FooPair would also adhere to Foo.

extension FooPair: Foo {
    func getBar() -> Int {
        return f1.getBar() + f2.getBar()

Now FooPair conforms to Foo as well.