When All You Have Is a Class

I care little for static typing, but when a language gives you static types, use the type system.

Say we have a domain class like

public class User {
  public User(String firstName,
              String lastName,
              String email,
              long balanceInDollars) {
  ...
}

I’m in agreement with Stephan that using String and primitive types here is wimping out. That is weak typing. Weak! Chuck Norris does not approve!

The post goes on to describe a more typesafe and relatively elegant implementation. While obnoxiously verbose, its type system is not Java’s real problem. The actual deficit that makes Java less expressive than many others is that it only supports one modeling paradigm, the ubiquitous class.

Take an interview question as an example:

Given an input string, write a program that lists the top n words. So for the sentence, “Do or do not,” the top 2 tokens would be:

do = 2
not = 1

Sort first by frequency, then lexically by token.

A reasonable solution takes four conceptual steps:

  1. Tokenize
  2. Count and map tokens to frequency
  3. Sort
  4. Display the first n

In Java, sorting causes the most code. The most obvious way to maintain type safety demands an entirely new class; it contains two properties, token and frequency; it implements Comparable, equals and hashcode. The implementation then sticks instances of this class into a sorted data structure.

An alternative implementation could eschew the new class, instead jamming data into two-element Object arrays then sort using a Comparator. This would likely be shorter but lose type checking along the way.

The first feels unnatural because the data and the sorting behavior have no intuitive connection. Word frequency means nothing outside the sentence while sort order means nothing outside the problem. The two should live apart but the language foists that artificial marriage on the program. To make the error in this design more clear, consider if the problem specified that sort order should be interchangeable. For example, sort same-frequency tokens by length instead.

The second approach, though more conceptually pure, loses type safety. Using a value class containing token and frequency improves it but once again that class lacks conceptual justification. The token itself is unrelated to its frequency when apart from the sentence.

Like many problems, this one only involves scraps of data and a way to sort them but both Java programs require class implementations in a problem with no natural need for modeling anything as a class.

Not only does Java make you think in classes even when inappropriate, it simply refuses to acknowledge that any other problem model exists. You want collection literals to group data? Forget type safety. First class functions? Better define an interface. Mixins? Sorry, not even multiple inheritance. Declarative domain specific languages? Good luck. When all you have is a class, everything looks like an object.

The Trouble With Stack Overflow

More and more, searching for how to do one thing or another leads me to question and answer site Stack Overflow. This is good in many ways, especially because Stack Overflow’s open format allows anyone to read full answers, obliterating closed systems like Experts Exchange that used to clutter Google results but refused to actually give you the answer without registration.

Lemming that I am, I signed up. Not thanks to an altruistic desire to make the Internet a better place by helping others, nor to get my own questions answered. Stack Overflow has grown to a critical mass where enough employers and peers might know it to conceivably consult your reputation on the site as a signal of competence.

Many talent markets suffer from asymmetric information. Computer programming productivity studies find order of magnitude differences between the best and the worst talent but no corresponding difference exists in pay, which ranges only from $54 thousand to $104 thousand for averages of groups from lowest to highest seniority. Taking on faith the intuition that this represents a market failure and therefore inefficiency, Stack Overflow’s token economy for reputation points that track the user’s talent looks promising as a potentially more efficient signaling solution.

The economic idea of “signaling” refers to sending a message by choosing a costly action. I signal when I buy my wife flowers on Valentine’s Day; I am not convinced she needs the blossoms in mid-February. I am sorry to say this to all you cheapskates out there, but the cost of signaling is the entire point. A fancy diamond ring goes further than flowers…

Love cannot be measured scientifically or directly, at least not until neuroscience dramatically advances. We must instead show other people all the time that we love them, and that means we look to send the right signals.

Just as in the market for love, the market for programmers could benefit from signals. The signalers’ main real cost is time, but the tokens of Stack Overflow’s economy are questions questions, answers and votes. Successfully bartering questions and answers into votes builds reputation.

Judging by the number of answers that now appear prominently in Google results, this makes a very successful business. But after only a short stint of use, I will heavily discount Stack Overflow reputation as a proxy for talent because of what users call the “Fastest Gun in the West” problem:

If a person sits down and answers a question in a long, thorough way, going through every nook and cranny, once they post their answer, it will already be one of about seven different ones, some of which have already been upmodded. This wouldn’t be a problem if those answers were as thorough as the one this guy’s posting, but they usually aren’t. Some of them are downright wrong, some aren’t even answers to the question.

I personally observed this when answering a Java homework question:

I’m trying to count the number of characters that occur in a java string. For example: given the poker hand 6s/3d/2H/13c/Ad
how many times does the / character occur? = 4

That question received three answers before mine. All three were wrong. That’s right. Ask, “how to count the number of a specific character in a string,” and three users with respectable reputation respond incorrectly.

This is not likely to change since Jeff Atwood and others agree with legitimate reasons for encouraging many rapid answers. They say there is no problem because “getting rapid answers the entire goal of a question and answer site.” For some purposes, however, there is a problem. For signaling talent, writing a blog and developing an online code portfolio is still a better option.

Percieved Inhumanity

Butthurt (adjective): annoyed, bothered or bugged because of a perceived insult

In Change Your Organization: A Diary, James Shore writes an intriguing account of how he worked as a peon to change his organization from a position of little formal authority. The diary describes an experience that will seem familiar to many programmers and his commentary is often right and valuable. I wish he advised, however, on how not to be so butthurt.

The PM went back to his cube (on the other side of the building). A few minutes later, I got a call:

PM: Those two new issues are absolutely critical. They have to go in to the next drop.
Me: I only have time to do one before I leave. Which one’s most important?
PM: Both are critical. They won’t accept the build if both aren’t in. They have to be in.
Me: Well, I don’t see how that’s possible. I’ve estimated them at two hours each, and I don’t have that much time.
PM: Can you come in on Friday? (Friday is traditionally a holiday.)
Me: No, I’ll be out of town.
PM: Okay, well, they have to be in. Can’t you just do them tonight?
Me: I have to meet someone at the airport. The latest I can leave is 6:30, which doesn’t give me enough time to do both.
PM: It’s critical that these two things be in the drop. Can’t you just come in on Friday?
Me: No, I’ll be out of town.
PM: Who else is qualified to do work on these issues?
Me: Joe or John.
PM: John’s wife just had a baby, and Joe’s going to be at the beach on Friday. If you can’t do these tonight, I’ll have to call John or Joe.
Me: My estimate for these two tasks is four hours. I’ve estimated them in the best way I know how. I don’t see how I can get them done tonight.
PM: Can you come in for just a few hours Friday morning?
Me: I’ll be out of town.
PM: Where?
Me: (My home town, two hours away.)


I have some compassion for what our PM was going through. Remember, it was 2002. Jobs were hard to find. The PM was scared.

That still doesn’t excuse [pressuring us to work extra hours]. It didn’t do any good–in fact, I’m sure it hurt performance–and, in my opinion, it was inhumane and unethical.

Shore never quite goes far enough to invoke Godwin’s Law, but “inhumane?” As in “cruel and savage?”  Genocide is inhumane. A manager’s request for overtime hardly qualifies.

Murdered Emaciated ChildrenLumbergh from Office Space

Shore highlights the importance of respect for employees. Were he the manager, he says, he would “be absolutely professional and respectful … avoid placing blame, and focus on their well-being.” Though he does acknowledge this would not have saved the project, the analysis implies that respect is a necessary condition for success.

I think that projects will rarely succeed when executed by an organization lacking internal respect. That common sense seems logical, since resultant infighting and lack of cooperation would tend to decrease efficiency, but the intuition still begs for questioning.

About two minutes into one presentation, Gates had stood up, looked around the room, scowled at the newly arrived product manager, and said, “Where the fuck did we hire you from?” The manager left the meeting in tears and within a week had left the company.

Before arguing that Bill Gates cheated or bargained with Satan remember Linus called Subversion “the most pointless project ever started” (video transcript). Neither man, though successful, could reasonably be described as respectful in these instances. Personal experience, however, still does not allow me to believe that an inherently disrespectful culture can also be efficient and successful.

To resolve the contradiction, it is worth defining respect in an organizational setting. Shore advocates unconditional respect. “Don’t think of others as incompetent,” he says, “Look at problems and think, ‘There must be a reason things are the way they are.'” While sound, this denies the reality that incompetence often really did cause the problems. Second, it appeals only to the degenerate form of respect that implies only tolerance, as in “I disagree but respect your right to use Perl.”

“Civility” would be more accurate. Calling that respect risks a dangerous myopia that sees esteem as a goal unto itself. Explicit encouragement of unconditional respect focuses the group on an unproductive and impossible goal, distracting from productive work.

Simple distraction is not, however, the most harmful consequence of focus on respect for its own sake. True respect, respect that means admiration as well as tolerance cannot be unconditional. Respect must be earned. To advocate freely given respect undermines its meaning and its power as an intrinsic motivator.

Successful managers do respect their employees and foster respect among their employees. This works not because it is moral or ethical but because pursuit of respect motivates. An effective manager indicates a clear path to earning respect and makes that path align with the organization’s goals. Bill Gates knew how; Shore’s project manager did not.

Android List

Some time ago, I wrote a shopping list app as an exercise to learn Android programming. I do not plan to maintain this or enhance it, but the code is now available.

It is just a couple simple list views. One view adds items to the list. All items ever added remain in that view, the inventory. The other view is the actual shopping list. Tapping an item in the inventory moves it to the shopping list; tapping it in the shopping list moves it back to inventory.

A right or left swipe switches between the views, which brings up an annoying factoid: the Android api does not have built-in swipe detection. Creating your own gesture detector is easy; 30 seconds on Google finds as many slightly different implementations as you could care to see. Nevertheless, swiping is a simple, common need. A side-to-side swipe detector and a zoom detector would probably cover almost every application.

This illustrates another reason to like Python:

Fans of Python use the phrase “batteries included” to describe the standard library, which covers everything from asynchronous processing to zip files.

Death To the Downloaders

Paint.Net is a well-known free photo editor. It may be an excellent product but I cannot recommend it because only an alert and somewhat savvy user can navigate its website to find the actual installer.Paint.net homepage screenshot The home page sidebar looks like advertisement, so that big blue button looks like right place to click.

Nope. That installs Pdf Creator and its pile of adware.

Once you figure out the most prominent item on the page actually contains adware, your next likely target becomes the big green button.

Wrong again. This time you get Zoom Downloader.

Think about downloaders for a moment. When computers were made from bamboo and ran Netscape 1.0, downloaders may actually have added useful functionality to a browser. In 2012, they have been pointless for at least ten years but hapless Internet users still confront them constantly.

In the spirit of not ascribing to malice what incompetence can explain, some of these downloaders are pet projects, done only because they are easy, solving problems that don’t exist and creating new ones.

If you did upgrade to the latest version of Flash from the Adobe website, you very likely have Adobe Download Manager installed.

What is the Adobe Download Manager? “The Adobe Download Manager (Adobe DLM) is a small application that is used to deliver two of Adobe’s most frequently downloaded products, Adobe Reader and Adobe Flash Player.”

Is the Adobe DLM safe to use? According to Adobe: “The Adobe DLM is signed by Adobe, uses SSL, MD5 checksum integrity verification, encryption and other methods to insure that the software you request is the software you receive from Adobe.”
Pay attention to the bold part of the last sentence. The reason I marked this part of the sentence is that apparently you can force automatic download and installation of software upon anyone who visit your website and have Adobe Download Manager installed [CVE-2010-0189]. Safe to use, ha?

Download managers by definition require firewall openings and not all downloader creators are as stupidly benign. They produce software you do not need. They trick you into installing them.

Aunt Millie, of course, realizes none of this; she just wants to remove red-eye from her cat pictures. By now utterly baffled that she cannot get Paint.Net to install, if she can find her way back to its site with her now crippled browser and locate the small download link, she tries again. Paint.Net download page screenshot This time she gets one step closer, the actual download page, with another big blue download button.

Fool me thrice. Another download manager.

On fully patched and otherwise completely clean Windows Xp, I took before and after screenshots. Internet Explorer froze once and was so broken after the second install that I could not download the third craplet. Something along the way disabled Windows Firewall.

Ideally, when someone clicks those ads, the browser would interrupt with, “Awesome Downloader Express from Trojans R Us is not the software you want. Try http://example.com/therealsoftware.exe instead,” a stillborn scheme due to implementation difficulty. Gray-hat warring with distributed spiders that drive up click and bandwidth costs might at least be more fun. I am not sure my vigilante altruism goes that far, but if I find someone waging that campaign, I will applaud them.

So the best I can do for poor aunt Millie is rage. From one remote corner of the Web, the futile scream goes out, “Paint.Net, you may be a fine program, but I cannot support you.”

Groovy, The Gateway Drug

Once upon a time, the only languages I trusted used static typing. This now seems silly, but is a fairly common attitude and for good reason. To a developer trained in C++ and Java formality, using Ruby or Python feels like anarchy. And there is that pejorative term “scripting language.”

At my first job after college I built Java Enterprise Web Services on the gruesome Servicemix platform. My task involved deploying the xml beasts and synchronizing our Cvs repository with the Devil’s own source control. Just maybe, this was a job for a scripting language. Just a taste couldn’t hurt…

So I found Groovy and got myself a copy of Groovy In Action.

At first, my Groovy scripts looked like Java, semicolons and all, since almost any Java program is also valid Groovy. An established codebase full of closures and duck types would have been alien, but to the programmer tiptoeing at the edge of dynamic language, Groovy felt very safe. After time, the same comforting safety eventually made Groovy feel like lugging Java baggage, but I highly recommend it for the programmer monogamous with Java. Just start renaming your Java files with Groovy extensions.

Next, drop a semicolon here and there and those ridiculous “throws Exception” clauses. Then, discover the “each” method; it seems like syntactic sugar, but explore. It involves some wacky thing called a closure. Write a function that takes a closure argument.

Every once in a while, try writing “def foo” instead of “String foo.” Surely dangerous, but promise yourself it will just be this one more time. The examples all do it; how bad could it be?

Ask yourself again, “What’s so great about closures?” Google says they sprout like weeds among the Ruby community. That’s still not a real language, but maybe Groovy is; it works with Java, after all.

Soon enough, you will realize Java feels stifling. “Dicing all this xml sure would be easier in Groovy,” you will think. You will notice and understand dynamic language zealots. The cool kids mostly run Ruby and Python. Java virtual machine startup delay is a drag for scripts, so try one of those.

No variable declarations at all? No damn curly brackets? You will be hooked.

Google Reader Squish

Remember when Google was minimalistic? This is Google Reader now:

Google Reader default user interface

At 1600 x 900 resolution, this relegates actual content to only about two thirds of the available screen space, part of a 2011 Google effort:

The way people use and experience the web is evolving, and our goal is to give you a more seamless and consistent online experience—one that works no matter which Google product you’re using or what device you’re using it on.

The “elastic” interface concept that Google intends to follow sounds like the idea of making a single page that works well on both a desktop and mobile device. It turns out that the mobile page is actually completely different, so the new desktop look must be more for styling than cross-device usability.

To be fair, the interface is minimal in that it displays only a few buttons, but I think Google went too far making the interface look touchable. Modern phone browsers render normal pages faithfully while handling the small screen size nicely, so a page that displays well on high and low zoom on a desktop will also likely display well with little or no modification in a mobile browser. Even if it were intended to work on widely varying screen sizes, I see no functionality reason for expanding incidental controls to consume almost a full third of the screen:

