There’s this marvelous talk that James Gosling gave called “The Feel of Java,” in which he said you need three real uses before you put anything in. You don’t put anything in just because it’s neat.
But people just want to put stuff in. What do engineers do? They write code. And if they are writing a library or writing a language, they want to put their stuff in. You need some presence, some guiding voice, to give you something that works well together and has made the right set of trade-offs between what you do and don’t put in. Because there’s simply more stuff that you could put in than you should put in to any given language. Does that mean that any of this stuff is bad? No, it doesn’t. It just means that you make your choices and certain things shouldn’t be mixed.
Seibel: I was reading Java Puzzlers and Effective Java and it struck me that there are a lot of little weird corners for a language that started out so simple.
Bloch: There are weird corners, yes, but that’s just a fact of life; all languages have them. You haven’t seen a book called C++ Puzzlers. Why not?
Seibel: Because it’s all puzzlers.
Bloch: Yep. It would take up a shelf. In Java, the puzzlers are worth collecting precisely because you think of it as a simple language. Every language has its corner cases and Java has few enough that they’re for the most part fun and interesting.
Seibel: Is there anything that you’ve learned about programming specifically from working on Java and thinking about its design?
Bloch: I’ve learned an awful lot of things. One thing I’ve learned—I wrote about this in the “Nearly All Binary Searches and Mergesorts Are Broken” blog entry—is that even writing small programs correctly is incredibly difficult. We’re just fooling ourselves if we think our programs are, by and large, free of bugs. They’re not. For the most part, we’ve written programs that are free enough of bugs to approximate the jobs that we want them to do.
I learned that, given how hard it is to write correct programs, we need all the help we can get. So anything that removes potential bugs from our plate is good. That’s why I’m very much a believer in static typing and in static analysis—anything that can remove the possibility of a certain class of bugs from our plate is a very good thing. Anything that can make our jobs as programmers easier is a good thing.
My belief in the importance of good API documentation has been reinforced. Javadoc is one of the lesser-appreciated reasons for the success of the platform. Good API documentation has always been a part of Java’s culture, and I believe it’s because Javadoc has been there from day one.
My natural tendency to believe that simple is good has been reinforced. Over and over I see additions that are more complex proving themselves to be detrimental in the long—or short—run. When I’m designing stuff, I pay close attention to my “complexity meter:” when it starts bumping into the red zone, it’s time to redesign stuff.
I’ve occasionally run into people who just don’t believe that, who just say, “Well, you’re stupid, Josh, you just don’t get it; this is the right way to do it and I’m sorry if you don’t understand it.” I just don’t buy that. I think that if things start getting complicated, there’s probably something wrong with them and it’s probably time to start looking for an easier way to do it.
There’s a brilliant quote by Tony Hoare in his Turing Award speech about how there are two ways to design a system: “One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.”
The paragraph that follows is equally brilliant, though it isn’t as well-known: “The first method is far more difficult. It demands the same skill, devotion, insight, and even inspiration as the discovery of the simple physical laws which underlie the complex phenomena of nature. It also requires a willingness to accept objectives which are limited by physical, logical, and technological constraints, and to accept a compromise when conflicting objectives cannot be met. No committee will ever do this until it is too late.”
Seibel: Do you expect that you will change your primary language again in your career or do you think you’ll be doing Java until you retire?
Bloch: I don’t know. I sort of turned on a dime from C to Java. I programmed in C pretty much exclusively from the time I left grad school until 1996, and then Java exclusively until now. I could certainly see some circumstance under which I would change to another programming language. But I don’t know what that language would be. I think it may not exist yet. I think the world is ripe for a new programming language but I also think that the inertia of a platform is so much higher now than it used to be. A modern platform isn’t just a language and a few libraries; it’s got loads of tools, a virtual machine—it’s an enormous thing. The prospect of creating an entire new platform is much more daunting than it ever was before.
I don’t know what’s coming next. But I’d like to think that if changing my primary language was the correct thing to do, I could still do it. I want to keep my mind open to the possibility. I want to play around more with other languages. I haven’t had the time to do that recently, but I want to take the time.
Seibel: What’s your short list of ones you want to play with more?
Bloch: I want to try Scala, though I have some doubts as to whether it will be the next big thing. I have great respect for Martin Odersky. I think there are a bunch of neat ideas in the language. But I also think it may be too complex and too oriented towards academics to succeed in the world at large. I have no right to say that, though, because I haven’t learned it yet.
I should also play with Python. A real old one I want to play with is Scheme. I think that it would be fun to just take a couple of months and work my way through Structure and Interpretation of Computer Programs with my son. Everybody says it’s such a great book. I bought it—that’s the first step. But it’ll take a while to do. I guess that’s my current short list.
Seibel: These days lots of people are worrying about how we’re going to write software that takes good advantage of the coming multicore CPUs. Java is notable as the first mainstream language to provide built-in mechanisms for multithreading; do you feel like Java’s approach is viable in a multicore world?
Bloch: I’m going to go one step further. I think it is the best approach of any language out there. It’s funny because it seems very popular to talk about Java being dead now. I see it as histrionics, basically. But I think that right now the best existing multithreaded building blocks are in Java. I think Java is poised for a little resurgence. I’m not saying it is where we’ll be headed for the next 20 years; that it is the best way to take care of these multicores. But I think of what’s available today, it’s head and shoulders above the competition.
Seibel: What do you see as the competition to Java?
Bloch: Well, I’m thinking C++ and C#.
Seibel: What about things like Erlang or Software Transactional Memory?
Bloch: So far as I know, STM doesn’t yet exist in a practical form in any mainstream language. If STM proves to be worth its salt, I suspect it will appear in Java at about the same time it appears elsewhere.
Erlang’s approach to concurrency is actors, and if they prove to be a big win, they can also be implemented in many languages. As you know, Odersky and company have already implemented them in Scala. I’m not convinced that actors are the best fit for multicore parallelism, but if they are, I suspect that someone will implement them in Java soon enough.