Swift associated types are a bit confusing, and Russ Bishop’s article on the subject is top notch, the best I’ve seen. I do have a couple of questions after reading it, though:
Type parameters force everyone to know the types involved and specify them repeatedly (when you compose with them it can also lead to an explosion in the number of type parameters).
Why would this need to be the case, necessarily? In Java, a language that does allow for parameterized protocols (Java calls them “interfaces”) you can create concrete classes that conform to generic interfaces without specifying the parameterized type each time the concrete class name is referred to.
interface Food {
}
interface Animal<T extends Food> {
public void eat(T food);
}
class Grass implements Food {
}
class Cow implements Animal<Grass> {
public void eat(Grass grass) {
// Eat the grass
}
}
// No ugly repeating of the concrete type being used
Cow cow = new Cow();
cow.eat(new Grass());
[Type parameters are] part of the public interface. The code that uses the concrete thing (class/struct/enum) makes the decision about what types to select. By contrast an associated type is part of the implementation detail. It's hidden, just like a class can hide its internal ivars.
I don’t see how associated types leak implementation details any less. Taking the example from the post:
class Cow : Animal {
func eat(f: Grass) { ... }
func supplement(s: Salt) { ... }
}
Cow
’s method signature still publically specifies that it’s eat
method can only take an argument of type Grass
. I’m confused as to how this is any more “hidden” than if generics were used instead of associated types.
As Kevin Ballard points out:
So the issue with redundant parameterized type specifications is when referring to the protocol, not a class that conforms to it.