Monday, November 26, 2007

My New Favourite Analogy: Design Like Water


I am a big fan of analogies and metaphors. When I think of a good (or funny) one, it is often the very definition of a good day.

Well, I discovered a doozie. Influenced by positive reviews from several corners, I have been reading a bit of the book Getting Things Done. Though only mentioned in passing at the beginning, GTD mentions a beautiful idea.


Mind Like Water

The book describes an image from Karate: Mind Like Water. The idea is that, in Karate, a state of perfect readiness is having a "mind like water". Water (e.g. a lake) responds perfectly to a disruption; that is:

Water reacts appropriately and then returns to a calm state.

If one throws a pebble into a pond, there's a ripple, then calm. If one lobs a boulder, then there's a huge splash, then calm. The reaction fits perfectly, and the disruption is dismissed.

Design Like Water

For me, that is a beautiful analogy for all kinds of things in computer science. This is all very subjective, and hard to quantify, but consider this:

Shouldn't a software system (e.g. web application) be designed like water? i.e. A small number of requests should be a pebble; perhaps a Superbowl TV ad spawns a massive boulder. But in all cases, it should react appropriately and then return to a calm state.

Some real world examples include the Big Databases and the massive e-commerce sites. One doesn't hear of eBay or Amazon "being rebooted". They're designed like water.

What about computer languages? Though hopelessly whimsical, it strikes me as beautiful: a language should barely react to small things. It is allowed to require a big splash for big things, but ultimately it should shrug off the disturbance and provide calmness.

Specifying examples for languages is much more difficult, because the idea is so abstract. Long time readers will predict, correctly, that I'll offer Python as an example. It's a big pond of OO, functional capability, and brevity that seems to react appropriately to both pebbles and boulders.

What do you think? Do you buy the metaphor? If so, which languages resonate for you in this philosophy? Does Java or C# ?

Wednesday, November 21, 2007

Ctrl-Space Invaders

Ctrl-Space Invaders: The scenario where a user of Idea will use Ctrl-Space to view a list of available methods on an object, and search by pressing keys for the first letter of the method, with a fervor that is reminiscent of an early 1980s arcade game. Coined by a teammate.

Hey, can you tell me how to send a holiday greeting with a List? I've been playing Ctrl-Space Invaders for 10 minutes and don't see it.


Tuesday, November 20, 2007

Ambient Info: Hear Your Build

In a previous post, someone commented that wacky comments brighten one's day.

True that. So, too, does Ant's sound task. On past projects, we used it to denote a failed or successful build. We used:

Not only was it fun (as James Brown sang throughout various cubes) but it was a great way to subconsciously know the state of the build. This is a small example of ambient information. (For a far cooler example, check out this device built by Kohsuke Kawaguchi).

Does your project use the Ant sound task? What sounds does your team use?

Here are some ideas.....

For Success
More fun (or painful) are ideas for Failure:
Add your own ideas in the comments!

Thursday, November 15, 2007

My Grails Aha Moment

Recently, I attended a training class led by Gruru Jeff Brown. (A Gruru is a Guru in Groovy & Grails, esp. if one is a committer)

I have some experience with Groovy and plenty experience with webapps, but none with Grails, nor with Ruby on Rails.

Here's a few neat tidbits that I discovered:

  • In terms of configuration, Grails has no XML and the only properties files are i18n messages. Almost everything else is Groovy. I am familiar with 'convention over configuration', but I didn't know the configuration was so fluid and dynamic.
  • Many of the language features of Groovy become perfectly obvious in the context of Grails. The big one, for me, was named parameters. As a Groovy language feature, I was neutral on it; in the DSL setting of a web application, the feature is vital. Similarly for closures and other constructions.
  • Also, the MOP (Meta-Object Protocol) becomes extremely important. However, it is so sublime that it is hard to "see". That is, the Groovy code looks so lucid that it is easy to gloss over the machinations behind the scenes.
The Moment

