Saturday, October 22, 2005

Qt for Java

Aaron Seigo writes a good amount about the TrollTech developer's social in San Diego. The part that made my ears perk up:

haavard announced that by Q1-06 they'll be releasing a tech preview of java bindings for qt4 that will be officially supported. wow.

Wow indeed.

Friday, October 21, 2005

Jeff Biggler's Tack Filters

I heard about this gem of an article on the XP Yahoo! Groups list, Tact Filters. As any of my friends will point out, my native tact filter is applied to the incoming direction. Age has granted me an add-on tact filter for the outgoing direction, not as operative as the native filter but better than none.

Monday, October 17, 2005

Ruby in Eclipse

An interesting article from IBM on the Ruby extension for Eclipse, Using the Ruby Development Tools plug-in for Eclipse. The blurb:

This article introduces using the Ruby Development Tools (RDT) plug-in for Eclipse, which allows Eclipse to become a first-rate Ruby development environment. Ruby developers who want to learn how to use the rich infrastructure of the Eclipse community to support their language will benefit, as will Java™ developers who are interested in using Ruby.

Fortunately, the article is more than just a description and includes setup and all that. And what pretty screenshots!

Wednesday, October 12, 2005

Agile leadership

One of the things that draws me to agile programming styles is the agile approach to leadership.

Waterfall processes naturally fit within a top-down organization where leadership is a direct chain of control in the shape of a pyramid. The exemplar of waterfall leadership is a military organization.

Agile leadership follows from agile processes. It emphasizes change, collaboration and consultation. To adapt is more important than to plan; to listen is more important than to order; to trust is more important than to manage. The shape is that of a network.

But agile leadership is not the opposite of waterfall leadership. A good leader keeps both in mind and applies the best principle to the problem at hand.

For example, new junior programmers are often bewildered by the array of technical approaches available for a given problem. In an agile environment, pair the young Jedi with a senior developer who can share his craft and training.

However, there may not be a senior developer available. Lacking a suitable guide, it is better to task the apprentice with short, straight-forward steps—spell out a likely solution that the junior programmer can learn from as he codes, and provide supervision as requested.

Again, a problem arises: what sort of supervision? If possible, instill in the new peer that you trust him to follow simple instructions but that you are approachable for questions and suggestions. The goal is not to simply train the fingers to type good code, but also teach the mind good values. I believe those values to be agile ones; you may believe otherwise.

None of this is controversial, yet I encounter such mentoring more often with agile leadership than with waterfall leadership. Perhaps it is more a measure of where I worked than how I worked, but I prefer to believe the manifesto.

The big picture

Am I a details person? The impression of most people is that I am; this blog certainly is detail-oriented. But I would argue otherwise.

I approach most topics as scaling problems. If you are talking about atoms, the appropriate level of detail is the atomic; if you are talking about aggregates, the appropriate level of detail is small but at the macro scale; if you are talking about galaxies, the appropriate level of detail is stars and dust.

On this blog, most entries are detail-oriented simply because small domains are easier to describe than large domains and the answers are more satisfactory and complete. (Even so, I often miss interesting points; I am grateful for comments.)

Contrast the small scale of algorithms where behaviors can in many cases be analyzed fully with the large scale of company-wide systems where behaviors are imprecise and many factors difficult to analyze come into play.

For a short blog entry written to a general audience, I would rather approach an algorithm as the level of detail. I believe it is more satisfying for the reader and less time-consuming for the author. For a white paper (such as this one I wrote while at EBS) I have more freedom in exposition to tackle a larger topic. Perhaps more opportunities will come for me to write about the bigger picture.

Arrays and Collections

Keith Devens makes a good point of recommending Arrays.asList(...) over hand-crafted lists. Thus he suggests that in place of:

List<Foo> foolist = new ArrayList<Foo>();
foolist.add(foo);
return foolist;

You instead use:

return Arrays.asList(foo);

This has much to recommend it, especially conciseness and clarity. However, as the hawker on late night TV says, But there's more!

