How can we make default implementations safer?

IMO, there is nothing wrong with downcasting here. To make it clear that downcasting is intentional, I would wrap it into a computed property:

public protocol ServerResponse 
{
}

public protocol CacheableResponse:  ServerResponse
{
    var cacheKey:MD5 { get }
}

extension ServerResponse {
    var asCachable: CacheableResponse? { self as? CacheableResponse  } 
}

And if you want to avoid lookup in the conformance tables, you could make this property part of protocol requirements:

public protocol ServerResponse 
{
    var asCachable: CacheableResponse? { get  }
}

public protocol CacheableResponse:  ServerResponse
{
    var cacheKey:MD5 { get }
}

extension ServerResponse {
    var asCachable: CacheableResponse? { nil  } 

extension CacheableResponse {
    var asCachable: CacheableResponse? { self  } 
}
2 Likes