« Archives in May, 2008

The Awful Java Programming Language

In 1880, Mark Twain wrote a satirical essay entitled “The Awful German Language” where he explains his difficulty in getting the hang of the complicated German grammar. Today, I felt like it was time for me to nag a little bit about the Java programming language.

Don’t get wrong – I’m actually a Java fan. Years ago, I took (and successfully passed) the “Java Certified Developer” exam; I’ve written a considerable amount of Java code in my life. I’ve always loved Java for its run-time environment: the platform-independence you get from the virtual machine and the huge set of powerful libraries. I’m not complaining about Java per se – I’m only complaining about the Java programming language.

Obviously, it’s easy to find weak spots in any programming language – that’s why there are so many of them. Today, I only want to focus on one thing – Java’s wordiness, or rather, Java’s lack of expressiveness.

When developing software, I often start out with a Perl prototype. Yes, Perl is a quirky language, but it is also very powerful and most of its power comes from its very expressive grammar. It is easy to get your job done with Perl.

The other day, I was working on a seemingly simple problem, along these lines: a server produces a text file, containing user vs. usage-time records:

    # Format:  <user> <time>
    # Asterisk: secure connection used.
    Alice 13
    John 440
    Bob 2
    Carl 49
    * Peter 90
    Alice 219
    Bob 8
    Alice 72
    * Jim 1
    Peter 97
    Jim 199

Another process – my program – takes this list as input, sums up all the usage-times for a user and prints an alphabetically sorted list:

    Alice:304
    Bob:10
    Carl:49
    Jim:200
    John:440
    Peter:187

That’s it. Sounds like a five minute job, which it is, if you happen to use Perl:

    #!/usr/bin/perl -w

    open USERS, "users" or die "Cannot access user list\\n";
    /^\\*?\\s*(\\w+) (\\d+)/ and $users{$1} += $2 while <USERS>;
    print \"$_:$users{$_}\\n\" foreach (sort keys %users);

