Thursday, September 27, 2007

Sublime By Contract


Over and over again, I am amazed by the genius of separating the What from the How.

From the micro-level of interfaces to the grand schemes of protocols, the inherent beauty of The Contract is cool. For two reasons:

  • it clearly defines the expectations
  • the brilliant, creative solutions to Gettin' It Done





Example 1: The History of Couriers

The contract: get stuff from A to B, in X time units, for money. Classic.

From the Pony Express to banzai bicycle messengers, onward up to FedEx and UPS, each step of the courier business is an intriguing story. I don't know if there is a popular history of couriers but there should be. The pioneering spirit is abundant and the technology is outrageous. Fascinating.

Example 2: IP over Avian Carriers

It is a silly example but delights me now as much as it did when I first read about it, ages ago. Birds and nerds team up for some networking mojo.

Example 3: Inversion of Control

In the early days of Java, it was very neat to use Collection, List, and other interfaces because of the latitude of changing the implementation; e.g. one might go from a HashMap to a TreeMap, based on profiling. Swing and distributed computing use 'em all over.

For straight-up apps, though, it seemed like we never really changed the implementation, even with factories, but it was cool nonetheless. We could change them if we wanted to.

Then came the IoC containers and the interface had a resurgence: Version 2.0. Now, it's very easy to change out implementations. It's a great feeling to use a set of mock objects for daily unit tests and a full-blown DB implementation during nightly integration testing. More than just using a contract, it's the tactile sense of different implementations. A sense of change.

Example 4: Terracotta

I recently went through the Hello Terracotta exercise on Alex Miller's blog. Check it out.

Terracotta is the latest mind-altering idea I've come across. I'm not even sure that I understand the implications of what it does, just yet. It really makes one say 'wow' and 'huh?' at the same time.

I do understand that it is sublime by contract. Get this: it honours the semantics of the Java Memory Model, and yet in doing so, it dopes up your (designated) classes and JVM so that it can shuttle your data to a central service (this phenomenon is called Network Attached Memory). In the simple example, one's app/JVM can go up and down and yet work with 'persistent' objects.

The kicker is that your code doesn't need to know: there is some serious mojo under the hood, and yet the contract of the Java Memory Model still holds.

If the standard JVM is a bike courier, Terracotta is UPS. Your stuff still gets done, but more efficiently.

There are some ideas that wouldn't occur to me even if I were on a desert island for 100 years. One of them is separating -- in such a weird way -- the contract of Java memory semantics from the implementation.

That's sublime.

Wednesday, September 26, 2007

No Fluff Just Stuff Redux

I'm looking forward to this weekend: the fall edition of the Gateway Software Symposium (aka No Fluff Just Stuff).

As I blogged back in March, I really enjoy NFJS; this will be my 6th!

The list of speakers is top notch, as always. Two favorites are Ted Neward and Stuart Halloway. I'm looking forward to meeting Alex Miller and seeing my colleagues Jeff Brown, Mark Volkmann, and Tom Wheeler.

If there's interest, I'll try and blog on a day-by-day basis. The flow of ideas in these conferences are really great.

Hope to see you there!

Tuesday, September 25, 2007

Yo Classpath, It's Globbering Time !

This post isn't rocket science: it is mostly for my own reference, but you might find it useful.

I've written a small, easy Groovy script that scans a directory (recursively) and builds a CLASSPATH from scratch.

We'll call it a jar globber. This really appeals to me:

1. Sometimes, it's great to go 'minimalist' and start from scratch

2. setting the CLASSPATH is the first step to cool scripting with the 'JVM Tunnelers' such as Groovy

In this post, I'll show the Groovy script and then use it to glob jars in the Jini project, and write a tiny script as a demo.


Here's the Groovy version of Jar Globber:


// Usage:
// groovy jarGlobber [targetDir]
//
// e.g. groovy Which c:\YourProject\lib

// Closure: if file is a jar, emit string
myEmitter = { file ->
if( file.isFile() && file.canRead() ) {
fileName = file.getName();

if( fileName.indexOf(".jar") != -1 ) {
// easily changed for Unix
println "set CLASSPATH=%CLASSPATH%;" + file;
}
}
}

////////////////////////////////////////////////
// static void main(String args[])
//
// TODO 1: sanity check arguments
// TODO 2: add param for Windows versus Unix
def fileName
searchDir = args[0]

println "set CLASSPATH=."
new File(searchDir).eachFileRecurse(myEmitter)


Easy stuff, thanks to Groovy's ability to iterate over files. (Yes, you Bash hounds, there are easier ways to do it.) Using Jini's lib directory as the target, the output looks like this:


set CLASSPATH=.
set CLASSPATH=%CLASSPATH%;c:\jini2_1\lib\browser.jar
set CLASSPATH=%CLASSPATH%;c:\jini2_1\lib\checkconfigurationfile.jar
set CLASSPATH=%CLASSPATH%;c:\jini2_1\lib\checkser.jar
set CLASSPATH=%CLASSPATH%;c:\jini2_1\lib\classdep.jar
set CLASSPATH=%CLASSPATH%;c:\jini2_1\lib\classserver.jar

ETC

If I output this to a BAT file and execute it, I'm ready to roll.

Here's a screenshot of a Groovy shell session where I start scripting Jini objects and interacting with them. (Note: I have started the Jini service elsewhere.)



You can click on the screenshot but here's the gist:


