Verbosity is not Java’s fault

Quiz: Whats one of the most heard flaws of Java compared to other languages?

Bad Performance? That’s a long overhauled myth. Slow startup? OK, this can be improved… It’s verbosity, right? Right but wrong. Yes, it is one of the most mentioned flaws but is it really inherit to the language Java? Do you really think Closures, annotations or any other new introduced language feature will significantly reduce the clutter? Don’t get me wrong here: closures are a mighty construct and I like them a lot. But the source of the problem lies elsewhere: the APIs. What?! You will tell me Java has some great libraries. These are the ones that let Java stand out! I don’t talk about the functionality of the libraries here I mean the design of the API. Let me elaborate on this.

Example 1: HTML parsing/manipulation

Say you want to parse a HTML page and remove all infoboxes and add your link to a blog box:

        DOMFragmentParser parser = new DOMFragmentParser();
        parser.setFeature("http://xml.org/sax/features/namespaces", false); 
        parser.setFeature("http://cyberneko.org/html/features/balance-tags", false);
        parser.setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment", true);
        parser.setFeature("http://cyberneko.org/html/features/scanner/ignore-specified-charset", true);
        parser.setFeature("http://cyberneko.org/html/features/balance-tags/ignore-outside-content", true);
        HTMLDocument document = new HTMLDocumentImpl();
        DocumentFragment fragment = document.createDocumentFragment();
        parser.parse(new InputSource(new StringReader(html)), fragment);
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        Node infobox = xpath.evaluate("//*/div[@class='infobox']", fragment, XPathConstants.NODE);
        infobox.getParentNode().removeChild(infobox);
        Node blog = xpath.evaluate("//*[@id='blog']", fragment, XPathConstants.NODE);
        NodeList children = blog.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            node.remove(children.item(i));
        }
        blog.appendChild(/*create Elementtree*/);

What you really want to say is:

HTMLDocument document = new HTMLDocument(url);
document.at("//*/div[@class='infobox']").remove();
document.at("//*[@id='blog']").setInnerHtml("<a href='blog_url'>Blog</a>");

Much more concise, easy to read and it communicates its purpose clearly. The functionality is the same but what you need to do is vastly different.

  The library behind the API should do the heavy lifting not the API's user.

Example 2: HTTP requests

Take this example of sending a post request to an URL:

HttpClient client = new HttpClient();
PostMethod post = new PostMethod(url);
for (Entry param : params.entrySet()) {
    post.setParameter(param.key, param.value);
}
try {
    return client.executeMethod(post);
} finally {
    post.releaseConnection();
}

and compare it with:

HttpClient client = new HttpClient();
client.post(url, params);

Yes, there are cases where you want to specify additional attributes or options but mostly you just want to send some params to an URL. This is the default functionality you want to use, so why not:

  Make the easy and most used cases easy,
    the difficult ones not impossible to achieve.

Example 3: Swing’s JTable

So what happens when you designed for one purpose but people usually use it for another one?
The following code displays a JTable filled with attachments showing their name and additional actions:
(Disclaimer: this one makes heavy use of our internal frameworks)

        JTable attachmentTable = new JTable();
        TableColumnBinder<FileAttachment> tableBinding = new TableColumnBinder<FileAttachment>();
        tableBinding.addColumnBinding(new StringColumnBinding<FileAttachment>("Attachments") {
            @Override
            public String getValueFor(FileAttachment element, int row) {
                return element.getName();
            }
        });
        tableBinding.addColumnBinding(new ActionColumnBinding<FileAttachment>("Actions") {
            @Override
            public IAction<?, ?>[] getValueFor(FileAttachment element, int row) {
                return getActionsFor(element);
            }
        });
        tableBinding.bindTo(attachmentTable, this.attachments);

Now think about you had to implement this using bare Swing. You need to create a TableModel which is unfortunately based on row and column indexes instead of elements, you need to write your own renderers and editors, not talking about the different listeners which need to map the passed indexes to the corresponding element.
JTable was designed as a spreadsheet like grid but most of the time people use it as a list of items. This change in use case needs a change in the API. Now indexes are not a good reference method for a cell, you want a list of elements and a column property. When the usage pattern changes you can write a new library or component or you can:

  Evolve your API.

Designed to be used

So why is one API design better than another? The better ones are designed to be used. They have a clearly defined purpose: to get the task done in a simple way. Just that. They don’t want to satisfy a standard or a specification. They don’t need to open up a huge new world of configuration options or preference tweaks.

