Hacker News new | ask | show | jobs
by morecoffee 3155 days ago
Java is commonly criticized for being too verbose, but I never understood why. I agree it is verbose, but verbosity isn't really that bad of a problem. Programs aren't harder to write, they aren't more bug prone, and they aren't harder to understand. On the contrary, high verbosity means less information per token, making it easier in my opinion to read.

A good example is the anonymous class. They are portly and wasteful of vertical space, often costing 5 lines when one would due. But, the amount thinking per line is greatly reduced. In order to visually afford anonymous classes, logic must be simplified or structured, commonly by splitting up a larger function in order to fit it on a single screen. An arguable misfeature of the language has a convenient side effect of forcing best practices.

10 comments

> On the contrary, high verbosity means less information per token, making it easier in my opinion to read

See I think this is actually backwards thinking. The more boilerplate you have to sift through, the more you're trying to retain before getting to what the program is actually doing.

> A good example is the anonymous class. They are portly and wasteful of vertical space, often costing 5 lines when one would due. But, the amount thinking per line is greatly reduced

Same applies for this statement. You're trying to absorb so much more code before knowing what is actually happening.

Yeah but the boilerplate is basically invisible to anyone with experience in the language
This phenomenon is a genuine quality problem.

Small bugs in the implementation of boilerplate code have a tendency to sail through code reviews and go without notice until they become production issues, because experienced developers develop a habit of glossing over boilerplate without reading it too carefully.

I think that's the issue though. One should not need to have much experience in any particular language to read and understand what a particular piece of code is doing. It should be relatively intuitive. The more boilerplate a language has, the larger the cognitive load. This holds true regardless of whether or not it is invisible to anyone, it's just that much more annoying. I'm not doing a good job of expressing my thoughts here, but I absolutely "feel" this way when working with Java vs something like Python.

That being said, I'm a big of Java and the eco-system.

"One should not need to have much experience in any particular language to read and understand what a particular piece of code is doing."

I'm not sure I agree with this. I think every effort should be made to keep your code readable to others with similar knowledge. However, I don't think you need to make everything readable by a junior level coder.

Maybe a decent analogy is that not all books target a 4th grade reading level. The varience of information density isn't just about saving time for those that understand it, but also for keeping you interested (or disinterested if you aren't ready for it yet). For example, reading young adult fiction in your 30s usually wouldn't keep you engrossed.

The older and more experienced you get, the harder it is to assume others who will have to deal with the code will have "similar knowledge".

"However, I don't think you need to make everything readable by a junior level coder." I may not be a junior-level coder, but I may still be 'jr' with your particular language or framework, but have been assigned your code because you've moved on to something else.

I've never written a nontrivial Java program but generally speaking I find it pretty easy to read Java code.
Exactly which is why no one is going to look at all those getters and setters you added not realizing that one of the setters actually does something other than setting the field or a getter causes some side effect before returning the value.
To be fair, most people use IDEs that generate them based on the fields so this would be unlikely.
Unlikely, but to be sure, you have to read all the boilerplate, attentively.

If your language generates them behind the scenes, so that nobody can modify them, that doesn’t happen.

Also, if a developer overrides one particular example, it stands out in the source, as it (ideally) is the only code visible in the source.

Unlikely edge cases are the biggest source of bugs. One of the worst production bugs I've seen happened because someone refactored some code assuming a getter just got the field, like 99.9% of getters do, but this particular getter didn't.
I think you miss my point. Most people DO generate them via an IDE so they don't get looked at closely. But imagine someone then editing one of the generated methods to do something different than expected. Happens all the time.
True, but it does have impacts, like you can see less of the overall program on the screen at a time, so to scan through requires more of a look->scroll->look->scroll.
Sure, but excessively dense code has its own drawbacks. Does anyone like reading regexes?
Compared to the equivalent handwritten state machine, yes.
I don't think dense code has drawbacks; people measure in lines of code because they implicitly assume all lines are equal, but that's completely wrong. Reading the same logic when it's 20 lines is much, much easier than reading the same logic when it's 100 lines, because whether you can fit it on a single screen or not makes a huge difference to whether you can comprehend it.
Never worked in Perl, I take it
Even if that were true, it still wastes a lot of space and can make reading the whole body of code more difficult. Just think about how easy it would be if Java had 2 or 5 times the boilerplate code it has now. According to you it'd be "invisible," but it'd still be a lot worse.
Ergonomics changes your design decisions. When some idiom of code or data or both is awkward to express, you'll lean naturally to something else, which may have drawbacks not related to ergonomics, like coupling or over-abstraction or duplication, etc.

Ergonomics goes into the mix of tradeoffs for design. Something like LINQ's expression trees, for example; not easy to do in Java not because ASTs can't be constructed, but because their construction isn't as ergonomic.

I think in Java this is most notable in the boilerplate it takes to create value types (and related: typedefs). This often leaks from the realm of bad ergonomics into the realm of bad design; primitive proliferation is a common problem that I believe would be less pronounced were there a more convenient way to define a value type.
This sounds like Stockholm Syndrome. The low-information verbosity is actually good because...
I've programmed in python, scala, and java quite extensively. There definitely is such a thing as a good writing language and a good reading language.

Python fits nicely in both, but java is a great reading language. If I had to maintain any existing codebase I would prefer a java one.

Scala is the great obfusciator.

I have used all 3 extensively, too. And when it comes to large, sloppy code bases, I'd take the Java over the Python any day.
Couldn't this same reasoning be used to argue that we don't need for loops or functions because we have GOTOs? Boilerplate is tedious and error-prone to write and to read/understand in my experience.
It cannot. The syntax bloat forces structural cleanliness. A lower level problem is addressed with a higher level fix. It would be better of course to not have bloated syntax, but not at the cost of better program logic.

As for tedium: Java programmers rely heavily on IDEs to "write" most of the boilerplate for them. The IDE fills in tokens automatically, and hides them visually with +/- boxes to the side.

But if the bloat is hidden, how is it forcing structural cleanliness?
Personally I don't hide it, and I do type each token by hand. Since the parent brought up tedium, I wanted to mention that there are solutions to it. IDEs hide bloat, but code review and other tools often don't.
No, those things aren't even boilerplate.
I agree. Java is one of my favorite languages partly due to its verbosity. It's easy to figure out what I was doing when looking at my code later on. It's also easier to repurpose old code.
There is a language agnostic rule hat there is a linear relationship between lines of code written and number of bugs.

High verbosity == more lines == more bugs.

Depends on the person I guess. I like terse code. I like pure functions. Maybe they have somehow a little cost because they can be complex, but the semantics make the reasoning quite cheap. In OO, every goddamn line is a potential nightmare.

Also, I bet 10$ that until you saw some short yet clean and expressive code, you might believe that the choice is either Java verbosity or Perl cryptics.

I agree with your general sentiment that Java verbosity is actually a strength rather than a weakness. However, the examples given in this particular article are all (IMO) cases where the verbosity truly is unnecessary and is mainly there because for backwards-compatibility. These shortcuts do not reduce readability significantly and I would love to have these in Java.
I think Java is oaky-ish. Much more commonly than core Java itself, Java libraries are being criticized for verbosity. All of those satire AbstractSingletonWorkerFactoryImpls come from real world experience. I personally see a lot of design pattern use for the sake of use without considering benefits that would bring. I see Java code happily introduce two line boilerplate to median call just to shave single line from an edge case. Scattered all over the codebase this makes business logic part of application rather verbose.
You have to create and read more tokens in a verbose language. That takes extra time, and the more tokens, the higher the odds are for bugs to creep in.