def loc = new net.jini.core.Discovery.LookupLocator('jini://localhost')
def registrar = loc.getRegistrar()
println registrar


We shoot, we score! Dynamic Jini objects. So, now it is Game On (or Flame On?) for experimenting with Jini, since the CLASSPATH was clobbered....

The cool part is that there is nothing particular here about Jini. We're ready to roll with any given project. Try your project at work. It is truly amazing to start scripting Java classes.

Sunday, September 23, 2007

Zen Python: The Sound of One Record Appending

Recently, I tried to make a Python program ultra-terse, as a fun puzzle.

I re-discovered two things:

  • I love Python. I hadn't used it in years and yet I was "back in gear" within a few minutes.
  • Python just seems to work. It is like a substance that can be a solid or a liquid, depending on your requirements, and at the same time.
In particular, I found that Python V 2.5 has some pretty cool ways of handling empty maps, or 'dictionaries' (in the Python parlance). This is elegant stuff, and yet easy enough that you need not know Python.

Consider a problem where we want to organize participants in a triathlon: a person has a name, gender, and age. Age groups will be 20s, 30s, 40s, etc.

By using a lambda expression (think anonymous function), on a defaultdict method, we can specify the default behaviour of a dictionary when there is no entry for the key.

myEasyMap = collections.defaultdict (lambda:[])

In this case, myEasyMap will create an empty list and insert it, when a key is not found. For example:

myEasyMap = collections.defaultdict (lambda:[])
myEasyMap[30].append("John Smith")

The above example appends "John Smith" into the list of triathletes in the 30s, even though there were not yet any listed.

The really cool thing is that we can chain these default dictionaries:

myData = collections.defaultdict (lambda: collections.defaultdict (lambda:[]))

myData["M"][30].append("John Smith")
myData["F"][20].append("Barbara Doe")

Above, myData is a map that resolves to a map of lists. There are two outer keys ("M" and "F"); the inner keys are the age ranges.

Should we do this in production? Probably not. But it is gorgeous.

Below, we iterate over some records and organize athletes:

myData = collections.defaultdict (lambda: collections.defaultdict (lambda:[]))

records = []
records.append( { 'name': "John Smith", 'age': 35, 'gender': "M" } )
records.append( { 'name': "Axl Rose", 'age': 45, 'gender': "M" } )
records.append( { 'name': "Britney Doe", 'age': 25, 'gender': "F" } )

for record in records:
name = record['name']
age = record['age'] % 10
gender = record['gender']
myData[ gender ][ age ].append( name )

Neato with a capital 'O'.

Ruby has similar behaviour, which is not surprising (see Porsches and Ferraris) but I don't know many languages that can do this. (e.g. I don't know of a way to do it in Groovy. Do you, Groovy readers?)

Porsches and Ferraris

I once wrote about Alligators versus Crocodiles, which was a metaphor for the religious wars of syntax.

Recently, some colleagues have been experimenting with a number of programming languages. I hope to write more on this, but essentially it has renewed my interest in a variety of languages.

And, the discussion spawned another analogy.



The main thought is this: often, in CS or not, there are 2 camps
with rabid proponents. The debate between the two can get
quite heated. What gets lost in the shuffle is that both camps
are truly sublime, and that the rivalry and competition brings
parity, in terms of excellence.

Two examples outside of CS: Porsche versus Ferrari, and a
Fender Stratocaster versus a Gibson Les Paul.

I'm sure there are message boards all over the net, filled with
flames on all sides. I have my own preferences, and might even weigh into the debate, but another part of me asks: Are you kidding me? How can you knock any of these? At the same time, there are nano-level differences that polarize people.

The CS example (du jour) of 'Porsches versus Ferraris' is Python and Ruby. They have many, many similarities at the "forest level", even if the trees look different. And yet I don't know many (if anyone) who has one foot in each camp.




Thursday, September 20, 2007

The Art of Flame War: DoS Attack


Every night is Halloween on the Internet -- Anon

'Twas a dandy day for dueling posts about various technologies. Unfortunately, the flame war du jour is extraordinarily vacant: no insight, neither satire nor parody, and no bumper stickers :-O It's not even especially funny (though a recent parody post got a chuckle).

Website hits are the currency of the tech blogosphere, except there are no debits: only credits.

Counter flame-bait, posts of outrage, etc only offer up more hits and service the ego of the originator. There is no bad PR, as they say (especially if you have a book coming out).

From this corner: no links, no names, no outrage. Just a yawn of indifference.

Denial of (ego) service starts now, as I turn the page. Join me!

Sunday, September 16, 2007

Tycoons of Screen Real Estate

An Investigative Report
Exclusive to CodeToJoy
September 2007


CodeToJoy recently went on location to a local IT shop to investigate, in the words of one developer, an "arms race" of screen real estate.

All developers know the luxury and productivity gains of having two monitors. Some time ago, an enterprising developer supplemented standard-issue corporate equipment with a personal monitor. Not to be out done, teammates soon followed.

Before long, the 2 monitor barrier -- long considered a theoretical limit -- was broken. Said one coder, "Yeah, things kind of escalated".

Months later, we now document -- for the first time -- the culmination of this pixel parade, these Monitor Mansions.

Dear readers, here are The Tycoons of Screen Real Estate, and their design patterns. No photo editing has been used. These are real cubes with displays for a single computer.

The Letterbox



The Sports Bar