Call to action

So I argue that to make Java (or your language of choice) a better language and environment we have to design better APIs. Better designed APIs help an environment more than just another new language feature. Don’t jump on the next super duper language band wagon because it has X or Y or any other cool language feature. Improve your (API) design skills! It will help you in every language/environment you use and will use. Learning new languages is good to give you new viewpoints but don’t just flee to them.

29 thoughts on “Verbosity is not Java’s fault

  1. Actually verbosity is Java’s fault … when speaking about a language, you’re also speaking about the ecosystem of tools around it.

    Java has great IDEs available, all of which have intellisense … this is a given, and I’ve heard very few developers that aren’t using one.

    Having auto-completion available makes developers lazy … in dynamic languages the API simply has to be easy to use and easy to remember.

    When talking about languages you’re also talking about the culture around it. It’s really hard to create clean APIs when best practices are leaning towards monstrosities like these …

    BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(“file.txt”), “UTF-8”));

    • Of course the best practices have to be adapted, too. But many of these are influenced by the APIs. So changing the APIs causes the best practices to change.

    • So write the following Java code instead:

      RandomAccessFile in = new RandomAccessFile(“file.txt”, “r”);

      This is also a JDK class (from java.io), and it supports reading UTF-8.

      Now, sure many Java APIs are unnecessarily complicated, but quite often the developer using them is the one to blame, not the language or the standard APIs.

      • I am not saying that there aren’t any good APIs in Java land. My point is that much of the verbosity Java is blamed for is in the APIs and how we use them and not tied to the syntax.

  2. Agreed, a lot of Java APIs seem to be designed with the motto “make everything equally difficult” in mind.

    I do think Java would benefit from a literal syntax for hashes, though.

  3. Some of the verbosity is Java’s fault. Sleeping for a while in C#:

    Thread.Sleep(500);

    Sleeping for a while in Java:

    try {
    Thread.sleep(500);
    } catch(InterruptedException iDontCare) {
    // TODO Auto-generated catch block
    }

    OK, so the comment is an Eclipse-ism rather than Java, but you get the point. Checked exceptions are a nightmare of pointless verbosity, particularly when API developers misuse them.

  4. It looks like it is an example of Tell, Don’t Ask principle paired with Domain Driven Design.

    – What do I want? I want to replace stuff in this HtmlDocument with other stuff -> document.replace(originalStuff, newStuff)

    – What do I want? I want to send a post request -> client.send(postRequest)

    – What do I want? I want to add attachment and action bindings to a table -> table.add(columnBinding)

    The last one made me think. Why do you use “tableBinding.bindTo(attachmentTable, this.attachments);” ? Is it because of JTables API design? Why not subclass JTable?😉

    @Adam
    Yes, Java could be less verbose. Language constructs like C# properties are less verbose, auto-properties don’t even need need a backing variable and getter/setter are not scattered all over my class. Less typing -> less reading.

  5. I agree with jens. A lot of frameworks and libraries want to cover all possible (and sometimes impossible) aspects of a domain … very often for the cost of simplicity. So you have to write a lot of boilerplate code to accomplish simple standard tasks.

    Sometimes I have the impression we’ve lost the idea of KISS just to make even the simpliest things as configurable and adaptable (and thus complex) as we can.

    This is not a specific java problem, but because java is the language with the richest eco-system, it is the one you can see this best.

  6. You’ve missed the point completely. Verbosity is a side effect of of having to declare types on both sides of an assignment, not having an initializer syntax, having to iterate over collections or having to write entire classes to simulate a closure.

    It’s the difference between:

    List strlist = new List();
    and
    var strlist = new List() // borrowed from C# syntax

    Or
    for (Object o : olist) { … }
    and
    List.map(olist, op)

    I think you get the point. You may not want to blame Java, but the fault here is squarely on Sun (and therefor Java) for not keeping up with modern language and API design trends.

    • Syntax is one kind of verbosity. But I argue that in most Java programs/code bases the majority of the verbosity comes from badly designed APIs not from the Java syntax.

      • You can argue that all you want, but the kind of verbosity *I* care about isn’t of the API variety. I can *fix* that problem–what I can’t fix is the impoverished model of abstraction that lies beneath.

      • Of course, Dave, there is verbosity in Java, the language, and there are languages out there which are way better abstracting things even ones that are quite old like Lisp. One of my points made here is that many developers use this lack of abstraction as an apology for poorly designed APIs. I met too many just saying: if I only could code in language X my code would be so much better. But they design horrible APIs and blame it on Java, and that’s not fair to Java.

  7. Verbosity is one of Javas strong points.

    Terse languages like Perl famous for its one liners or the morse-like code you can achieve with c++ is perferred by people who do mostly one-man projekts.

    If you do big enterprise projekt with say 50+ developers, then the verbosity of Java is your friend cos you’ll be reading a lot of code made by other people. Java code can be read at a steady pace, almost like a book because it has fewer ambigous launguage constructs than most languages and only a mild dose of syntactic sucker that bring along a lot of hidden asumptions.

    As for APIs (not the language) there is so much to chose from in the Java ecosystem. I dont think can make good case that Java APIs in general are very verbose by picking a few extreme samples.

    • OK, maybe I was not clear enough: not all Java’s APIs are verbose. I think most of the verbosity seen in Java code nowadays comes from bad APIs and not from the syntax of Java.

  8. BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); s = in.readLine();

    in c++ cin>>
    in python input(“”)
    in ruby gets.chomp

    yes maybe its because bad apis, the problem is that the bad apis begins with the sun ones

  9. If you have a verbove API that deal with all cases and you need a simple one… Just make a small API/class/facade that will do the job for you.

    It is the difference : in java you can do everything (from an IT point of view) and you adapt “rich” and complex API to do this.

    Many other language offer clean API or more syntaxic sugar but sometime the code is more difficult to read/understand, and ofen many thing simply can’t be done… Or you need to write the full API in the first place.

  10. Pingback: Verbosity is not Java’s fault

  11. Great post, I cannot agree more. Most of the Java verbosity comes from “misdesigned” APIs. The JTable code above is a good example how a “Sun-only” interface can be improved for daily business by adding more useful constructs.

    Maybe “newer” languages already come with a nicer API, true. But this can easily be achieved by every Java programmer, company, open-source organisation as well.

    It’s trivial to write a new class whose (main) constructor takes a file name and opens it for UTF-8 reading by wrapping all those necessary streams. Are we programmers or what? Just write your own API if you really care.

  12. Pingback: Rozwlekła java « Miała być Java

  13. The Reflection API is a fairly shocking example of the needless verbosity of Java. And I would consider the official API to be part of Java.

    Here’s a simplistic example in Java and Ruby, replacing characters in a string (“putty” => “puppy”) first directly and then via reflective invocation:

    // Java
    String s = “putty”;
    System.out.println(s.replace(‘t’, ‘p’));
    try {
    Class c = s.getClass();
    Method m = c.getMethod(“replace”, char.class, char.class);
    System.out.println(m.invoke(s, ‘t’, ‘p’));
    } catch (Exception e) {
    e.printStackTrace();
    }

    # Ruby
    s = “putty”
    puts s.gsub(“t”, “p”)
    puts s.send(“gsub”, “t”, “p”)

    This kind of verbosity is prevalent in Java’s standard libraries, particularly when (anonymous) inner classes are involved. At the moment I’m struggling with “doPrivileged” blocks in some Java code which deals with sandboxing, and it is syntactically very unpleasant.

    • Yes, you are right. But in my post I argue that not the syntax of Java is verbose but the APIs. And we can change or adapt the APIs.
      So in your example that would be a new method like ReflectionUtil.invoke(s, “replace”, ‘t’, ‘p’) which encapsulates all the stuff necessary to call the method via refelection.
      While languages like Ruby help to adapt your syntax and make it even less verbose, you can also use better APIs in Java to reduce verbosity.

    • You cannot compare interpreted languages with not-interpreted languages. Interpreted languages are always less verbose.

      • Of course. But you can kill a lot of verbosity with the right abstractions and the right API.

  14. Wow, Java seems almost as idiotic as ActionScript in current Flash versions🙂

    You used to be able to do object.alpha = 50 or something, now you need to do stuff like

    var myAlphaChanger:alphaChanger = new Module.Action.AlphaChangerModule;
    alphaChangerModule.opacity:opacityType = number(50);
    myAlphaChanger.opacity.new ColorEffect().apply();

    But that’s probably because nowadays, even the very last backyard
    farmer needs to be able to program…🙂

  15. This is the reason why libraries exist. You can always use other libraries if you are not satisfied with the default API.

    • Actually the default API just provides the basics. They don’t have the purpose to inflate the default API to cover all usages.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s