Wednesday, August 29, 2007

NASA, Java, and Defending The Title

Like many CtJ readers, I'm a big fan of Wired magazine.

People have noticed lately that Wired has a major interest in (a) the private sector space race and (b) railing against NASA.

Consider these stories:

That's a small sample. The overall theme, for years, is that NASA is a bloated, incompetent bureaucracy and that the small private entrepreneurs are much more agile and effective.

I don't know a lot about engineering, and I don't really want to get into politics (public versus private sector). I just see parallels.... especially with this retort in Aug 07's Letters to the Editor (by George C. Mantis):
... you [Wired] dismiss government space programs. Yet those supposedly inept, wasteful programs have orbited humans around the Earth countless times, erected and maintained numerous crewed space stations, and traveled to the surface of the moon and back seven times. Elon Musk... has achieved two failures in two launch attempts... at the cost of $100 million.
Game on! In the one corner, we have the maverick upstart ventures: lean and mean, agile, and ready to change the world. In the other corner, we have an entity, though bloated, that has the title of Heavyweight Champion: it may be a lumbering giant, but its career achievement is formidable.

Wait a minute. Lean versus Bloated. Nimble versus Plodding. Hmmmmm....

So if we had, say, Erlang, Ruby/Rails, and Haskell in one corner and then Java/EE in the other.... then perhaps some would argue that the upstarts can circumvent the red tape of bureaucracy, and others would point to the fantastic legacy of the Champion (and its honed one two punch combination).

Fascinating. Let's order pizza and we'll watch both title bouts....

ps. Naturally, some might argue that there is in fact another Heavyweight Champion of the World.

Monday, August 27, 2007

The Essence Of Improv

I once took a 10-week class in improv theatre, from a true virtuoso, Ed Reggi.

It was quite a departure for me, and one of those classes that had an impact far beyond the duration and cost of the class. Now, it seems like it was 4 months of fun.

Here's some things I learned about improv, as they relate to programming and IT.

It's Ok To Fail: Just Fail Fast

The whole point of improvisation is to act on the fly, on the edge of failure. If you don't fail once in a while, then something isn't right.

In fact, there are games that improv performers play before practicing/learning that are intended to promote failure. Once you screw up, you're less likely to worry about it later. One game is "swish-bonk", where a group stands in a circle: someone shouts "swish" with an arm movement to the right. The recipient can swish to the right or "bonk" it back to the left. Variations, hijinx, and failure ensue.

Later, in an actual improv setting, a failed idea is ok: performers don't dwell on it. They keep things moving with a new idea.

This is reminiscent of two things:

  • The entrepreneurial spirit of IT, where failed ventures can be a badge of honour
  • The XP approach to design software, where we "embrace change". That is, we don't expect ideas to be correct, but we do want to correct them ASAP.
It Takes Two

The essence of improv is 2 or more performers on a stage. No props. Just a sense of location and occupation, then: go. (e.g. A doctor and a lawyer wait for a bus.)

But there has to be at least 2 people. Yes, Robin Williams is fantastic on his own, but real improv, from what I can tell, is like dancing: it works best with two people, and gets more complicated with more.

Just like pair programming. The doubling factor of creativity and focus is the magic. Is it any wonder that the best music composers of the 20th century were a pair of complementary song-writers?

Yes, And...

The golden rule in improv is that one never says no. If you and I are waiting for a bus, and you say "hey did you break your leg?", the only legitimate reply is "yes, and....".

"No" is cheating. One has to go with it and riff from it.

This is a stretch for IT, but I once met a pleasant, effective sys admin, who told me that his policy for admin requests was:

My default answer is 'yes', unless there is a reason against doing it. Too many people have a default answer of 'no'.

That's something to consider for all corporate interactions, I suspect.

Watch A Virtuoso

Reggi, the instructor, never really did a full performance for the class. But he would do these 10-15 second riffs that had the essence of what he wanted to convey. For example, to illustrate some point, he would say "oh I don't know", pause, and then pretend he was in a supermarket and the lights go out.

And, it was magic. For that brief flash of time, he was in a supermarket and the lights did go out.

It was like watching a virtuoso guitar player dash off a fast, melodic lick that seems impossible.

