In Java's OO paradigm, instance variables are inherently defined separately from their initialization, making it quite difficult to make sure they're always used when initialized, properly.
The nullability stuff bites me over and over :(
Forgetting to use .start() on a thread is a stupid runtime error, instead of using some design where it isn't possible to forget .start() or at least get a compile-time error.
I am also using a lot of C in parallel, and with the C preprocessor, I am finding that C is often more expressive and nicer to use than Java!
Everything takes ridiculous amounts of code.
For example, in Haskell, I can write:
threadIds <- replicateM 10 . forkIO . forever $ do
code .. here ..
To get a thread-pool of 10 threads looping around my code, and put their thread ids in a variable.In Java, this requires so much effort!
Not to mention the utter lack of sum types and pattern-matching, making tons of Java code that looks like:
if(msg.what == Foo) {
msg.obj1 ...
msg.obj2 ...
} else if(msg.what == Bar) {
..
}
arrrg!Android uses named integers rather than enums, due to some issue with Java enums.. And the switch would only help a bit, the main problem is needing to correctly interpret the associated payload according to the message type. That's what sum types give you, which Java doesn't properly have.
They could be emulated with visitor pattern, if one is masochistic...
Though my tip though for the long term replacement of javac is Scala. I'm very impressed with it! I can honestly say if someone had shown me the Programming in Scala book by by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy. So why Scala? Scala is statically typed and compiles down to the same fast bytecode as Java so its usually about as fast as Java (sometimes a little faster sometimes a little slower). e.g. compare how well Scala does in some benchmarks with groovy or jruby. Or this. Note speed isn't everything - there are times when you might want to trade code thats 10x slower for more productivity and conciseness; but for a long term replacement for javac speed is important.
His dissatisfaction with Groovy concerned more than just its speed, and originated much earlier, see his very last Groovy mailing list posting [2] in Dec 2005 just before he left the Groovy development team:
The MOP and introspection APIs do NOT solve the horribly broken name resolution rules in the current RI of Groovy [...] I see no argument yet for why we have to throw away decades of language research and development with respect to name resolution across the language as a whole [...] It just feels totally wrong to break Closures across the entire language just because of some use cases for Markup.
Groovy is sloooooooow, its recent static typing is buggugguggy and not even used by Grails or Gradle, and its closures are broken. Its "recent surge in popularity" was also probably based on deception [3]:
Groovy, which turned up in the [Tiobe] 18th spot last month [October 2013], slid back down to a number 32 ranking [Nov 2013]. "After a long discussion with one of the Tiobe index readers, it turned out that the data that is produced by one of the Chinese sites that we track is interpreted incorrectly by our algorithms. So this was a bug," Janssen said. "After we had fixed this bug, Groovy lost much of its ratings." The ratings slip takes Groovy from a 0.658 percent rating last month to 0.393 percent this month.
This has happened before. In April 2011, Groovy fell from #25 to #65 on Tiobe in a single month after they increased the number of search engines they monitor. Groovy had begun its short-lived rise just after December 2010 when Groovy tech lead Jochen Theodorou "volunteered" his services to Tiobe to help them improve their algorithms.
[1] http://macstrac.blogspot.com/2009/04/scala-as-long-term-repl...
[2] http://groovy.329449.n5.nabble.com/Paris-write-up-tt395560.h...
[3] http://www.infoworld.com/t/application-development/c-pulls-a...
I have much more faith in the JVM but would like to see it provide a step beyond Rails rather than catching up. Play is nice because it is trying to accomplish this with Akka, though yes I see there are other issues. As mentioned in another comment, I'm kindof just wishing there was a cool Clojure framework. Maybe I will try one even there is not so much of a consensus as there are around these other emerging JVM frameworks...
Think Sinatra instead of Rails.
buuuut as retrogradeorbit points out.... the clojure macro system is powerful, so maybe it lends itself better to this type of setup
It's also a pleasure to program in Groovy.