Tuesday, May 20, 2008

The Sound of Music: Podcast Themes

For a random sidebar...

What are some favourite podcast themes? No, not the content per se, but the catchy bumpers at the beginning and end of the casts.

Some thoughts on podcasts on my playlist:

  • I'm a guitar fan so the theme at Software Engineering is a winner, and the inspiration for this post. The music is punchy, upbeat, and they always seem to fade it in and out just right. By the way, this week's guest is Anders Hejlsberg.
  • I really like the end theme/outro for Java Posse. The retro synthesized voice is delightful. The famous opener is sufficiently catchy and irritating to burrow deep into your consciousness, which is really the point.
  • Man, the band phoned it in for CNet's Buzz Out Loud. The theme is musically bankrupt, and they barely let it play, which may be merciful. However, I'm always suckered in by Molly Wood's brisk whirl through the subtitle "podcasts of indeterminate length". Nice.
  • For the Google Developer Podcast, the immediate opening isn't for me: it's punchy but something is not quite there. But when the wah guitar kicks and the woman begins to sing, I'm completely on board. Great voice and a cool vibe. The fade in is very erratic in terms of length, but at least they give the tune lots of space as the outro.
Yours?

Monday, May 19, 2008

Fitness as a Competitive Advantage

Jeff Atwood blogged recently about cleaning the monitor and the keyboard.

Some quick thoughts:

  • A big +1 on not touching the monitor. I cringe every time anyone touches any monitor. It actually distracts me during code reviews.
  • Keyboard manufacturers should figure out a way that the electronics can be removed easily (like a cartridge) to enable dishwasher use.
  • Jeff mentions "my" keyboard: I guess he doesn't work in a public war-room. Believe me, that is a whole new, fascinating ballgame. More to come sometime.
  • I don't condone filth, but I'm not convinced the neat-freaks have it right, especially with those cleaners that clean 99.5% of bacteria. Hmmmm.... no training for the immune system and we leave The Nasties to party. Is that a good idea? (As an aside, check out this article on germ factories (aka children) and the beneficial effects on parents and pediatricians.)
On to the point: presumably, Jeff wants to clean his keyboard so that he doesn't get sick. However, that is only half of the equation.

It is well-documented that moderate exercise can boost the immune system. So one could argue that we owe it to our teams, our careers, and our families to get out there and work out.

Maybe you do so. Maybe you do more than me. But if not, I'm not talking about doing an Ironman (though a sprint triathlon is a fantastic accomplishment, and much easier). I'm suggesting a 30 minute session 3 times a week, where the heartrate is elevated. Don't go for a walk: that's ok, but if you want to fight germs, aim higher.

There are other benefits as well:
  • You know those "aha" moments in the shower? Well, athletes shower more often: more aha moments.
  • It's not quite as magical as the shower, but if you swim or run, it is a phenomenal way to work out problems, without trying. The whole subconscious/background cooking thing.
  • I hate the pseudo-verb "network" but if you find your niche, you'll meet all kinds of new people. Bonus.
  • I have friends/colleagues who train in mixed martial arts: that's gotta be a stress reliever.
I ain't preachin'. I ain' teachin'.

I'm just sayin'.... Something to consider.

For those who are active: what do you like to do?

Monday, May 12, 2008

Logical Fallacies Considered Harmful: You Should Learn New Languages

Gustavo Duarte recently posted an article about the folly of dabbling in new languages.

The post is an earnest one, and thought-provoking, but I realized this evening that it is a masterpiece of logical fallacy.

Problem #1: Begging the Question

Gustavo argues that "dabbling" in new languages gives superficial results to your career. To dabble is to "work at something in a superficial manner". So, the argument is that a superficial investment in something yields superficial results. Hmmm... this seems like begging the question to me.

Note that I don't mean the popular usage of "that begs the question: yada yada" but rather the classical sense of proving something that is implicit in the premise.

Problem #2: The Strawman Argument

Gustovo condemns the Pragmatic Programmers' advice to "learn a new language every year". But he goes on to set up that advice as though they are saying "Open an editor, screw around with some syntax, and wait for the enlightment to hit you". Then he knocks that Strawman down, with ease.

I just checked the Prag Prog book: it is relatively terse on this point. I may be guilty of my own "Ironman Argument" here but, having seen Dave Thomas speak on several occasions, I doubt if they intended for us to take a full year to merely mess around with some core language syntax. My guess is that they will agree with the examples in the next item.

Problem #3: False Alternative

Gustavo seems to set up two choices: either noodle around aimlessly with a new language, or learn something specific with your current language, such as algorithms, math, or AI.

Wow. We have hit the trifecta now with the fallacy of false alternative.

