>[The 911 is] so obviously superior to the Cadillac that a child could tell it's better.
My first thought was that the Cadillac looked better even though the internals of the 911 were certainly higher quality. Does that mean I have worse design sense than a child? :(
>The Cadillac was carefully designed to appeal to the average driver. The 911 was designed for performance. Which one is better design?
It all depends on how you evaluate quality: there are so many ways to determine the "best" that questions like this are almost meaningless.
Regardless of the car metaphor, I think PG's point makes a lot of sense.
Regardless of the car metaphor, I think PG's point makes a lot of sense.
Does it?
From the article: C, Smalltalk, Lisp. The languages that were consciously designed for "average" programmers (Cobol, Pascal, Ada) have tended to be evolutionary dead ends.
COBOL and Pascal (via Delphi) are probably used more than Smalltalk and Lisp in the real world. Also, Java and C#, designed for the 'average' programmer, are immensely popular outside our little bubble. Java has been around for twenty years and will probably be for at least two more decades.
I like tinkering with new and 'revolutionary' languages - I wrote a fair share of Prolog and Haskell, but I have come to the realisation that that I like to solve interesting problems (mostly in NLP and machine learning) far more. And when you focus on solving an interesting problem it can be good that the language and ecosystem are boring and predictable (Java, C, C++), so that you can focus at the problem at hand. For example, in Java you can easily add a library to a project via Maven and its usage will often be completely predictable, you don't have to deal with the fact that the library writer was in an existential typing, GADT, or arrows phase and fight with its API.
A false dichotomy. Somehow, these always crop up when discussing languages. Sure, in Java you don't have to deal with GADTs. But you do have to deal with the fact that people think functions are dark magic and expect you to extend an abstract class instead. (Yes, Swing, I'm looking at you!)
I've found that the advantages of using a nice high-level language like Haskell far outweigh issues with build systems and libraries and the usual boring stuff Java et al are supposed to excel at. This for very interesting problems--most recently, program synthesis using MCMC. (Following the "Stochastic Superoptimization" paper, but I honestly think that name is a bit silly :P.)
Besides, have you ever tried to use the equivalent of Parsec or QuickCheck in Java? Even boring, practical things like that are better in Haskell!
Every time someone figures out how to solve a small programming problem elegantly in Haskell, it is interesting enough for a 10 page ICFP paper with a 10 page appendix.
Sure, Java is inelegant and dirty, but you don't have to perform the thinking needed to write a dissertation to use it.
Untrue for the things Java makes easy. After all, in the worst case, you can just drop into Haskell's imperative subset.
Besides, it's mostly small programming problems like practical STM, deterministic parallelism, easy randomized testing or DSLs for describing derivatives (alliterative). These are things not even dreamed of in Java--the only reason they're small is because Haskell makes them small.
However, all this is not important. Sure, coming up with abstractions requires research and produces papers. But using the abstractions doesn't!
OOP and Java and the JVM are all based on a ton of CS research themselves, but clearly you don't think that makes them impenetrable. The same applies to Haskell--you don't have to create your own abstractions from scratch; instead, just use the brilliant ones people have created for you.
You still have to know a lot to use those abstractions...like category theory (monads and arrows). You have to at least be able to read the paper even if you aren't capable of writing it.
There is also a kind of compulsion to design elegant abstractions when using Haskell, to think about and understand problems really well before you write a solution. This is not just about the kind of people who are attracted to using Haskell, but the language itself promotes this compulsion. Sure, you can drop into Haskell's imperative subset, but it is frowned on and discouraged.
Java as a language gives you very little, and there is not much pressure to obsess over the design of abstractions. This is both good and bad: good in that you feel less guilt about writing dirty code fairly quickly and with less understanding (to be acquired more gradually via trial and error), and bad in that this code will probably incur more technical debt. Sometimes worse is better [1], ironically (or maybe not) a concept that comes from Gabriel, who is a cornerstone of the common lisp community.
It's frowned upon because the imperative subsets tend to code that's less general and harder to reason about. These critiques falls identically on Java, though nobody misses it there because nobody practices the generality and reasonability available in a very simple typed lambda calculus there.
It's remarkable how much more you have to keep alive in your mind to program in Java (or even Clojure) over Haskell. The reason things are more complex is because you're freed from having to think hard about state and execution methodology except at bottlenecks of design and performance.
Sure, in Java you don't have to deal with GADTs. But you do have to deal with the fact that people think functions are dark magic and expect you to extend an abstract class instead.
The amount of type wizardry that Haskell permits is far larger than Java and C++ teaches us that in practice you have to expect all possible combinations language features that are allowed. A random Java library will have a far more understandable API than a random Haskell package, since there are not so many permutations of language features possible.
If everybody stuck to just Haskell 98, things would be far simpler.
Besides, have you ever tried to use the equivalent of Parsec or QuickCheck in Java?
As a matter of fact, I just committed QuickCheck-like unit tests five minutes ago [1] :):
I write such tests in Java quite often. Of course, you don't have the nice combinators of QuickCheck :). I am not saying that Haskell isn't more powerful it is. But it comes at a cost: many packages come with an up-front learning cost, Haskell is hard to optimize compared to Java or C, etc. The Java APIs are predictable, run-time performance is predictable (in the sense that it easy to profile and optimize) and the ecosystem is boring and predictable. These are some of reasons that Java is popular (besides having a steward with deep pockets).
([1] Ps. yes, I know there is a very obvious optimization optimization possible that commit, it's a development branch.)
Yeah, I also prefer the Cadillac visually. (although I'd drop either for a BMW 2002) And for 90% of what you do with the car, the Cadillac was probably more practical. Particularly if you lived in any parts of the US except maybe LA/SF/NY in 1973.
>[The 911 is] so obviously superior to the Cadillac that a child could tell it's better.
My first thought was that the Cadillac looked better even though the internals of the 911 were certainly higher quality. Does that mean I have worse design sense than a child? :(
>The Cadillac was carefully designed to appeal to the average driver. The 911 was designed for performance. Which one is better design?
It all depends on how you evaluate quality: there are so many ways to determine the "best" that questions like this are almost meaningless.
Regardless of the car metaphor, I think PG's point makes a lot of sense.