Contextual Readability

What about readability? It's fine and dandy to subvert a language when you're the only one who will be looking at the code, but which of the following lines will the average Java programmer comprehend faster?

if (L.l(FIRST, THIRD).contains(theOne)) doSomething();

if (FIRST.equals(theOne) || THIRD.equals(theOne)) doSomething();
-- EricHodges

Readability requires an understanding of context. In modern ides, it is trivial to look up the definition of the method, and the regular structure makes it immediately obvious to every maintenance programmer I've worked with what the construct was intended for. If it is used once in a system, the overhead to understand it is too high. If it is a commonly used construct and part of a coherent style, it dramatically increases readability. -- JeffBay

But it's precisely because readability requires context that I object to this. I try my hardest to program it into the language I'm using. That means using the common idioms, naming conventions, coding styles, libraries, etc. Oftentimes I don't like what I have to use; it's a pale imitation of the same thing done right in some research lab. But I grin and bear it and write the code the best that I know how given the constraints of the language.

Provided whatever common idioms, styles, etc, have some redeeming value. In this case, we talk about a language not having support (i.e. good notation) for common data structures. not having is hardly a value.

I figure that if I'm stuck using a language, it's for a reason. Often that reason is not technological. But that doesn't make it invalid. I use Java at work because that's what everyone else uses; the cost of building libraries we would otherwise be able to buy, interfacing everything together, and retraining the programmers would be way more than the productivity benefits of switching to a better language. I use PHP in my non-profit, where I got to "choose" the language, because we could find PHP programmers but not Lisp programmers, and our forum software is all in PHP anyway. I could easily Greenspun a Scheme (or use Kawa ;)) for either of these, but that would defeat the whole point of using those languages in the first place.

The fact that you are stuck with a language, does not mean that you are also stuck with its shortcomings as long as you can do something about it. It's not an either/or proposition. You can use the libraries, the runtime, the HotSpot compiler and whatever is good in Java, but you can also have a convenient notation for lists.

If you want varargs and terse naming conventions, why not use Perl? Then you don't have to convince all the "more senior programmers" that this is a superior convention, and you don't have to familiarize incoming team members, and you don't have to write all these utility frameworks. You've got a huge existing community to draw on, and you're not fighting the language. -- JonathanTang But I do have to cope with all that ugliness in perpetuity. -- JeffBay

In point of fact, the Java language designers apparently agree with our desire for varargs, since they are included in the Tiger release (JDK 1.5). -- JeffBay

I don't use perl anymore (though I used to be quite good at it, as some of my other writings in this forum (I hope) show). The reason I use Java is because I like type safety. This refactoring is merely a refactoring of existing duplication, and specious arguments about "go use Perl" do not add to the discussion. By the "senior programmers" I really meant exactly the people (regardless of experience, actually) that have the attitude you are expressing. I'm not fighting the language - I'm *abstracting* within the context of a language in order to make my job easier. Your argument is headed straight down a slippery slope to "don't refactor because if you put all the code in line, it's easier to understand. That's great *once* but doesn't aid in the long run. -- JeffBay


You are drawing the wrong comparison. Imagine that the programmer would need to construct a list with the objects ONE, TWO, THREE in order to pass it somewhere. He could use array, and many people use array for interface purposes, but arrays are not collections, and even array are more verbose. Anyways, many APIs out there do not use array, but use collection and incidentally not even the ArrayList constructor accepts an array of objects. So the alternatives you are looking for are:

 1) framework.call( L._(ONE, TWO, THREE ));

2) List list = new LinkedList(); list.add(ONE); list.add(TWO); list.add(THREE); framework.call(list)

3) framework.call( new Object[] {ONE, TWO, THREE})
With the caveat for number three that many frameworks are designed to use collections but not arrays (including Java's very own collections framework), and another caveat that if the framework writer offers you the API to pass in the list as an array, he will probably have to write code to copy the objects from the array into a proper collection. It should be obvious that 1) is preferable to 2) and slightly better than 3) while 3) is not always applicable. -- CostinCozianu

Do you really think 2 will be easier to read than 3? -- EH

No, I said 1) is slightly better than 3 because of minor technical issues, including the fact that a collection is a more powerful object than an array. Unless the receiver simply wants to do a loop over the array, he'll probably need to copy an array into a collection of its own. And as I said, 3) is often just not available - for example, you can construct a set as:

 Set x= new TreeSet?(L._(x1, x2, x3, x4));
but you cannot construct it as
 new TreeSet?(new Object[] {x1,x2,x3,x4});
because the API just isn't there. The closest you can get is:
 Set x= new TreeSet?(Arrays.aslist(new Object[] {x1, x2, x3, x4}));
-- Anon

Sorry, I meant to ask if you really thought 1 was easier to read than 2 or 3. -- EH

FWIW, I think not, but what if it was framework.call(ListUtils.makeList(ONE, TWO, THREE));? -- JonathanTang

See TheSclass for a brief explanation of why I chose to keep the name exceedingly small. The gain from creating this class lies primarily in removing the clutter of "ListUtils?.makeList(...)" or "Arrays.asList(new Object[] { })". Both emphasize the construction of the list rather than the elements of the list, which is the primary gain of this class. By keeping the name trivially short, the reader is left to concentrate on the elements of the list. -- JeffBay

But by keeping the name inscrutably short, the reader is expected to know what L.l() means. "ListUtils?.makeList()" may look like clutter to you, but it gives the reader a good idea of what it does. -- EH

Given the constraints of brevity, why not L.ist then? It won't make you pause to decipher it, it doesn't require reaching for the shift key (a pet peeve of mine, and one reason I prefer identifiers-like-this to IdentifiersLikeThis or identifiers_like_this), and IntelliSense will complete it in the same number of keystrokes as L.l. -- JonathanTang

Now that is a *great* idea. I really like the L.ist() idea, but I'm too lazy at the moment to implement and test it for the wiki. Thanks for the suggestion! -- JeffBay

There's also been static imports and varargs in Java for a while now. -- PeteKirkham


EditText of this page (last edited September 15, 2005) or FindPage with title or text search