There are more than two choices. Let's assume that we only know Java. How about these examples:

  • Write an implementation of a Red-Black tree in Scala.
  • Compute Pi to a million decimal places in jRuby. Then check an online source to see if you are right.
  • Develop a simulator for Tic-Tac-Toe that uses genetic algorithms to evolve a winning strategy. Use Groovy.
Sounds fun to me! Personally, I would learn (or dust off) something from all of these examples. And we would learn a new language along the way.

Problem #4: When timeless arguments aren't timeless

This isn't a formal logical fallacy, but Gustavo hints at some classic, timeless elements such as Lisp and the "Gotos Considered Harmful" article.

One might think that his arguments are timeless: nope. He asserts that:

In reality learning a new language is a gritty business in which most of the effort is spent on low-value tasks with poor return on time invested. You need to get to know the libraries, struggle with the environment, find or tune a text editor, look for tools, and so on.

This was true in the past, but with languages on the JVM and the CLR, we are in a golden age. As proof, consider the 3 examples above: all of those languages are a simple drop of a jar file and allow the use of the Java libraries. They run on the JVM. (Ted Neward has given entire keynotes on this idea.)

I will grant that the debugging/IDE facilities won't match Java, but this argument is completely bogus.

Problem #5: Confusing Momentum with Inertia

Again, this isn't a fallacy per se, but I take issue with this:

There’s another pernicious effect to language hopping: it hurts your momentum. Every time you rely on your current languages you get a little better.

Last year, I blogged about using Groovy to interrogate an OODB. My team still uses that tool. Anyone on the team could have written it in Java, but in the span of 5 years, no one had done so.

That's not momentum. That, my friends, is inertia. My little Groovy program is one of the biggest contributions I've made to that team: people ask me for it all the time.

The Upshot

Gustavo ends by recommending that we learn languages that are orthogonal to each other. I agree completely. And, for the record, I agree that merely dabbling is dangerous: I have probably been guilty of it myself.

But I heartily recommend learning a new language. And learning as much as you can about logical fallacies. They are everywhere (in this post?).

Monday, May 5, 2008

Satire Development Kit: Democrats Use Groovy To Pick Candidate

This is our first SDK: a Satire Development Kit that allows you, dear reader, to create your own satire, tailored to your own taste.

In this case: political taste. And we'll will learn a bit of Groovy along the way.

Architecture

The SDK is based on these steps:

  • No matter where you may lie on the political spectrum, you may agree that the process to pick the next Democratic presidential candidate (in the USA) is complex. It involves a mix of delegates and super-delegates.
  • Groovy is apolitical, but uses delegates to resolve references in closures. Since delegates may be objects, they may be derived from other objects, which we'll dub super-delegates.
  • Punchline: this is up to you. We just provide the tools.

Minimalist Example


class Foo {
def bar() { println "hello" }
}

def c = { bar(); }
c.delegate = new Foo() // delegate is a keyword

def candidates = [ "Clinton", "Obama" ]
candidates.each( c )

In the above example:
  • candidates is an array that has a closure, c, applied to each element
  • the closure calls bar()
  • Groovy will search for bar(), first in the owning scope of c (the script itself), and then, if necessary, in c's delegate
  • Groovy will not find bar() in the owning scope, but does find it in the delegate, which we assigned as a Foo

Full Example

Below, we have a full example where a self-named Delegate object acts as the, well, delegate and derives from the SuperDelegate, which can pledge (or not?) for a candidate.

class SuperDelegate {
def clintonPunchline = "TODO: fill in"
def obamaPunchline = "TODO: fill in"

def pledge(def candidate) {
if( candidate == "Clinton" ) {
println clintonPunchline
} else if ( candidate == "Obama" ) {
println obamaPunchline
}
}
}

class Delegate extends SuperDelegate {
// defer to base class
}

def convention = { it -> pledge(it); }
convention.delegate = new Delegate()

def candidates = [ "Clinton", "Obama" ]
candidates.each( convention )

The Upshot

Simply fill in the punchlines in the above Groovy script, and you're all set to lampoon (or support) one of the Democratic nominees -- or both -- via a dynamic language on the JVM. The direction of your satire is up to you. Impress friends and family no matter if you are a Democrat, Republican, independent, or international observer.

Enjoy!

Wednesday, April 30, 2008

Pulp Nonfiction: Defending the Transient Book

First, there was this attack on books: they are too long and have high-falutin' ideas versus the immediate gratification of raw code. After 2 days, I still cannot tell if it is a satirical piece.

Then, Jeff Atwood defends the timeless classics (e.g. Pragmatic Programmer) which stay on his bookshelf for 5+ years. Fine. This is the blog equivalent of shooting fish in a barrel.

I, too, enjoy the classic books and use online resources (such as these, by my colleagues) all the time.