In Grails, we created a test application, and created a domain class.

Subsequently, we created an MVC controller for our app. At this point, we had a barebones app that could be launched and viewed.

Cool beans. However, the turning point for me was that Jeff said we could generate a controller: that is, Grails would generate the full code and then we could tweak it. Without a hint of irony or coyness, he warned us that it would generate a lot of source-code.

Being from the Java world, I braced myself for the output. Surely it would be verbose, impenetrable, and a rats nest in terms of formatting.

Surprise: the generated Groovy was gorgeous. Due to the brevity and style of the language, the generated code was 2 screens long -- without doc. And I was able to grok it and start tweaking it immediately.

At first, I just started changing some code. But then I realized that I was working with generated code. That was the profound moment. I understood.

Below, I've provided the generated code for a Gambler controller (think of a casino app) on my local machine. Give it a glance.... As a hint, the controller contains several methods which are actions (in MVC parlance) on either a target Gambler object or a list of Gambler objects.

Note that I'm not asking if you can understand it cold. I'm asking "do you think you could understand it, if warm?". Remember... this is generated.

Personally, I think it is stunning.

Final Score: Grails 1 My Old Biases 0. Check out Grails here.

class GamblerController {

def index = { redirect(action:list,params:params) }

// the delete, save and update actions only accept POST requests
def allowedMethods = [delete:'POST', save:'POST', update:'POST']

def list = {
if(!params.max) params.max = 10
[ gamblerList: Gambler.list( params ) ]
}

def show = {
[ gambler : Gambler.get( params.id ) ]
}

def delete = {
def gambler = Gambler.get( params.id )
if(gambler) {
gambler.delete()
flash.message = "Gambler ${params.id} deleted"
redirect(action:list)
}
else {
flash.message = "Gambler not found with id ${params.id}"
redirect(action:list)
}
}

def edit = {
def gambler = Gambler.get( params.id )

if(!gambler) {
flash.message = "Gambler not found with id ${params.id}"
redirect(action:list)
}
else {
return [ gambler : gambler ]
}
}

def update = {
def gambler = Gambler.get( params.id )
if(gambler) {
gambler.properties = params
if(!gambler.hasErrors() && gambler.save()) {
flash.message = "Gambler ${params.id} updated"
redirect(action:show,id:gambler.id)
}
else {
render(view:'edit',model:[gambler:gambler])
}
}
else {
flash.message = "Gambler not found with id ${params.id}"
redirect(action:edit,id:params.id)
}
}

def create = {
def gambler = new Gambler()
gambler.properties = params
return ['gambler':gambler]
}

def save = {
def gambler = new Gambler(params)
if(!gambler.hasErrors() && gambler.save()) {
flash.message = "Gambler ${gambler.id} created"
redirect(action:show,id:gambler.id)
}
else {
render(view:'create',model:[gambler:gambler])
}
}
}

Android, GWT, and Lingua Java

One can almost feel the Blogtomonous Collective try and wrap their minds around the Android SDK. Between the Mensa puzzle of the legal-speak and creative lure of the prize money, there is a lot to contemplate.

Looking back a week or so, there are some weird psychic fingerprints that led up to the announcement.

  • At the St Louis JUG, Andrew Prunicki presented a cool talk on the Javelin Stamp. This is a microcontroller that uses a Java-like syntax which compiles onto a JVM (of sorts). The VM doesn't have garbage collection. My theory is that it can't be licensed as true Java and so that the company chose the wonderfully clever name Javelin.
  • Eric "Photoshop till You Drop" Burke posted satire: Android shuns Java. The joke being, of course, that there is no way Android could shun Java: such a prediction would be as ill-fated as "Dewey defeats Truman". But Android does shun the JVM!