But since I needed this functionality as part of a larger Java product, I bravely recoded it in Java:

    import java.io.*;
    import java.util.*;
    import java.util.regex.*;

    public class GetUsers {
        public static void main(String[] argv) {
            Map<String, Integer> map = new HashMap<String, Integer>();
            try {
                BufferedReader input = new BufferedReader(new FileReader(\"users\"));
                Matcher matcher = Pattern.compile(\"^\\\\*?\\\\s*(\\\\w+) (\\\\d+)\").matcher(\"\");
                for (String line; (line = input.readLine()) != null;) {
                    if (matcher.reset(line).find()) {
                        String key = matcher.group(1);
                        if (!map.containsKey(key)) { map.put(key, 0); }
                        map.put(key, map.get(key) + Integer.parseInt(matcher.group(2)));
                    }
                }
            } catch (Exception e) {
                System.err.println(\"Cannot access user list\");
            }
            for (String key : new TreeSet<String>(map.keySet())) {
                System.out.println(key + \":\" + map.get(key));
            }
        }
    }

Wow! I used the regular expression library and the HashMap container class; I even used Java 5′s autoboxing feature as well as generic containers (both of which save you a lot of casting); nevertheless, the Java version is more than four times longer than the Perl script. Here are the stats:

    Language:  Perl  Java  Ratio
    Lines:     5     25    5.0
    Chars:     191   834   4.4

Is this additional typing really such a big problem? It definitely is! Studies have shown that the number of lines written per developer per time-unit is by and large independent of the programming language used, which means that you are three to four times more productive in Perl than you are in Java. But there is another angle to this problem: if your programming language is highly expressive (like Perl, Python, and Ruby) you are many times more likely to actually write programs. You cannot imagine how many useful programs I have written in Perl that I would have never written in C/C++/Java – just because of all that typing!

I’ve never liked Sun’s “it-is-so-simple-even-a-brain-dead-monkey-can-now-program” paradigm. As a professional software developer – just like a craftsman – I need powerful tools: tools that get the job done in as little time as possible. These tools might be dangerous – very much like a power drill or a circular saw – but in the hands of an expert they can achieve miracles.

But Perl is not perfect, either. In my view, it is good for short programs, less than 1000 lines of code. For larger projects (possibly involving more than one developer) statically typed languages — like Java — are probably a better choice.

Spec Coders

If you’ve been working as a professional software developer for some time, you must have come across a “Spec Coder”.

Spec Coders are usually well-educated, have good grades and know every detail about dozens of specs. Frequently, they come with social skills well above the level of the average (nerdy) coder. They are – therefore – a human resource manager’s dream.

Alas, what they can’t do is write decent code, I mean, readable, reusable, efficient, elegant code. Sure, they’ve read “Kernighan & Ritchie” and they might have taken a three-day Java course, but between their excellent domain knowledge and their (basic) knowledge of a programming language is a big gap in every Spec Coder: a total lack of design capabilities due to a total lack of passion for software development.

This lack of passion clearly shows in their “if-this-do-that-else-do-another-thing” style of programming. You won’t find abstractions, base classes, function pointers, recursion. Just a plain translation of boring spec words into code that sucks.

Here’s an example.

Let’s assume our Spec Coder is assigned the task to write some code for a file system and that THE SPEC says:

3.2 File selection behavior

After selecting a file, the file’s record marker shall be undefined, except for ‘blue’ files, in which case the record marker shall point to the first file record.

Our Spec Coder will immediately turn this into code like this (don’t worry about the use of global variables here – it’s just an example):

void SetCurrentFile(FILE_REF ref, FILE_TYPE type)
{
    ...
    g_CurrentFile = ref;

    if (type != FILE_TYPE_BLUE) {
        // Record marker undefined.
        g_CurrentRecord = -1;
    }
    else {
        // Record marker at first record.
        g_CurrentRecord = 0;
    }
    ...
}

So far so good, at least until someday THE SPEC gets extended (obviously by a non-programmer):

3.2 File selection behavior

After selecting a file, the file’s record marker shall be undefined, except for ‘blue’ files, in which case the record marker shall point to the first file record.
If the file system is in state ‘raw’, the record marker shall always be undefined.

Again, the Spec Coder will directly translate this to code:

    ...
    g_CurrentFile = ref;
    if (type != FILE_TYPE_BLUE) {
        g_CurrentRecord = -1;
    }
    else {
        g_CurrentRecord = 0;
    }
    if (g_FileSysMode == FILE_MODE_RAW)
    {
        g_CurrentRecord = -1;
    }
    ...

How disgusting! Our Spec Coder didn’t take the time to refactor the code logic according to the new requirement. In fact, a typical Spec Coder wouldn’t even think that refactoring this code was a sensible thing to do. Why? Because there wouldn’t be a 1:1 mapping between the code and THE SPEC anymore. Arrrgh!

Any true software developer would have jumped at the chance. A true software developer would have mentally rephrased THE SPEC to read “A file’s record marker is always undefined, except for ‘blue’ files when the system state is not ‘raw’”:

    ...
    g_CurrentFile = ref;
    g_CurrentRecord = (g_FileSysMode != FILE_MODE_RAW && type == FILE_TYPE_BLUE) ? 0 : -1;
    ...

This code is definitely more efficient and readable. If you don’t like the ternary operator, just use an if-else statement (are you a Spec Coder, by any chance?):

    ...
    g_CurrentFile = ref;
    g_CurrentRecord = -1;
    if (g_FileSysMode != FILE_MODE_RAW && type == FILE_TYPE_BLUE) {
        g_CurrentRecord = 0;
    }
    ...

Are Spec Coder’s really dangerous? I think so! Because of their attitude, with every change they make, the code gets slightly more complicated – little by little – until it’s such a mess nobody understands anymore. Once the critical mass is reached, even otherwise decent developers tend to implement their changes by adding little “ifs” here and there. But there is another problem with Spec Coder’s: It is usually difficult to get rid of them, because their usually good spec knowledge makes them indispensable for a company.

Weird, isn’t it?

Douglas Adam’s Cookies

I recently read a funny story by Douglas Adams called “Cookies“.

Here is a summary.

Douglas arrives early for a train, and buys a cup of coffee, a newspaper and a packet of cookies. He takes a seat at a table, opposite of a businessman. After a while, the guy leans forward grabs the packet of cookies, tears it open and eats one. In his story, Douglas explains how he – as an Englishman – is not at all able to cope with this situation, so he just takes a cookie himself. A minute later, the guy takes another cookie and so does Adams. This procedure repeats until the packet is empty. Finally, the guy leaves – they both exchange “meaningful looks”. When the train arrives, Adams gets up, takes his newspaper and discovers underneath it – his packet of cookies! Douglas ends the story by saying that “The thing I like particularly about this story is the sensation that somewhere in England there has been wandering around for the last quarter-century a perfectly ordinary guy who’s had the same exact story, only he doesn’t have the punch line.”

A very funny story, indeed…

After my giggling had settled, I couldn’t stop pondering about it. Doesn’t this seemingly improbable story happen all the time, only slightly differently? How often do we think somebody is plain wrong or is unfair to us, when in fact it is exactly the other way around? How often do engineers, salespeople and managers talk at cross purposes? Isn’t this a terrible good example of a paradigm shift, a total change in one’s perspective?

Douglas picked up the newspaper, which triggered the paradigm shift. If he hadn’t picked up the newspaper, he would have walked around for the rest of his life believing that the other guy was pretty weird. So what is the lesson to be learned? Whenever we think we are treated badly or others are plain wrong, we should try hard to find the newspaper — and pick it up.

About me

Hi, I’m your host, Ralf Holly. I’m a passionate software developer living in Munich, Germany.

With this blog, I want to share my views with you on Code, People and … pretty much Everything!
Drop me a line at ralf.holly_at_approxion.com.

ralf_small3.jpg