We all need to find the code virtuosos and pay attention. There's a lot to learn.

Yes, and..... standup meetings are a lot more fun.

Sunday, August 26, 2007

lasreveR gnirtS

It's not hard to determine the output from the little Groovy Puzzler. (Spoiler ahead).

It reverses a string. Since the post, I've wondered about this little refinement:

Write a terse Groovy program that reverses a string. How terse can you go?

For Groovy experts, this is pretty easy. As I've poked at this (as an intermediate), here's what I've found out along the way (starting with the Puzzler above).

Evaluate() is Powerful

No surprise here. The ability to execute data can be tremendously useful. Check this out:


i=args[0].length()
evaluate('print args[0][i---1];'*i)

This program checks in at 55 characters. The key is the '*' operator which generates a string. For example, 'abc' * 3 = 'abcabcabc'. This generates a sequence of print statements, which is executed by evaluate. Note that evaluate has a sense of context (e.g. the variable 'i').

Another way to see what is happening:
evaluate:
print args[0][ (i--) - 1 ]; // print args[0][N-1]
print args[0][ (i--) - 1 ]; // print args[0][N-2]
print args[0][ (i--) - 1 ]; // print args[0][N-3]
... etc

'Tis hardly efficient but my favourite of these programs.

Home on the Range

Python has fantastic flexibility in indexing arrays. As it turns out, Groovy does too, with ranges. Surely there is way to exploit this to tighten the terse factor:

println args[0][args[0].length()-1..0]

That's a trim 39 characters. We just let the reverse range iterate over the string.

KISS rocks

Many of you knew this all along: keep it simple. If you check out the list of methods that Groovy adds to the JDK (see it here), then things get much easier. And, I think, optimally terse!

println args[0].reverse()

That's 26 characters and just one calorie.

The Upshot

The upshot isn't to strive for terse programs. The point is that the "what if?" questions can be a cool way to learn about a language's capabilities.

Friday, August 24, 2007

Groovy Puzzler: Ping Pong

I'm borrowing a "Friday puzzler" theme from Weiqi Gao.

This puzzler is in my "language of the week": Groovy. It didn't make my list in the thought experiment Seven Wonders, but it is a charming language, especially for Java developers.

What's the output from this program? Assume an argument is passed on the commandline.


i = args[0].length()
bonk = 'println args[0][i---1]'
ping = { if( i ) { evaluate(bonk); pong.call(); } }
pong = { if( i ) { evaluate(bonk); ping.call(); } }
ping.call()

Watching Swing Do Its Thing

My father has an old, dense textbook on electricity and magnetism. He once told me with a sense of wonder, "if a person knew everything in this book....." -- with an implicit "s/he would be off the charts".

I feel the same way about this Swing book. It's chock-full of ideas.

Here's one tip to slow down Swing's painting operations so that rendering of a component can be observed. It's a great debugging tool and also somewhat hypnotic.

I'll use a previous Groovy example, but the code translates directly to Java. The key lines are:

// from Swing by Robinson and Vorobiev
// It is vital to disable double buffering
// There are also options involving logging and buffering

RepaintManager.currentManager(frame).setDoubleBufferingEnabled(false);
table.setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION);
DebugGraphics.setFlashTime(100);
DebugGraphics.setFlashCount(5);
DebugGraphics.setFlashColor(new Color(0,0,0,0));

In my experience, it is useful to wrap this in a utility class, where one can simply pass a component and let the class use some default values for the flash time and colour. Then, for debugging, this is always at hand. Naturally, don't call this in production code.

Here's the example. This one uses straight-ahead Swing and not the SwingBuilder from Groovy. Also, it doesn't display bogus entries in red (see previous post).

import java.awt.*
import javax.swing.*
import javax.swing.table.*

String envVar = System.getenv(args[0])
final String DELIMITER = ';' // use File path separator

// build data

String[] columns = [ args[0] ]

String[] values = envVar.split( DELIMITER )
Object[][] data = new String[values.length]

for( i in 0..values.length-1 ) {
String[] row = new String[1]
row[0] = values[i]
data[i] = row
}

// build GUI