I think we are seeing an interesting dichotomy:
  • On one hand, JVM Tunneling implies that the JVM is The Thing. Scala, JRuby, Groovy, and others all run on the JVM. Java is being marginalized as merely one syntactic "view" of the virtual machine. It's not even the coolest view going these days.
  • On the other hand, Javelin Stamp, Android and the Google Web Toolkit make the case that the Java syntax is The Thing. It certainly looks like Google believes it is the Lingua franca of our time. Who cares what transformations take place, as long as we have the apple pie of "public class MyClass {}" !
Call it Lingua Java.

This just in: we are in interesting times.

Tuesday, November 13, 2007

Trivial Pursuit: Unit-Testing Getters and Setters

While I was in Vegas, Eric, Alex, and Brian posted some ideas on unit testing trivial code.

The question: should we unit-test everything? The hive-mind currently says: yes.

E.g. Relevance recently posted a job offer that mentions 100% code coverage. At a recent NFJS, Stuart Halloway made the point that code coverage is one of the few things where one has to be extreme: 80% doesn't work; it has to be 100%. (Relevance is adamant on this point.)

Fine, so the answer is yes. But how do we remove the tedium of writing that testing code?

  • Modern IDEs generate code for getters/setters. They should do the same thing for generating unit-tests for this code. I haven't seen this: perhaps they already do? I've looked in Idea 6 and didn't see anything obvious.
  • It seems possible to write an abstract base class for unit-tests that uses reflection to auto-test common getters/setters. Is there such a tool out there?
  • Interestingly, we are seeing the impact of this issue in language development. Groovy will auto-generate getters and setters for a class member if they aren't provided. Not only is there less code to read, but also there is less code to test.
Post a comment if you know of a neat method to facilitate this testing...

ps. Here is a post from last winter on my experiences with unit-testing: in particular, TDD. It was a true growth experience for me.

pps. Here is the obligatory acknowledgement that getters/setters should not be automatically provided without just cause!

Thursday, November 8, 2007

The Name Game: Improve on Map for Java 7

What's in a name? that which we call a map
By any other name would associate as sweet;
-- with apologies to The Bard

Kevin Bourrillion has posted a joint proposal for minor additions to some core APIs in Java 7.

This is pretty cool stuff:
  • The proposal itself smacks of being agile: it's small in length and in scope.
  • The changes address some corner cases in the vein of Java Puzzlers, and fill some inconsistencies in various APIs.
The most interesting proposal, IMHO, is #7. The idea is to have a new Map interface that is fleshed out with new methods (those from ConcurrentMap) and have all Map implementations use that new interface.

Of course, we need a name for this new interface. The doc has this line:

not likely to happen, due mostly to lack of tolerable name

Like many thoughtful developers, my reaction is:

  • No doubt, names are important, and vitally so for a core API.
  • Can I come up with a better name?
  • Can I come up with an absurd name? (Delightfully, they offer MapDaddy)
  • Why can't I stop thinking about this?
I could write an entire post about the importance of names and how much fun/challenging it can be to find just the right name.

What would you name a new Map interface? Here are some of mine
  • Dictionary. Has a classic appeal to it, but is already used (and deprecated) in the JDK.
  • Lookup. Another classic but somehow it doesn't seem strong enough. It seems like we should have a derivative of 'Map'.
  • Map7. The doc cites this as a bad name but it makes my shortlist, for some reason.
  • ReplaceMap. Probably too cute, the idea here is (a) the new methods involve replacement and (b) we are replacing the Map interface. At this point, one starts to realize how hard this task is. I can understand the reluctance expressed in the doc.
and some more yet:
  • iMap. That will get Apple's attention.
  • NüMap. Java has great support for Unicode, so let's go Euro. Plus we could sell lots of Java 7 schwag to heavy metal fans and feed the proceeds back into the Open JDK.
  • Map#. We need to grab mindshare from from the .NET crowd before F# takes off.
  • MapQuest or GoogleMap. Now, we're on to something: Java could be the first language to embrace corporate sponsorship in its core libraries. Call Nike and CocaCola immediately! (though they will probably want to brand the String class)
Your turn. What do you think?