top | item 4734559

Why I love everything you hate about Java

114 points| of | 13 years ago |magicscalingsprinkles.wordpress.com | reply

93 comments

order
[+] oconnor0|13 years ago|reply
I find it odd that while the article is titled about Java, all of the code examples are in Scala.

The statement "function composition is a degenerate case of the Decorator pattern" in the blog is bizarre to me. OO languages like Java have to resort to the Decorator pattern to handle their lack of composibility; that seems far more degenerate than a language that supports this kind of composition without hacks.

Also this article is 2.5 years old.

[+] mercurial|13 years ago|reply
Agreed. Most design patterns are workarounds around missing features in a language. You can go around and pretend the reverse is true all you want, but it doesn't make it so. Also, looks the author never heard about decorators in Python, which let you do the same thing if you want, just with much less boilerplate.

The article reads like it was written by somebody with experience in Java and Scala, but not much more.

[+] r00k|13 years ago|reply
So we set about to re-write Querulous using my favorite modularity techniques: Dependency Injection, Factories, and Decorators. In other words, everything you hate about Java.

Hey there Mr. Strawman.

I write mostly Ruby, and I use dependency injection, factories, and decorators liberally. There's nothing in Ruby that makes these any harder than they are in Java (in fact, I'd argue they're easier.)

Two years ago, when this piece was written, the author had more of a point: some people rejected anything that reminded them of Java out of hand, including design patterns.

These days, I'd argue that interest in classic OO design ideas is experiencing a massive resurgence in the Ruby world.

[+] devin|13 years ago|reply
RE: "classic OO design ideas experiencing a massive resurgence"

I don't know about that. I see a whole lot of functional paradigm chatter these days. That wasn't true 5 years ago as I recall.

Then again, I suppose it depends on what color your glasses are: If you're a classic OO devotee you see most of the techniques being put forth as classic OO, and if you know a bit about FP you see it all as the stuff that FP has always been made of, the stuff that OO gurus who cut their teeth on FORTRAN neglected to mention came from FORTRAN.

[+] tptacek|13 years ago|reply
Why would you ever use a "factory" in Ruby?

I'm less certain that DI is "wrong" in Ruby, although it's definitely unidiomatic.

[+] chris_wot|13 years ago|reply
It's still happening. I'm constantly seeing ignorant comments about AbstractSingletonProxyFactoryBean!
[+] josteink|13 years ago|reply
Just before I saw this post on HN, I realized that the first editor I was presented to when I was being taught Java at university was emacs.

Emacs felt slow, clunky, last-century and everything which could be light, nimble and cool Emacs made feel boring and hard. I did not get to like Emacs back then.

In fact I've gone years and years and years actually never fully liking emacs, beyond it being simpler to use than vim (which I still consider insane) while readily available on most shells. It was a safe haven, although a unpleasant one.

Recently though, I've dabbled in clojure. Eclipse is really not good for clojure development. Especially not so for learning how things works under the hood. So emacs is seemingly the lingo-franco in clojure circles, and I was forced to return to my old Java-related enemy. Or at least so I thought.

Out of the box, almost nothing is optimal for clojure development. So you have to add packages (emacs supports packages? nice!), you may have to tweak init.el to do so (emacs is configurable and programmable through its own lisp-dialect? nice!), oh and you may want to add some repos and map package-install over this collection of useful pacakages (no way!).

Once you're there and getting productive, you might encounter things you don't like. Google it and find ready-made lisp-code to import into your init.el, and your problem is solved.

I guess that's not really directly related to this article, but before heading to HN now, I had the realization that emacs, despite it being the horrible tool which Java made me hate, is actually pretty awesome.

You need the right perspective to fully appreciate something. This is crucial and something Java taught me this, although in the wrong way. And just as I realize this, then I see an article about Java and perspective.

I like cute litle coincidences like that :)

[+] chris_wot|13 years ago|reply
Have you considered adding your configurations to a GitHub repo?
[+] argv_empty|13 years ago|reply
The article explains why closures are a poor man's objects. Be sure to read the comments to see why objects are a poor man's closures.
[+] w0utert|13 years ago|reply
The comments do in fact contain more interesting insights than the article itself. Good discussion.
[+] zanny|13 years ago|reply
Both are a poor mans structs with name mangling!
[+] confluence|13 years ago|reply
Language wars bore me. I've got pretty decent proficiency in C, C++, Java, Python and Javascript and I honestly like them all.

I use C to really get what happens on the metal. I use C++ to leverage C and C++ libraries for perf critical applications quickly. I use Java like C++ where it makes more sense - Android, or availability of libraries etc. I use Python to prototype and quickly express complex ideas and determine their perf characteristics. I use Javascript for frontend web dev which communicates with json back-end APIs that are language/platform independent services that scale out horizontalty.

I have 2 main rules.