However, someone has to stick up for some friends of mine: the excellent programming books that are highly relevant to me right now, but yet are not timeless. These books, call 'em Pulp Nonfiction, may well not be as useful in 5+ years. They aren't cheap, and I will probably clear them out for new editions. *sigh* What a pain! What an expense!

And yet you will have to pry them from my cold, dead hands.

I'm not talking about Dummies books, or "How to Learn X in N Days". I'm talking about books like Thinking in Java, Java Persistence with Hibernate, and Java Concurrency in Practice. And other books that may or may not be useful in 5+ years like the delightful duo of Groovy Recipes and Programming Groovy.

Here are some defenses for these wonderful works of Pulp Nonfiction. The following is brief because I fear that those "who be needin' it won't be readin' it".

The Forest and the Trees

A good book will offer up not only the tree-oriented detail that you need right now, but will give you a view of the forest. Consider concurrency in Java 5: there is no way that you can pick up the overall themes and issues from online docs. By understanding the forest, you'll always have a sense of context for the particular trees that you are dealing with.

Often, when confronted with a climbing a particular tree (i.e. solving a problem at hand), you'll know that it isn't about the answer, but a rephrasing of the question. That is, the real answer involves another tree entirely.

Timeless Tranquility

Sure, it takes time to read books, but the payoff is that the author has the chance to expand on ideas. For centuries, a book has been a thoughtful discussion in an intimate setting. Imagine having a dinner series with Gavin King!

It's a good example: the Hibernate online docs are terrific, but the book is better. The writing is more thoughtful and the background and issues are explained very well.

Getting Things Done

The book remains the ultimate mobile device. Yes, they are hard to search. Yes, they are a proprietary format and have limited storage (i.e. 1 book). But y'all can keep your Kindles and iPhones. When I am waiting for my car to be serviced, I'll take Effective Java, thanks. (Possibly the best example of Pulp Nonfiction, with a new release due).

The Great Conversation

When loaded up with the ideas and vocabulary of the times, you can engage in the discussions. And from these spirited conversations, we learn new ideas and views.

This isn't about elitism or impressing those at the local user group: it's about participation. And fine-tuning your B.S. detector so that you can protect your project, and minimize your time spend talking to posers.

(Note: it is true that the online stuff is vital on this point.)

The World is Flat

Imagine that you are at an interview for a new position. You need to read the Pulp Nonfiction because your competition already has done so. Give 'em hell.

Better Reader, Better Writer

Perhaps best of all, the more one reads, the better one can write. And that goes for prose, code, you name it. Don't scoff at this one: effective email communication is extremely important to your career.

The Upshot

Sure, use online resources. Absolutely, read the timeless classics.

But don't discount the transient books.

Discount most of them, but find the best, because they'll change the way you think. That's profound stuff. And if that comes for $40 and with a 3-year shelf-life, so be it. That's a steal.

Friday, April 18, 2008

iSurrender: a new chapter with a Macbook Pro

As posted in the past, I have been seeking refuge from Windows Vista and have been drawn to the autonomous collective known as the Mac community.

Tonight, I have joined them. This is my inaugural post from CtJ HQ on a spiffy new Macbook Pro.  (17 inch, matte display)

So far, so good... The out-of-box experience has actually matched the substantial coin I just put down. Up and running in a few minutes...

To my Mac friends at OCI and throughout St Louis: you are on notice! As Ted Neward once posted, you got me into this and I expect substantial helpdesk support ;-)

M.E.

ps. I haven't had the fun of exploring a new machine and OS in a long time. Like Linux, only more so, this machine takes me back to the true Wonder Years of my youth, when computing was truly fascinating and possibilities seemed endless.

Thursday, April 17, 2008

The Golden Rule of Testing and JUnit Assumptions

The Golden Rule of Testing:

  • There are two times when all the unit and integration tests must run and pass: immediately prior to a check-in and on the build server.

Great. But what about the time when the developer is actively working on a task? That zone of "dev time" is a gray area.

I think most developers run the particular unit test for the class of interest. Lately, I have been running integration tests with the wonderful dbUnit.

In this case, each test is working with Hibernate transactions. It is very important that each test perform its setup and teardown properly, as one error can impact other tests, and this is tricky to debug. Consequently, during dev time, I want to run all of the tests fairly often.

Well, all of them except one called Test Q. Test Q takes 90+ seconds. It has become my nemesis, my rival. I see it running when I close my eyes at night. It haunts me.

Options

There are plenty of options for dealing with Test Q. We could break it up into different tests. We could write a test suite. And so on.

However, with an article and a JUG presentation, Charles Sharp has opened my eyes to the possibilities in JUnit 4.x.

Assumptions

JUnit 4 (and other modern testing frameworks) have a concept of theories and assumptions. These ideas are interesting, but outside of the scope of this post. Check out this article for more.

