Re: The Origins of Scala
Posted: May 4, 2009 4:39 PM
> > It isn't sound but it is simple. You get 90% (95%?
> > 30%?) of the benefits of generics with almost no mental
> > costs. Given that java development was trucking along
> > just fine without generics, it seems like the
> > argument for them isn't as strong as is often
> I think it comes down to theory over practice. In theory,
> covariance is not adequate. In practice, it's only
> potentially an issue when your covariant types are mutable
> and even then only in rare cases does it become an issue
> and I'm fairly sure there's always a workaround. You get
> most of the value without all the extra complexity. The
> real problem with more complicated variance is that it's
> often hard to see that the declarations you use now will
> limit you later and unwinding them is difficult.
Are you talking primarily about Java's wildcard variance annotations? If so, I can see your point. For a long time I ignored them, and didn't try and learn or understand them, mostly because we just didn't have time to generify our app, even though we wanted to. There were just always more important things to do with our limited resources. So I didn't really tackle Java wildcards until I started learning Scala's variance stuff, and I do find wildcards confusing myself.
Josh Bloch tried to make it easier by providing a mnemonic in his Effective Java 2nd edition book. He talked about it at Devoxx last December, and had a picture of our (Californian's) Governer, Arnold Schwarzenegger, as a younger, bare-chested man. Because the mnemonic was PECS, for Provide Extends Consumer Super. That might make it easier, but frankly I think it is a terribly big complexity burden to require anyone using any generic type in a method signature to try and figure out what the variance should be. So regardless of how you value the benefit of type soundness, the cost with wildcards seems high. And as you say, if someone gets this wrong, it can be difficult to unwind it and change it later, because any code that uses that method signature or subclasses, overrides it, etc., can break.
I think declaration site variance that Scala uses is much easier on users, but I don't have enough experience to know how much easier. In other words, the cost is much lower than Java's wildcards, and I think also the cost of change is also mitigated. If a library designer tries to make something covariant or contravariant that isn't by nature covariant or contravariant, the program won't compile. Any nonvariant type will compile (absent other problems), but you can always change a nonvariant type parameter into a covariant or contravariant one without breaking any client code.
I also think that nonvariant and covariant will not be too hard for most programmers to grasp. Only contravariance is counterintuitive, but hopefully with a bit of study and head scratching, most people will be able to grok it. But is Scala's variance simple enough to reduce the cost and make it worth the benefit? I'd be curious to hear what people who have actually used Scala think on that question.