frame = new JFrame()
frame.setTitle('Env Viewer (by Code to Joy)')
frame.setSize(520,500)
frame.setLayout( new BorderLayout() )

jPanel = new JPanel();
jPanel.setLayout( new BorderLayout() );

JTable table = new JTable(data, columns);
JScrollPane scrollPane = new JScrollPane(table);

jPanel.add(scrollPane, BorderLayout.NORTH);

frame.add( jPanel , BorderLayout.SOUTH );

// from Swing by Robinson and Vorobiev
// It is vital to disable double buffering
// There are also options involving logging and buffering

RepaintManager.currentManager(frame).setDoubleBufferingEnabled(false);
table.setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION);
DebugGraphics.setFlashTime(100);
DebugGraphics.setFlashCount(5);
DebugGraphics.setFlashColor(new Color(0,0,0,0));

frame.pack()
frame.setVisible(true)


Thursday, August 23, 2007

Groovy SwingBuilder and Secret Methods

Last night, I mocked up a little Groovy example that split an environment variable (e.g. PATH) and displayed each entry. This is a modest experiment to mitigate Microsoft's dreaded, 1970-vintage line editor for modifying environment variables. (I had done something similar in Python years ago, and the topic has come up recently. More on this to come).




I used straight-ahead, quick-n-dirty Swing, and then decided to reduce the code by using a SwingBuilder.

As usual, most of it went fine, except when it came to simply performing something like this:


jPanel.add( scrollPane );

On a couple of projects now, I have spent considerable energy trying to figure out how to do this.

Widget To The Rescue

The answer may be in the GINA book but on the web, the only morsel of help that I could find is an article from 2004. (thank you!)

The answer is the secret widget method! See the code listing below for an example on how to use it.

As an aside, I find it useful to display non-existent PATH entries in red (see screenshot).

import java.awt.*
import javax.swing.*
import javax.swing.table.*
import groovy.swing.SwingBuilder

class MyTableCellRenderer extends JLabel
implements TableCellRenderer {
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int rowIndex, int vColIndex) {

setText(value.toString())

File file = new File(value)

if( !file.exists() ) { setForeground(Color.red) }

return this
}
}

///////////////////////////////////////////////////////////////
// static public void main(String[] args)
//
// args[0] = env var to view

final String DELIMITER = ';' // change this for Unix

String envVar = System.getenv(args[0])

// Build data

String[] columns = [ args[0] ]

String[] values = envVar.split(DELIMITER)
Object[][] data = new String[values.length]

for( i in 0..values.length-1 ) {
String[] row = new String[1]
row[0] = values[i]
data[i] = row
}

// Build GUI. Note that this is quick-n-dirty stuff,
// that illustrates a SwingBuilder more than proper
// Swing techniques.

builder = new SwingBuilder()

JTable table = new JTable(data, columns)
def renderer = new MyTableCellRenderer()
table.columnModel.getColumn(0).setCellRenderer(renderer)
JScrollPane scrollPane = new JScrollPane(table)

gui = builder.frame( title:'Code to Joy',
size:[520,500] ) {
panel( layout: new BorderLayout(),
constraints: BorderLayout.NORTH ) {
widget(scrollPane) // THIS is a revelation
}
}

gui.show()

Monday, August 20, 2007

Contest: Opine On Closures In One Sentence

The first Sticker Contest on POJOs was fun: with the success of the last post, it's time for Sticker Contest #2!

The gist: the ladies stated their case in the nightclubs. Now it's your turn.

Write a single sentence that states the case for (or even against) closures in Java 7. Send your entry to "codetojoy" @t (gmail).

Be earnest. Or creative. Or funny.... The choice is yours, but be brief.

The contest will end August 31. Winners (see rules) will get a free sticker (either "Code to Joy" or "+1 For Closures") and CodeToJoy pays postage.

ps. Here are some more contest rules. (Though note that most likely more than one person from a given country can win.)

pps. If you have written a closure proposal or contributed to the debate with a major article (e.g. Neal Gafter, James Gosling, Brian Goetz, and others), then you're a Diamond Member! Membership has privileges: a free sticker. Just let me know if you're interested.