Are you scared of Java language change? Why? I'm going to try and debunk some of the arguments against change, and express some frustration with Java as-is.
"It was designed simple"
There is a commonly held view that Java was designed to be this simple, perfect language for all-known tasks. Thats not how I read history.
If we go back and re-read about the creation of Java we see some interesting points. These articles cover how Java (Oak) was written for set-top boxes, a market that didn't work out. Thus, the plan changed to focus on Applets on the new internet. Then the internet exploded, Java caught the wave and the rest is history.
Yes folks, Java was originally designed for set-top boxes and applets. Yet today, it is probably the most widely used enterprise language, and applets are dead. Since the fundamental use-case has changed, why shouldn't the language?
My point is that those who claim Java's 'simplicity' was its reason for success are wrong. I contend Java just got lucky.
Still not convinced? Try reading this extract from Patrick Naughton's Long strange trip to Java (via Artima):
[Bill Joy] was often comparing Oak to more complicated and elegant languages like Python and Beta. He would often go on at length about how great Oak would be if he could only add closures and continuations and parameterized types. While we all agreed these were very cool language features, we were all kind of hoping to finish this language in our lifetimes and get on to creating cool applications with it. The more we argued with Bill about making those changes the more strongly he would fight us. After a while it became a choice between not having Bill involved at all or losing control of the language. James and I got into a rather epic battle with Bill in his office in Aspen one evening about this issue. He started out by insulting both of us about how poorly Oak compared to better languages and then he volunteered to resign from being the Live Oak architect if we wanted him to. James and I agreed that would be best and walked out to go across the street to watch "Speed". What a rush.
The next day, Bill was pretty much his normal old nice guy self again, a little relieved, I think, to be out of the role of being directly responsible for our destiny. Bill is annoyingly smart, and I wouldn't put it past him to have planned that whole scenario the night before to force us to defend our positions and take ownership of our project. The interesting thing is that we were right about needing to finish the language even though it had missing features. It was a timing issue, there was only about a three month window in which the whole Java phenomenon could have happened. We barely made it. It is also interesting that Bill was absolutely right about what Java needs long term. When I go look at the list of things he wanted to add back then, I want them all. He was right, he usually is.
Java succeeded because it hit that critical time-window of being in the right time at the right place. But to achieve it, compromises were made. In particular, lots of language features were dropped - assertions, closures, enums, generics (sound familiar?). By all accounts, they weren't dropped to keep the language 'simple', so much as because the timeline dictated it.
Thus Java's so-called simplicity is a fallacy. Language changes now are simply completing the job that was unfinished back then and meeting the realities of Java as an enterprise language.
"Nothing beyond Java"
Some in the Java community seem to have become zealots, extremely passionate about the language, and vehemently rejecting all change. This may stem from the battles between Sun and Microsoft, where some became religiously committed to Java. This has left them unwilling to look over the fence at other programming languages, with a belief that anything from outside the Java ecosystem must inherently be bad.
I reject that view. Other programming languages do exist. Each has its plus points, and each its negatives. But they can teach us what works and what doesn't - assuming that we are willing to look Beyond Java and learn.
"Just look at generics"
Java 5 introduced generics amongst many other items. Unfortunately, generics are probably the most troublesome change that has been made to Java. With over 400 pages in the official generics FAQ attempting to explain weird corner cases, we know something went wrong.
The negative take on this is that we shouldn't change Java ever again because 'we might get another generics'. I believe that is a very reactionary point of view. So long as any change is well specified, and avoids weird corner cases, it should be fine. And the Java community should be testing that and enforcing it.
"Code isn't important"
Another group, take the view that in the big picture code and syntax isn't important. Instead, the focus should be on process, teamwork, risk and testing.
The problem with this is two-fold. Firstly, these issues about process affect you whichever language they use, so they are a non-argument when discussing language changes.
Secondly, they fail to take into account that less lines of code actually does matter. Less LOCs means less lines to test. Fewer if clauses means fewer places for it to go wrong, and fewer tests. Abstracted loops means more predictable code, and fewer tests. More errors caught at compile-time mean less problems in production and fewer tests. And less LOCs apparently also means more secure systems (number of bugs proportional to LOCs).
You could misread this last paragraph to suggest I believe LOCs is the only measure of language change - I certainly don't believe that (auto-boxing being the classic example of getting it wrong by obscuring intent). But it does turn out to be far more important than is often thought.
"Junior developers won't understand this"
The issue with training and language change seems overblown. Developers are not stupid - even the junior ones or so-called Java-Joes. Every day they interact with multiple frameworks consisting of hundreds of classes which are way more complicated than the language changes being talked about.
In fact, most language changes actually try to simplify that interaction. By abstracting out common patterns found in many frameworks into the language, knowledge from one framework becomes transferable to another framework and the overall interaction becomes simpler and often more compile-safe.
What if we don't change
An increasing number of developers are, over time, seeing life beyond the high walls of Java, most notably this has been exposure to Ruby or Groovy. When these developers come back to Java to write code, they tend to find it very frustrating. I think this quote from Ray Cromwell on Javalobby expresses the frustrations well:
I've been programming in Java for almost 12 years now, and I am pretty close to abandoning the language. If it hadn't been for IntelliJ IDEA, I think I would have dropped it in 2002. I really feel like I'm killing brain cells sometimes by generating the same code over and over. I program in a language that I would actually call "JetBrains Java" since I find I must drop into Live Templates often to refactor and reuse code that otherwise can't be abstracted due to Java's limited expressiveness.
Every Java IDE, every Java framework, every JSR and ultimately every Java developer is finding a way to work around issues in the language, many of which could be solved by relatively small, directed language changes.
Summary
Java is still the enterprise choice. But more and more architects are seeing life beyond Java. They're realising that coding something in half or less code is actually a good thing, and the result is code that is far clearer and more understandable than the equivalent Java code. And it often takes less time too.
Java will never be Ruby or Groovy, but it does need to learn some of their lessons. The process of language change really doesn't need to be scary - and, if done well, the upsides will far outweigh any downsides.
Another tired old thing I've seen:
ReplyDelete"X isn't object oriented", where X is a new language feature.
While we're quoting people, let's take a look at what Alan Kay said in 2003 (by 2003 he must have noticed Java):
"OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them."
First of all, Alan doesn't count Java as object orientated, and he coined the term, so let's not worry too much about Java being object-orientated. It isn't. It's only object-orientated at certain levels. Classes, methods, fields, blocks of code, statements, expressions, etc., aren't objects. Only things that we explicitly make objects are objects. Even in Common Lisp every one of the things I listed is an object.
Lisp and Smalltalk, the languages that Alan says can be used to write object-orientated code, are both languages that support, for example, closures as first level language features.
There is one anti-language-feature argument I can agree on though:
"X doesn't belong in a statically-typed language". Java is mostly a statically type-checked language. It's close enough that adding any dynamic typing features would probably ruin it somewhat. But then, I haven't given up on the idea of seeing a statically typed language with good syntax. Haskell tries, it really does.
Great post!
ReplyDeleteI think a part of the anti-change movement is pure protectionism. I learned to program in Java, so when I looked at Perl code I always thought "what the hell is this junk?" But a few years later I looked back and realized that this so-called junk was conceptually and functionally running circles around the mediocre crap that I was writing in Java.
You are dead-on correct about returning to Java being painful. Now, admittedly, some of the stuff you can do in Python or Ruby is downright black magic -- but once experienced, it's hard to let go of that power. I think that part of Java's popularity is that it is perceived as a language for "n00bs" -- strict enough to keep you from getting too crazy. The sad part of this is the missing realization that you can write horrible code in any language. (I know because I've done it.)
And the whole static vs. duck typing thing is so misleading, at least for me, because most Java code that implements any type of flexibility or discovery has so much explicit downcasting that it's just as dynamic as calling respond_to? or is_a? in Ruby -- if not moreso.
I've read comments such as "I don't understand language changes just to save a few keystrokes." Me, I don't understand changes that *aren't* about saving keystrokes... what other purposes for change exist?
Stephen, I really think I like you :-)
ReplyDeleteProgramming languages are a bit like natural languages, some programmers learn just a few, others a lot. For that reason alone one should not underestimate the power of being a mainstream language, like java.
It would be great to have a real versatile language that most people could accept and use to their liking, and many of the features being proposed now is to my liking and only a few to my dislike.
However, I cannot choose the features I would favour, and so all features existing and coming I will have to either accept or I would completely turn away from java. This is why I believe we are looking beyond java right now.
Many I hear of have come sucessful through their first major ruby applications now (not as in hello-world but as in enterprise system) but only where new software is required, and mostly in areas where duck typing and run-time binding is quite acceptable.
I personally would rather have a compiler where I could flag which features the language should embrace, and let it compile down to the same platform anyhow. This includes null-safe types, dynamic typing, generics, aspects, closures etc.
Anyway that my two pence of opinion today. Keep up the good work.
Why I'm scared of Java? I'm not really scared of the language but of the people who use it (or better who want you to use it).
ReplyDeleteHave you ever seen a craftsman using a screwdriver on a nail? There are many different languages around and some are better suited for a task at hand than another. You wouldn't use Java to process a single text file if you could do this with a Perl one liner.
This is it what scares me most about this language.
Just my own humble opinion and I really like your article.
tilting at windmills much?
ReplyDeleteanyway, i will try to exploit your ill-informed, crowd-pleasing rant to my own ends. if you find generics confusing then you should read naftalin and wadler - i have a review at http://www.acooke.org/andrew/writing/compjava.html#generics
I must say I'm more than sick and tired of hearing of "this language isn't that" and "that language isn't this". I've used both Java and LISP A LOT and I though I agree that Java isn't 100% object oriented, I'd choose Java over LISP for 99,43% of the tasks at my hand. Well, if I should do a big AI-system (again), then I'd probaby choose LISP but... :)
ReplyDeleteHave you stopped beating your wife? Why?
ReplyDeleteOnce again, this time without the strawmen, please.
People are against some of the specific features you propose for very good reasons. One of those reasons is that some of the changes you and others propose don't really add any value to the platform, while they add costs to companies using the platform. That doesn't make much sense to people who are using the language to make money or affect meaningful change to the world around them, instead of drawing personal joy of the trivial amount of added expressiveness.
Developers don't have to be stupid to make mistakes, and experience tells us that we can quantify those errors.
Propose all the changes you want, just be honest about it and try to understand that the fact that people have different priorities than you doesn't mean that they are ignorant, stupid or evil.
Mikael,
ReplyDeleteNot all language changes are equal. Generics had a controversial and complex implementation (and there were reasons for that), and of course there are lots of complaints there, some justified, some nonsensical.
On the other hand, I've not heard anyone complain about the retraining costs involved in using the foreach loop, or in the slightly-less-stupid ternary operator (as of Java 5, the second and third operators don't have to be the same type as each other).
Implemented well, language features don't have to involve retraining costs. I think generics were mostly implemented well, they just felt rushed - @SuppressWarnings("unchecked") didn't work for at least the first 6 months of Java 5, for example.
Specifically about adding value; it's hard to quantify what value a language feature adds, as we can already technically do everything that we need to. New language features are about making it easier to carry on doing the same thing, in particular being able to do the same thing in a better way (consider with withOpenFile closure idea) without paying the readability price.
For specific cases of adding value, see the numerous blog posts about use cases for closures, at least Stephen's and Neal Gafter's.
I'm personally against the null-safe # operator proposal, not because I'm scared of change, but because I'd rather that developers focus on getting rid of null - making null unacceptable, finding better ways of expressing the same things, so that a future language (including future versions of Java) can get rid of it completely. I think it detracts value from Java.
Shai, I don't think Stephen named you in his post, don't take it too personally. You're not the only person to express fear, uncertainty and doubt about language changes.
ReplyDeleteThe only language I know that can be argued to seriously have a problem with feature creep is C++.
The things that Gosling threw out were apparently things from C++, such as templates, operator overloading and pointer arithmetic (yes, that's from C). C++ still doesn't have closures, though it does have a proposal for them.
They weren't things from Lisp and Smalltalk, such as closures (blocks), which are less justifiable in leaving out.
"You didn't mention the fact that many API changes would be a misfit for the existing API such as ENUM's making all the "public static final int" code outdated."
This is where I stopped reading. You're really, honestly, complaining about a language change that made crap code look crap (in comparison to enums)? Oh boy.
Changes may be OK or not. Too bad, most propositions for Java7 are plain atrocious like type inference for finals or closures. Geez, Java is so formidable, for many many reasons, one of most important being NOT HAVING such features, being simple, static and verbose. Introducing more type safety, more static checks (and some dynamic, too) is OK, introducing more informational verbosity and reducing gratuituous one is also OK; inviting so called dynamic languages and allowing them to "interoperate" (what a buzzword) is definitely not OK.
ReplyDeleteAnd if other than Java languages have to be invited, they should be FORCED to obey Java rules, i.e. no unexpected checked exceptions, static and checked type declarations on everything and so on. Or else, Java the platform will decay into poor quality we currently see e.g. with Perl the platform (laughable, isn't it? want Java be Perl?)
I'm trying not to interfere in the comments on this post as it was a pretty clearly opinion piece (so disagreement is expected).
ReplyDeleteI do want to say one thing though - this post isn't a response to criticisms of 'my' ideas (if you blog ideas, not everyone will like them - in fact some of my ideas may well turn out to be crap). Instead, this post is a response to those who are rejecting any and all change, on every forum, and by any author.
I didn't take anything personally ;-)
ReplyDeleteI just assume that I am part of the group referred to and wanted to correct a "lumping together" and missing information.
The Gosling quote I mentioned is very common here is an example from http://www.artima.com/intv/gosling3P.html :
Bill Venners: The opposite of complexity is simplicity. I have often heard you describe your philosophy when designing Java in the early days: you didn't put something in Java unless five people screamed at you and demanded it. In one interview, you told this really good story about moving to a new apartment and something about keeping things in boxes.
James Gosling: That's actually a general principle for life that works really well. When you move to a new apartment, don't unpack. Just sort of move in, and as you need things, pull them out of the boxes. After you've been in the apartment for a couple of months, take the boxes -- don't even open them -- and just leave what's in there and throw them out.
I think Java threw out macros, const, functions, function pointers and many other ideas from Smalltalk as well after all C++ was not the only influence.
About the enum quote, I'm just saying that after enum was added we now have duplicate code with type safe enums and without. I'm not asking for a complete change of the API but this is a price you pay for late arrival to the language. Ignoring the "dirt" and sweeping it under the rug doesn't make it pretty.
Anyway the enum comment was near the end and if you got that far then good for you ;-)
"Another group, take the view that in the big picture code and syntax isn't important. Instead, the focus should be on process, teamwork, risk and testing."
ReplyDeleteNo, this other group (that includes me) takes the position that code and syntax are only so important and that developers spend too much time attempting to optimize at this level rather than in the higher-levels such as process, design, use cases etc where there's more opportunity for greater savings.
For example, a modern IDE can support macros etc and many of these proposed extensions could easily be implemented using macros which avoids all the mess of changing the language.
"The problem with this is two-fold. Firstly, these issues about process affect you whichever language they use, so they are a non-argument when discussing language changes."
So you rule out process but ignore all the other non-language aspects? If I improve the process which gives you more design time which saves you writing lots of un-necessary code (more than can be saved with the likes of closures) is it not relevant to you?
So far as I can see you've ignored effectiveness and efficiency of method. Language extensions are not always the most effective method for saving effort.
"Secondly, they fail to take into account that less lines of code actually does matter. Less LOCs means less lines to test. Fewer if clauses means fewer places for it to go wrong, and fewer tests. Abstracted loops means more predictable code, and fewer tests. More errors caught at compile-time mean less problems in production and fewer tests. And less LOCs apparently also means more secure systems (number of bugs proportional to LOCs). "
Are you suggesting the only way to save lines of code is with language enhancements? Do you not save lines of code through things like refactoring or redesign? And would you be prepared to state that refactoring and redesign won't save you as much code as a language enhancement?
Further, sure you save on some testing but if the resulting code is less easily understood because there are more cases where behaviour is not explicit, you create a maintenance nightmare instead where people constantly misunderstand what they're reading and thus make mistakes that are at least as costly as what you had prior to the language extensions.
And a timely reminder of the apparent saving that a language extension provides that yields an unexpected cost:
ReplyDeletehttp://www.javalobby.org/java/forums/t88648.html
If you add a new feature to Java, expect the average offshore developer to not be able to understand or want to use it till at least 3-4 years down the line.
ReplyDeleteYou average american developers think that building web apps is rocket science. Get a clue.
ReplyDeleteI was using Java during the 1.4->1.5 transition and I must say that the Java camp seems to be afraid of sugar.
ReplyDeleteThe C# designers did an excellent job with C# 2.0 in preparation for C# 3.0. They knew they wanted closures and type inference in C# 3.0 and added delegates to C# 2.0 to pave the way. There are no IL changes in C# 3.0 which is quite amazing -- all the cool LINQ stuff is just sugar.
My question: Why are Java developers afraid of sugar?
"I do want to say one thing though - this post isn't a response to criticisms of 'my' ideas (if you blog ideas, not everyone will like them - in fact some of my ideas may well turn out to be crap). Instead, this post is a response to those who are rejecting any and all change, on every forum, and by any author. (Stephen Colebourne)"
ReplyDeleteBut I'm not rejecting "any and all" (for instance, I said I don't like at all the # operator, but I could appreciate the "not null" stuff - and being basically both proposals of yours, I'm also demonstrating I'm not biased against you - if you had any doubt ;-).
I am not against the fact that people is _proposing_ changes - it would be crazy to freeze any kind of discussion.
I am objecting the way the _community_ is evaluating the topic and how much is unbalanced towards code topics.
"My question: Why are Java developers afraid of sugar?" (C# programmer)
Because most of us are worried about making things work, rather than selling sugar. :-)
"My question: Why are Java developers afraid of sugar? "
ReplyDeleteI for one am not afraid of sugar but given that it can rot my teeth I want a good reason to be consuming more of it :)
I'm all for improving the Java language (remembering that Java is also a platform) but the enhancements being pushed are poorly justified with either subjective reasons or overly-simplistic, non-real world LoC type arguments. As serious professional developers we should push back on that stuff and demand, solid reasons for the enhancements and solid discussions of costs versus benefits in each case.
A number of comments have been about LOCs. Shai said that he "spent the past 10 years convinced there was a consensus that lines of code is no measurement to quality or complexity". I agree that this had become a cosy consensus within the Java ecosystem. However, I also believe that Ruby has blown this consensus completely out of the water. I also know that this is still a controversial opinion ;-)
ReplyDeleteI hope to write soon about how far Java should change to adapt. There must be limits, and there really is a distinct Java-style that has to be maintained. As I said before, Java can learn from Ruby and Groovy, but it must not lose its own identity in the process.
@Stephen, thanks for adding that last comment, it really saved me from writing a full-blown lecture starting with: "The only constant in the Universe IS Change!" ;)
ReplyDeleteP.S. Oh... and Applets are not dead, I still use them! :)
Nice straw men. Keep up the lousy work.
ReplyDelete