If the question is to learn one important thing or another - I learn both. Then when I come across a new problem I solve it with a combination of the tools at my disposal.

Hence this is why I am currently learning Emacs, lisp, clojure, Scala and Haskell to round out my languages with maybe a little Ruby thrown in. This will take me a few years.

In the end programming is just about getting things to screen quickly and correctly. Seen from that viewpoint most languages are very similar at heart.

[+] jackpirate|13 years ago|reply
>Language wars bore me

The Haskell vs. everything else language war really is important though. All the languages you mention are basically the same thing with slightly different syntax or a slightly different runtime environment. Haskell, on the other hand, revolutionizes the way you approach code. Or at least it did for me.

[+] Cacti|13 years ago|reply
I write in all kinds of languages professionally and have been doing this sort of thing for a long time (since I was 9 and I'm now 31), so, I'm mostly over the language war thing. Yes, I prefer some languages over others. Or certain languages in certain situations. But I try not to let my opinions get out of hand. Everything is pretty much the same anyway.

Java? I can see the appeal. It's really come a long way. The only thing I can't get over about Java is the goddamned verbosity of it. It's _excruciating_ to write anything in Java.

Yes, I know. Use a modern IDE. The namespaces are designed that way for a reason. Just deal with it. It's not a product of Java itself but of the libraries. Blah blah.

It's still a painful environment to deal with and, with developer time several factors more important that just about anything else, I value my time highly and I'm not going to waste it on AbstractSingletonProxyFactoryBean bullshit.

Now, yeah. If you're a huge corporation that is bumping up against the law of large numbers, where most of your developers are mediocre and yet still have to work together, then I guess Java is OK.

[+] vsync|13 years ago|reply
I've found things like Lombok and LambdaJ to be super helpful as far as verbosity.

One thing that does frustrate me is that the compiler enforces a target bytecode level at least as high as your source version. Meaning that even the simpler syntax for initializing generics isn't allowed even though it's pure syntactic sugar and has no impact on the generated bytecode.

[+] gurkendoktor|13 years ago|reply
> where most of your developers are mediocre

Does anyone have evidence (including anecdotes) that Java 7 is simple enough for mediocre developers? Every new feature in Java that I have seen, starting from and including generics, seem like the non-orthogonal hacks that make C++ so frustrating to learn.

[+] viraptor|13 years ago|reply
This is a gem to remember in the future (from the comments): "Design Patterns are for when you run out of language".
[+] jlgreco|13 years ago|reply
I thought Rob Pike had a good point that, if "design patterns" had been a part of our language 40 or 50 years ago then things like calling convention would have been called "design patterns". Of course we don't talk about calling convention like that these days because languages handle it for us.
[+] sbochins|13 years ago|reply
Not sure how Java is better than all the "hipster" languages as you say. It doesn't seem like you're just using some design patterns that are present in basically every language.

Clojure has futures too, but the syntax isn't as clunky as Scala or especially Java. All these synchronization primitives are in basically every other language. Maybe I'm missing something but I don't really see what is special about Java here. Has the OP ever tried any "hipster" languages, he might be pleasantly surprised if he did.

[+] dustingetz|13 years ago|reply

    dependency injection : currying
    factories : type constructor
    decorators : higher order functions
there's nothing wrong with DI and the like. what's wrong is the way it's done in idiomatic java. when you do DI in idiomatic scala, there isn't much of a problem.
[+] lurker14|13 years ago|reply
Huh?

How do any of your analogies work?

[+] grogs|13 years ago|reply
I no longer care. Java is overly verbose, but therefore explicit. I'm happier to do concise Scala with more stuff implicit stuff going on, or more explicit stuff in Java with lots of Spring config.

Opinionated frameworks which hide stuff from me are bad. They're good for initial productively, but you pay the price later - you have to understand it to weak it, and may find the architecture doesn't fit your problem.

On the other hand, writing a Spring config file from scratch is a horrific process, especially without the Spring eclipse plug-in.

But now that I understand web.xml's and application-context.xml/*-servlet.xml, and have written plenty of Spring config, my productivity is pretty damn good. So why should I care.

[+] devin|13 years ago|reply
FWIW I don’t think the Clojure or Scala communities have any kind of “hate” for Java. Clojure views Java as an ally for many of the reasons you discuss. I think you’d be hard-pressed to find people in the Clojure or Scala camps that refuse to acknowledge there’s a right time to descend into Java. Likewise, I think any Ruby programmer worth his/her salt would tell you: if you’re trying to process 20,000 messages per second, don’t rely on Ruby. Moreover, JRuby, Clojure, and Scala are all quite fond of Java interop, so I’m not sure I agree with your opening statement that people who use said languages are “hipsters” who blatantly ignore the benefits of changing the level of abstraction when the situation warrants it.
[+] MatthewPhillips|13 years ago|reply
AbstractFactoryFactory seems like an inevitability of object orientation. I have to wonder why we don't see it as often in other OOP languages. I'm not versed in Ruby or Python so I can't comment on those. In JavaScript there isn't the concise class or extends/implements keywords and people tend to hide how a library is implemented behind a closure that prevents you from extending it.

So I wonder if Java just gets the blame because it is the most pure object oriented language. It doesn't put up walls preventing you from doing what OOP really wants you to do. C# is the same way, by the way, you see IThisOnlyExistsToBeGeneric<T> all of the time; AbstractControllerBase is a real class in C# MVC if I remember correctly.

What walls does Ruby and Python have that prevents this? Because I see no reason why people aren't doing it.

[+] icebraining|13 years ago|reply
I disagree; there's nothing pure about Java as an OOP language. In an OOP language, as defined by Alan Kay - who coined the term and popularized the concept - the key characteristics are that everything is an object and objects send messages to each other, while hiding their own state. Classes are not fundamental, but if they exist, they must be objects themselves.

As for JavaScript, the fact that people tend to use sealed closures is not a defining characteristic, anymore than having final classes. JavaScript has Prototypes, and they can be extended just fine.

"[java]’s a pop culture. A commercial hit record for teenagers doesn’t have to have any particular musical merits."

[+] viraptor|13 years ago|reply
My guess would be that most factories in Java are just very thin wrapper that do "if this return new A(); if that return new B();". This just doesn't need to be done explicitly in a dynamic language. Instead of creating a factory you could pass the class itself as an argument. In Python class is also a factory of its own instances, so the whole reason for wrapping it into another object disappears.

And if you do want some logic in the factory, you can just create one without changing the interface. Callee doesn't care when calling x() whether x is a type, factory, or something else. As long as it returns an instance, everyone is happy. (that makes factories disappear from the signatures)

[+] willismichael|13 years ago|reply
Could you clarify what you mean by "most pure object oriented language"? This seems disingenuous to me, since if you ask the users of a dozen different OO languages what "OO" means, you'll get a dozen different answers.

http://www.paulgraham.com/reesoo.html

[+] lars|13 years ago|reply
There reason you don't see interfaces or abstract classes in Ruby or Python is because they are dynamically typed. Interfaces and abstract classes are byproducts that are required for Java and C#'s type systems to work. What use would you have for them in Ruby?
[+] yxhuvud|13 years ago|reply
You want an AbstractFactoryFactory in Ruby? Heres the only one I've ever used or needed: Class

What does your pattern add to that?

[+] marizmelo|13 years ago|reply
Java is an excellent language, it has a elegant syntax, but... it's not made for web development. JSP/Servlets development is a joke.
[+] dscrd|13 years ago|reply
" Our life is frittered away by detail. Simplify, simplify, simplify! I say, let your affairs be as two or three, and not a hundred or a thousand; instead of a million count half a dozen, and keep your accounts on your thumb-nail. " -- Thoreau

This is pretty much why I find Java (and others at similar levels of complexity) distasteful and try to steer clear of anything related to it. It is also why Go appears to me as attractive: it has simplicity everywhere.

[+] setheron|13 years ago|reply
My experience at amazon has been that people.drink the config kool aid. They make everything configurable but never end of changing in the lifetime of the app anything from the sensible defaults.

At that point you've just added unnecessary bloat.

There is something nice to be said about code that works right off the bat with sensible defaults.

[+] irisshoor|13 years ago|reply
I think people get too caught up on the verbosity side of code. Most devs spend considerable amounts of time debugging, and that's probably the suckiest part of the job. The amount of time spent writing the code (especially for someone who types quickly, as most devs do) is immaterial compared to the pain of trying to debug a nasty bug or perf problem (especially in a complex systems). That's where verbosity helps a lot as you don't have to dig into the library code to understand what's going behind the scenes, because most of the relevant configs and choices made in regards to how to use the framework are laid out in front of you.
[+] nviennot|13 years ago|reply
In Ruby, we often use the middleware pattern (the rack stack, sidekiq or faraday to name a few).

In the article, replace "Factory" with "Middleware" and "apply" with "call" and it's just like what we do in the ruby community.

[+] ekyo777|13 years ago|reply
This article doesn't say much about Java, it is mostly about OOP patterns
[+] codewright|13 years ago|reply
>it is mostly about OOP patterns

It's mostly about why I love Clojure's partial / Haskell's currying.

[+] Peaker|13 years ago|reply
This guy must really love his null pointer exceptions.
[+] yxhuvud|13 years ago|reply
I think the author of this article has too much exposure to Rails 2.x and not enough core knowledge of Ruby. If he had actually known the language well, then he wouldn't have made any references to the deprecated rails hack alias_method_chain. Instead, he would have used modules to examplify.

The problem is though, when doing it with modules instead then the points he is trying to make totally disappears.