  • Links to unrelated Google services
  • Search box
  • 11 buttons

So decided to experiment with customized style sheets using the Stylish Firefox Add-on. The Stylish site already lists plenty of compact Google Reader styles, but I did this for the practice and also because many of the minimal styles I tried removed functionality such as the logout link.

Google Reader Restyled

I called the style “Reader Squish” and published it on userstyles.org under the WTFPL.

Unicomp Customizer

I am writing this on my brand new Unicomp Customizer. Since first reading Have Keyboard, Will Program, I wondered whether buckling spring hype was really worth it, especially since I have long loved the near-perfect1 Microsoft Natural 4000 layout.

Within an hour or two of receiving my keyboard and excitedly testing it on online typing tests and games like Qwerty Warriors, I realize this is the first keyboard that actually speeds up my typing. In that short time, my beloved Microsoft Natural has started to feel spongy and uncomfortable. [Update, March 2020: Flash is dead and Qwerty Warriors with it; my JavaScript version is at https://www.qwertywar.com/]

Finger exhaustion makes the difference. Five minutes full bore on another keyboard and my fingers feel tired. Tired fingers make more mistakes; I backspace more; I slow down. On the Unicomp, however, my fingers feel just as sprightly after the test as before. At test completion my fingers feel as if they have been jumping on a trampoline and their parents just spoiled their fun by telling them to come in for dinner.

Beside tantalizing finger pleasure, the Customizer adds visceral clattering spring charm. By practicing a soft touch, you can dull the sound a little, but passersby will always think a mini war zone surrounds your computer. And I thought even the Microsoft Natural’s space bar was a little loud in an office.

Regardless, those who regularly type long blocks of text might justifiably tell coworkers to suck it up. Even without an ergonomic layout, the reduced finger fatigue over just a five minute test makes up for every clicky keyboard comment. Sadly, the Customizer will probably not increase my overall work efficiency. My typing usually involves the typical programmer’s short bursts and frequent contortions for symbols.

So I probably will not use it in an office and I am unlikely to gain significant typing comfort or speed, but was it worth it? $80 to make typing fun again? I think so.

  1. I have only two gripes with the Natural’s layout. First, six should be on the right, but the peculiar left-handed six position may not have been Microsoft’s decision; it infects most split layouts, including the original Natural’s contemporary IBM M15. The second mistake, F Lock does belong exclusively to Microsoft.

Object Disorientation

Ask not what you can do to your objects, but what your objects can do for you.

The object-oriented primer tells us that objects are collections of data and behaviors. Sadly, modern Java de-emphasizes the behaviors, telling us we just need a bunch of beans wired to a few business functions and… tada… object-oriented magic.

This sort of programming tends to not be object-oriented at all. It generally leads to reams of what Martin Fowler calls “getter confetti,” plus a few thousand-line methods that do all the real work in about as procedural a way as you can make an object-oriented language.

I nominate this pattern for the name “object-disorientation,” or “object-disoriented.” Yes, someone already called it the blob, but the blob differs in its cause. The blob results from “sloth” and “haste.” Object disorientation results from careful, intentional misapplication of object-oriented principles. Someone says to encapsulate data, and someone carefully encapsulates fields, missing the more subtle encapsulation and allocation of behavior.

I suspect it happens because people think of programs as recipes for solving problems rather than reflections of the problems themselves. We tend to ask the steps from here to there rather than heeding Hannibal Lecter and asking of each particular thing, “what is it in itself… what [is] its causal nature… and what is it doing in the world?

Reluctantly, I admit that I have sometimes created getters, particularly in Groovy, which supports them syntactically, but immutable properties only need apply. In all cases, the class in question must mainly exist to do other useful things.

Instead of beans, if you want a collection of data, use a Collection. Pure mindless beans are not object-oriented; they existed in C too but we called them “structs.”

Stop Twiddling My Bits

Googling for how to compute checksums with Java might return insanity. Quick. What does this function do?

// Java
static String twiddleDee(byte[] data) {
  StringBuffer buf = new StringBuffer();
  for (int i = 0; i < data.length; i++) {
    int halfbyte = (data[i] >>> 4) & 0x0F;
    int two_halfs = 0;
    do {
      if ((0 <= halfbyte) && (halfbyte <= 9))
        buf.append((char) ('0' + halfbyte));
      else
        buf.append((char) ('a' + (halfbyte - 10)));
      halfbyte = data[i] & 0x0F;
    } while (two_halfs++ < 1);
  }
  return buf.toString();
}

Compute a SHA-1 and output a hex string. This is my first public service code donation:

// Java
public static String sha1(byte[] itsAllBitsAfterAll) {
  MessageDigest digester = newSha1Digester();
  digester.update(itsAllBitsAfterAll);
  return bytesAsHex(digester.digest());
}

// This might make a good future post about senseless
// factories
private static MessageDigest newSha1Digester() {
  try {
    return MessageDigest.getInstance("SHA-1");
  } catch (NoSuchAlgorithmException e) {
    throw new RuntimeException(
        "How many times must exceptions be thrown?", e);
  }
}

static String bytesAsHex(byte[] bytes) {
  Formatter result = new Formatter();
  for (byte nextByte : bytes) {
    result.format("%02x", nextByte);
  }
  return result.toString();
}

Like the countless optical illusions where the lines turn out to really be straight or the colors are actually the same, the first snippet matches the “bytesAsHex” method. The first is twenty times faster, but the second is twenty times clearer.

Always write the second. If you really need to squeeze those few extra milliseconds out of your code, use a library. If you think you can improve the library, use something open source, write it better, benchmark, and contribute.

Update, seven years later: In the intervening time, I’ve become somewhat more comfortable with bitwise operations and much more wary of dependencies. Today, I would not include a library only to optimize a little bit of string formatting.