Anyone who has had the displeasure of working around me has probably heard many of my complaints with the dominant corporate paradigm of Java/XML . In general, its inexpressive and bloated, I’m sure ill manage to have a long list of complaints about these things at some other time, but most of the complaints I have are well documented, and often covered in a lot more depth. But here is the overview:
Java was a stab at fixing some of the emergent problems of C++ in the mid-90’s. Some of it was done well (concurrency, garbage collection), but a _lot_ of the decisions just ham-stringed current programmers. The dominant decisions that constantly irk me are these:
1) It trades verbosity for expressiveness.
Java and its configuration system, XML, were heavily marketed under the philosophy that commenting didn’t work in code, and that it should be “Self-Documenting”. This is repeatedly encouraged not only encouraged by the very verbose API for the java platform, but also through the lack of expressiveness available in the language. Simple constructs like closures and function pointers were not implemented because they were too dangerous, or simply couldn’t work in the framework created. Instead they ignored anything that might be abused or could ever conceivably used the wrong way. Which brings me to my second point:
2) It trades power for safety.
Java not only removed delete, but also pointers in general, as well as adding checked exceptions, and heavy type checking. This has only continued with the introduction of anonymous inner classes, generics and other awkward heavyweight hacks that add a modicum of syntactic sugar. No longer do we have the option of just writing a simple imperative style of programming, instead everything has to be wrapped in clunky class declarations and it takes multiple lines of code just to write a hello world program or add two numbers together. Instead of writing answers to the problems we are solving, we are coercing logic into an overbuild object system that stole wholeheartedly from the clunky hack of an object system it was trying to replace.
This is a false sense of safety, as well. Just because there is no obligation to delete objects when you are done with them you are not relieved of the more general problem of resource management, or even managing the memory of your objects. Garbage collection will only work if all references to an object are removed _and_ the garbage collector runs. In general, though, memory allocation is only part of the resource problem. Most modern applications are tied to a database, or some similar system, and often have to work with system level resources like files, and sockets, even though java has tried very hard to not make such basic building blocks easily available.
The secondary problem with erroring so hard on the side of safety is that it has created several methods and workarounds to get around the pain of having to catch and throw every exception that might pass through the stack. In forcing people to do what they thought was the right thing, they ended up encouraging people to find the laziest way around these problems. At the absolute worst is wrapping all of main in a try/catch, and converting everything to run-time exceptions. Larger libraries and frameworks, like hibernate and spring have their own systems for trapping checked exceptions and turning them into run-time exceptions.
Another useful function that they removed was the ability to overload operators. Of course they can fake this out with their autoboxing, but consider BigDecimal. There is no primitive type for a BigDecimal, so auto-boxing won’t properly convert it to primitives to be able to work on it, there is no operator overloading, so if you are dealing with two numbers that could potentially be very large, your only available choice is the very natural expression:
bigDecimalOne.plus(bigDecimalTwo);
This is an excellent example of verbosity removing expressiveness, and hurting readability.
All of this comes down to java being a very strong, statically typed language when they were trying to move in the direction of dynamic behavior. Reflection was in the initial specification of the language, but approached from a method of static type analysis, which is a fundamentally intractable position.
So where does that leave us?
With a very hamstrung language. While the VM as a target is a very powerful platform, its flagship language has a lot of things that made programming fun and conceptually interesting removed in the name of “safety”. Safety meaning, “someone could use it wrong, so you definitely will not and should not be allowed to do this.”
This is the same as teaching math at half the speed to not make the stupid kids feel bad. Instead of enabling programmers to do what they want and trusting their own judgment to do what is right, they precluded that option and assume that we are all morons who will abuse whatever power given to use. What we are left with is an ineffective language where every task is equally tedious and mundane, there are no elegant solutions, there is no way to reduce code.
Their solutions: bloated IDE’s, language extensions that hack on meta-programming to reduce boiler-plate code that they decided should be manually entered with every class to begin with. “Refactoring” operations that double the size of simple classes, and “Interfaces” that increase the amount of indirection and mandatory implementations.
Nothing about this makes coding easier, more enjoyable, or even more maintainable. Instead, we are left with a generation of coders who are reduced to monkeying with XML config files and brainlessly tapping ctrl+enter to auto-complete through their projects.
What we are left is that the dominant language in programming is one that started out being completely dumbed down from the decision that if something could be abused that it would be and should therefore be removed. Every iteration of java since then has added more awkward and bloated syntax to get around these mistakes in the initial design and the rest of us are stuck with an overly-verbose and inexpressive language that caters to programmers with the least foresight and ability.