In addition to the useful Arrays class of static helper methods, there is Collections which has more useful static helper methods. So the example could have also been written as:

return Collections.singletonList(foo);

What's the difference? This is an interesting question. There is no way to select between Arrays and Collections without further information.

If the requirement were to return an unmodifiable view, then the easy route is:

return Collections.singletonList(foo);

Which is an even more clear way to express the intention of the code than Arrays.toList—the singleton pattern is one of the first grokked by any programmer. What if the code fragment were part of this method?

/**
 * Returns a modifiable list of just the topmost foo.
 *
 * @return Modifiable list containing just the topmost foo
 */
public List<Foo> copyTopFooAsList() {
    return ???;
}

Now it is clear from the javadocs for Arrays.asList that this is not quite what we want:

Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) This method acts as bridge between array-based and collection-based APIs, in combination with Collection.toArray.

And clearly Collections.singletonList(T) is not right either—when is a proper singleton modifiable? And Collections.toArray is clearly useful, but not what we are looking for (it returns an array, not a list).

After some thought, the solution is not hard to find: look at the constructors for ArrayList, and at ArrayList(Collection) in particular. Although the javadocs do not explicitly say copies from the input, they do hint at that (and a quick peek at the source code confirms it is so):

Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.

So the solution becomes:

return new ArrayList(Collections.singleton(foo));

A handy one-liner to keep in the back pocket for future use.

Tuesday, October 11, 2005

Better GC in JDK6 (Mustang)

As noted in OSnews, IBM has a great article on GC in the Java VM entitled Java Urban Legends. One of the developments in the ever-improving JVM really caught my eye:

Escape analysis is an optimization that has been talked about for a long time, and it is finally here -- the current builds of Mustang (Java SE 6) can do escape analysis and convert heap allocation to stack allocation (or no allocation) where appropriate. The use of escape analysis to eliminate some allocations results in even faster average allocation times, reduced memory footprint, and fewer cache misses. Further, optimizing away some allocations reduces pressure on the garbage collector and allows collection to run less often.

Escape analysis can find opportunities for stack allocation even where it might not be practical to do so in the source code, even if the language provided the option, because whether a particular allocation gets optimized away is determined based on how the result of an object-returning method is actually used in a particular code path. The Point returned from getLocation() may not be suitable for stack allocation in all cases, but once the JVM inlines getLocation(), it is free to optimize each invocation separately, offering us the best of both worlds: optimal performance with less time spent making low-level, performance-tuning decisions.

The referenced code before optimization:

public double getDistanceFrom(Component other) {
    Point otherLocation = new Point(other.x, other.y);
    int deltaX = otherLocation.x - location.x;
    int deltaY = otherLocation.y - location.y;
    return Math.sqrt(deltaX*deltaX + deltaY*deltaY);
}

And after:

public double getDistanceFrom(Component other) {
    int tempX = other.x, tempY = other.y;
    int deltaX = tempX - location.x;
    int deltaY = tempY - location.y;
    return Math.sqrt(deltaX*deltaX + deltaY*deltaY);
}

A nice win for Sun's JVM, to be sure.

Thursday, October 06, 2005

Testing protected methods with JUnit 4

One of the pains of JUnit is testing protected methods. Public methods offer no impediment to testing, and private methods in well-designed classes can be ignored as implementation details called by the public methods. But protected methods are important for frameworks and central to the Template Method pattern; they need testing.

The most common ways to test protected methods that I've seen are to invoke the protected method with reflection, to use a private inner helper class which extends the class under test, and similarly to extend the class under test and change the access of the protected methods to public. All have their drawbacks.

Enter JUnit 4. No longer must test classes extend TestCase. Using annotations, the test framework finds and runs your test methods without inheritance, and static imports keep calls to assertTrue and friends looking clean and tidy.

Your test class itself can extend the class under test and access the protected methods without the need for reflection or a second, helper class. This is another blow struck for small, clean code thanks to JDK 5.

UPDATE: As Sam in the comments pointed out, one could just put the tests in the same package as the class under test. For silly reasons, I left this out of the list of workarounds.