For my needs, suffice it to say that an assumption is used to declare assumptions about the data coming into a unit test. If the assumption is not true, then the test automatically passes.

Here's an example:


import org.junit.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assume.*;

public class AssumeTest {
@Test
public void testA(){
int x = 1;
assumeThat( x, is(7) );
System.out.println("assumption is true!");
}
}

The assumeThat statement assumes that x is 7. If not (as in this silly example), the test will quietly pass. This may seem horrifying, but it makes sense within the realm of theories.

It also blows the door open in terms of dev time. There are two advantages: (a) the test passes and (b) x is a runtime variable. Compare this to another approach with a timeout variable.


public class AssumeTest {
@Test(timeout = 5000)
public void testALongRunningTest() {
}
}

In the above example, the test will timeout after 5 seconds. However, the test will fail and the timeout value must be a constant. During dev time, I don't want Test Q to fail; during the Golden Rule, I don't want it to timeout. Effectively, I want to skip it on my terms.

Configuration via Assumptions

I don't know yet if what follows is merely a parlour trick. I have not yet used it in production, but one can do some pretty cool things with these assumptions, outside of the theory arena. We can make assumptions about the state of the JVM in order to determine if we are in "dev time".

For example, we can do the following:
  • Configure a test so that it can be disabled via a JDK parameter (take that Test Q!).
  • Configure tests so that only a given percentage of them will run at a given time.
Both can be done with assumptions. And in both cases, the Golden Rule is not violated.

Here is an example of the first configuration:


import org.junit.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assume.*;
import static java.lang.System.*;

// class under 'test'. I work in biology
class Bacteria {}

public class BacteriaTest {

@Before
public void setUp() {
out.println("hello from setup");
}

@After
public void tearDown() {
out.println("hello from teardown");
}

@Test()
public void veryLongTestA() throws Exception {
// if DEV is defined, then skip and auto-pass
assumeThat( System.getProperty("DEV"), nullValue() );

out.println("running long test A");
Thread.sleep(90 * 1000);
}

@Test
public void reasonableTest() {
out.println("reasonable test");
}
}


To run this example (with JUnit 4.4+ on the classpath):


apt BacteriaTest.java
java org.junit.runner.JUnitCore BacteriaTest
OR
java -DDEV=true org.junit.runner.JUnitCore BacteriaTest


The idea is simple: when the Golden Rule applies, no JDK params are provided and everything runs. But the dreaded test can be skipped when needed.

Admittedly, it does require code within the test, but I'm not sure that it is intrusive.

This is especially true in the next example, which combines both ideas: the one mentioned above but also another. This second idea is: during dev time, can we run some of the tests? The thought is that we don't want to run them all but don't want to run only one either. Think of it as a testing heuristic of sorts. The example below is neat in that the choice of tests is random.

Here's the code:


import org.junit.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assume.*;

import java.math.*;
import static java.lang.System.*;

// class under 'test'. I work in biology
class Bacteria {}

abstract class BaseTest {
// if DEV is defined, auto-pass test (i.e. skip)
public void binarySwitch() {
assumeThat( System.getProperty("DEV"), nullValue() );
}

// if random value < THRESHOLD, auto-pass test (i.e. skip)
public void probabilitySwitch() {
int threshold = 101;
String thresholdStr = System.getProperty("THRESHOLD");

if( thresholdStr != null ) {
threshold = Integer.parseInt( thresholdStr );
}

int value = (int) Math.floor( Math.random() * 100 );
boolean doRun = ( value < threshold );
assumeThat( doRun, is(true) );
}
}

public class BacteriaTest extends BaseTest {

@Before
public void setUp() {
out.println("hello from setup");
}

@After
public void tearDown() {
out.println("hello from teardown");
}

@Test()
public void veryLongTestA() throws Exception {
binarySwitch();

out.println("running long test A");
Thread.sleep(90 * 1000);
}

@Test
public void reasonableTest() {
probabilitySwitch();

out.println("reasonable test");
}
}


Again, to run this example (with JUnit 4.4+ on the classpath):


apt BacteriaTest.java

// Golden Rule
java org.junit.runner.JUnitCore BacteriaTest

// or Dev Time
java -DDEV=true -DTHRESHOLD=25 \
org.junit.runner.JUnitCore BacteriaTest


In this case, we've refactored the first idea into the binarySwitch() method and introduced the probability heuristic into the probabilitySwitch() method. The reasonableTest() might run and it might not. This is silly in the small example, but consider it over a large test base.

Again, this doesn't violate the Golden Rule because the assumptions will be true. But it may have potential for development time, when they can be falsified. Because JUnit 4.x completely supports the 3.x format of tests, I might try swapping out the jars at my day gig.

Test Q, you are going down!