For example I've been working on a Json library that stores everything in an enum (ADT):
public enum JsValue {
case JsString(String)
case JsNumber(Double)
case JsObject([String: JsValue])
case JsArray([JsValue])
case JsBoolean(Bool)
case JsNull
}Trait objects in Rust let you emulate inheritance. The issue I was talking about is that folks from inheritance-heavy languages use this as the de facto design pattern, and then stuff doesn't work so well, because you're not supposed to use inheritance so much (the languages aren't designed with this in mind). The correct option is to use enums and composition over inheritance wherever possible.
Saying use composition over inheritance "wherever possible" can lead to some cargo culting on its own. It is always possible to use composition over inheritance, but it isn't always wise.
Pretty much what I meant, when I said "wherever possible" I meant "wherever possible with decent code", sorry about the confusion.
"I’m using a protocol for the Account type. There are classes that conform to the Account protocol: TwitterAccount, AppNetAccount, LinkedInAccount, etc."
The important bit is the "etc." at the end. The types of accounts he wants to support is open ended. He also mentions a plug-in API. You can't have third parties come in and extend some algebraic data type.
If this is not a case for protocols then there is no such case at all and protocols should be removed from the language.
That's a bit harsh. You forget that protocols are useful for generics too.
But yes, if they want it to be extensible, protocols would be the way to go.
Looking deeper into the issue, it seems like this isn't really an issue with protocols, just an issue with the design of Hashable or Equatable (either allow Equatable to work with protocol objects, or move the Equatable dependency of Hashable to a different kind of Equatable).
This sounds like a nitpick, but it's the difference between language and API design, and the latter is often easier to evolve. It also means that this can be fixed by a ProtocolHashSet<T> library which does hashing differently without touching the compiler/stdlib at all.
(Which may or may not be the case here, depending on extensibility)
enum Car {
case Red
case Blue
}
extension Car {
func hello() {
print("hello")
}
}
let x = Car.Blue
x.hello()
https://developer.apple.com/library/ios/documentation/Swift/...edit: although you can't add a new case to the enum.
That's the point. We all know you can add impls or extensions.