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.

Sunday, August 19, 2007

Defining Language Aesthetic

I saw a presentation recently that showcased several 'scripting' languages such as Python, Ruby, JavaFX, Perl, etc.

Someone raised the point about how to evaluate a given language. That is: is it possible to state one's criteria for an 'appealing' or 'successful' language? Certainly such a statement would be subjective and true hair-splitting: many languages are subtle shades of the same colour on the language spectrum.

Still, it's an interesting question.... One person suggested that their criteria might be stated as: can a developer read a demo program in the given language and have a reasonable chance of understanding what it does? That's a fair question, IMO.

To paraphrase Guido Van Rossum (of Python fame), another aesthetic might be stated like so: what would it be like to maintain someone else's code in this language? I won't name any, but many languages fail this test for me. I'm talking here of the "average case" -- not bad, obfuscated code by a poor programmer.

I think the latter gets close to my sense of aesthetic. But also, more vaguely, a sense for "does the language help me do what I want to do, transparently, and then stay out of my way?". That's tough to quantify.

It's an interesting thing to consider... your thoughts?

Saturday, August 11, 2007

GDBC: easy queries with Groovy

I have blogged before about peeking at an OODB with Groovy. It was first "wow" factor with the language.

Here's an easy illustration of using Groovy and JDBC. Though my team uses a full-strength DB query tool, I find it useful to have a minimalist program to either (a) ping the DB or (b) perform a sanity check query.


// Be sure that the driver jar is in the classpath
// note the cool closure!

import groovy.sql.Sql

sql = Sql.newInstance("jdbc:oracle:thin:@machine:1521:THE_DB",
"user","pwd", "oracle.jdbc.driver.OracleDriver")

sql.eachRow("select * from a_table") {
row -> println "value = " + row.a_column
}


Final score: Groovy 1 Uncertainty 0

A Small World

I saw a blurb in Dr Dobb's Journal about SweetScape Software, based in my home in eastern Canada.

I can't resist a plug. In full disclosure, I have an undergraduate degree in mathematics from the school where a founder is a faculty member. No other affiliation.

I haven't used their software, but if you need a binary/hex editor, you may want to check it out....

Thursday, August 9, 2007

Ghost Stories for Geeks

In the dead of night, the moon is suddenly obscured by the clouds. A wolf howls in the distance. In the dim flicker of the campfire, a speaker leans in closer to the group. These developers have heard some of the stories before, but nonetheless they are wide-eyed and transfixed.....

The nefarious cracker was a vampire! He snuck up on the unwitting server using an SQL injection attack and sunk a stored procedure into its neck. Then he drank the data out of the database! But his thirst for info could never be quenched, and so he used the customer records to write a XSS exploit to eat all of their cookies and curse them to an unending hell of identity fraud!

Horrendous PR.... Financial ruin... Indictments!


(Kudos to Jay Mayer for a good talk at the St Louis JUG)

Tuesday, August 7, 2007

Herding Positive Deviants

Some phrases are simply too good to pass up, especially when they are asides.

From a management article on the effect of bad apples on teams (emphasis added):

Felps and Mitchell also found that negative behavior outweighs positive behavior -- that is, a "bad apple" can spoil the barrel but one or two good workers can't unspoil it. [snip]

The authors caution there's a difference between "bad apples" and employees who think outside the box and challenge the status quo. Since these "positive deviants" rock the boat, they may not always be appreciated. And, as Felps and Mitchell argue, unlike "bad apples," "positive deviants" actually help spark organizational innovation.
(Kudos to this post which introduced me to the article.)

Sunday, August 5, 2007

Unit Test Analogies

Alex Miller has a recent post about an interesting analogy for unit tests.

This weekend, I remembered this gem. I did not come up with this quote. I read it somewhere years ago... If anyone can credit the source, please do so (I tried a quick Google search but no luck).

Checking code into source-control without unit-tests is like betting on a poker hand without looking at the cards. -- Anon.

Wednesday, August 1, 2007

Hello World: A New Requirement

I am proud to say that this blog gets hits from all over the world. (Hello Finland, France, Brazil!)

These hits help me with the Big Picture, as does the calendar of Paris on my desk: it is a big world out there. Many people, many cultures, many languages.

Which led me to this thought: it bothers me that "Hello World" is always in English.

I think the venerable first program should always be internationalized, because:

  • It helps keep the Big Picture in mind. I18n is one of the universal issues of computing
  • In addition to showing language syntax, it shows the i18n features. "What do you mean the language doesn't have Unicode support?"
  • In an education environment, it teaches i18n to children from the start while reminding them that there's more than English. It also teaches issues of font, Unicode, etc.
Admittedly, the New Hello World is not minimalist any more and not necessarily pretty. But it would truly be able to say "hello!" to the world.

Here's a version in Groovy. It presumes that there is an i18nized labels.properties file in the current directory.

For example: labels_fr_ca.properties would contain

msg=Salut Monde!

Idea: why not leave "Hello World", in a different language, as a comment? Be sure to specify language, country, and variant codes as appropriate. (This is Java-centric: see here for details)

If you leave a comment, and email me at codetojoy through gmail, I'll send you a sticker!

The Groovy version:
// Requires labels_[Locale].properties
// with definition of key called 'msg'
//
// Locale = the various ways of specifying locale in Java
Locale locale

boolean hasLanguage = ( args.length >= 1 && args[0].length() > 0 )
boolean hasCountry = ( args.length >= 2 && args[1].length() > 0 )
boolean hasVariant = ( args.length >= 3 && args[2].length() > 0 )

if( hasLanguage && hasCountry && hasVariant ) {
locale = new Locale(args[0], args[1], args[2])
} else if ( hasLanguage && hasCountry ) {
locale = new Locale(args[0], args[1])
} else if ( hasLanguage ) {
locale = new Locale(args[0])
} else {
locale = Locale.getDefault()
}

ResourceBundle labels = ResourceBundle.getBundle("labels", locale)

println labels.getString("msg")