Sunday, December 31, 2006

Dipping My Foot In The Mac Waters

Well, today I dipped my toes in Mac waters with a PowerBook G4. I haven't had much time to dive into yet, but so far so good. Now, I need to get Squeak, Self (finally!), and F-Script installed. I'll keep everyone up to date on my findings. Wish me luck!

Friday, December 15, 2006

L'Atomium

I've spent the evening looking at pictures taken of L'Atomium in Brussels. I must go see this in person. It has to be the coolest thing I have ever seen. The inside is way cool. If I ever become rich, I want my house to look like this (both inside and out). I'm in complete love with it.

You are missed, Dawn

Power lines,
Steel webs confine,
Violating the brownish sky.
Hard grey smothers,
Earth, like cancer.
Cracks revealing,
Ground below.
Broken and bleeding,
every seed, every stone.

One of my favorite albums of all time, Fear of God's "Within The Veil" began with the above quote and you knew it wasn't going to be a cheery album. It's been ten years since Dawn passed and this has to be the darkest week in metal. We lost three great musicians all of which released albums that I cherish and love. So, today I raise my glass and listen to my metal brothers and sisters that are no longer with us. You all are missed dearly.

Are We Worrying About The Wrong Things?

Frank Kelly has written an excellent article entitled:"Are we worrying about the wrong things?" It's mainly aimed at the Java community, but it has relevance to all of us. The points he makes are problems in any programming language (minus the closure and language debate ones). It's great reading.

I agree whole-heartily with him. After awhile, I get tired of the same old language wars (pick your tools, know them well, and kick booty). We all need to know our tools better.

The core of the article is the message: Get better at your craft and mentor others on what you learn. It's up to us to make our community better. The time of being smug is over. We're in the same boat, let's help each other out.

I love Smalltalk, but I'm not afraid to use other tools. And I really don't mind Java that much (most of my rants come looking at poorly written Java). Good design is good design no matter what language. Yet, I see under-abundance of talk on design. I'm still shocked at meeting people who have never read Rebecca Wirfs-Brock's excellent "Object Oriented Design" or "Structure and Interpretation of Computer Programming". Both excellent books on design that transcend language. If you don't have them, buy them now and get "Code Complete" as well.

Anyway, the article is awesome and is a good wake-up call to us to look at the bigger picture.

Wednesday, December 13, 2006

Good Quote

Thought And Readable Code

Chris makes the following observation while wondering why the functional folks are such zealots:
No tool solves every problem. Put down the damned hammer and pick up a screw-driver once in a while.
I agree with the above sentiment. I love a lot of different languages for various reasons. I often say that everyday I get closer to becoming a functional programmer because that style keeps rearing its head in my code. But, like anything it needs to be tempered.

It's all about balance and simplicity. I think the functional guidelines of trying to make most objects stateless and composition to the smallest and simplest are wonderful. The code you write reads well and if you try to restrict the places where you change, then it's easier to find bugs when problems arise.

The point is don't go overboard with your ideology. The end goal should always be readable code. Readable code changes information in few places. Readable code is easier to maintain. Readable code performs well. Readable code cares about the programmer that has to pick up the pieces once you're on to something else. Readable code is small. And finally, readable code is simple.

But, readable code takes thought. Design takes thought. Most of the zealotry that I witness is from people who want to remove thought. They think great code comes from restriction. It does not. It comes from freedom to have choice. Sure, you can make a bad choice, but sometimes the bad choice might be the good choice in certain situations. But, the choice requires thought. Any hard and fast rules should be looked upon with suspension. In the wise words of George Clinton:
Think! It Ain't Illegal Yet!

Oh, and if someone still wants to make religion and dogma out of anything technical (like the functional and XP evangelists), tell them to:
Go Wiggle

I'm going to think about making better code and designs.

Shallow are words from those who starve...

...For a dream not their own to slash and scar.

Chuck you are missed, bud. Thank you for enlightening us with such great music before your untimely death. Let the metal flow!

Friday, December 08, 2006

Thinking And Sharing Ain't It Cool?!

Jeff Wild had a few comments about my Jakarta Commons post. Good stuff. It got me thinking though. The Jakarta Commons Collections library allows you to combine predicates, transformers, and closures via utility classes. And that's where my head was because my problem at work needed to have the predicates combined in different ways and I didn't want to pollute the public API of my class unneedlessly with each special case. But, Jeff made an excellent point. Do I want the clients of my code to have a dependency on the Jakarta Commons Collection library? What's a developer to do?

Then, it occurred to me. I should just make my collection of objects it's own domain specific object that I can then send the proper messages to. Thus, instead of a Collection object, you have an AccountCollection object that wraps around an ordinary collection. And this is where I can stick the "active" method. It's not static and reads so much better.

But, what about being able to combine predicates, transformers, and closures? I didn't discuss that in the original post. My post was inspired by a problem at work where I needed to combine different predicates on in-memory objects. So, it would be nice to have a "where" method that selects a subset of my new AccountCollection. I could even make the "where" functionality available in an abstract collection so that future domain specific collections could enjoy its benefits. But, to combine predicates, it's still ugly with all of the static utility method calls. Yuck. OK, what if I write my own abstract predicates, closures, and transformers that can chain themselves? For instance, you could have "and" and "or" methods to predicate; "then" for closures; and "as" method for transformers. Underneath the covers, could simply call all of the static utility methods. I get readability back (getUser().getAccounts().active() and getUser().getAccounts().where(Account.BY.olderThan(DAYS_90).and(Account.BY.active())).

I like this approach better and it keeps the knowledge shared. You could put the most frequent queries in the the domain specific collection, but still leave it open for future extension of less used queries or transformations.

Yet, again, this approves the more you move functionality down and spread responsibilities around, the easier your code becomes to read. Thanks to Jeff for making me thinking of where my solution was ugly.

Case Statements...They're Still Used?! Say it Ain't So!

It seems you can get a null pointer exception using enumerations and case statements. Ouch, my first gut instinct is why use a case statement? The enumerations in Java 1.5 support methods. Let polymorphism be your guide.

Of course, I'm surprised the minds at Sun let such mistakes go by. Both auto-boxing and enumerations allow null pointer exceptions that most coders will not catch because typically you don't expect them (because of the expansion of the real code). I think this is going to catch a lot of unsuspecting developers. Java has trained our eyes and minds to where potential null pointer exceptions could lie. Ouch. The rules have now changed.

Again, nulls rears its ugly head to smash down all of that compile type checking non-sense. It all compiles, but will it run? How much do you want to pay for safety that's not guaranteed? I'd rather not fight monsters with blankeys, but with a real sword (unit tests).

Getcha Pull

Thank you, Dime, for all of the great tunes, riffs, and solos. You are missed, my brother. You were taken from us too soon.

Thursday, December 07, 2006

Agile Religion

I was going to write a blog entry about this Agile debate at Thoughtworks. But, Micheal Burke said it all much better than I could. So, I reproduce it here for your reading enjoyment. Man, I wish I had written this.
I thought Patton's definition of "software success" (taken from the blog post) was interesting:

'We knew we?d delivered successfully not when the ?EAR file as uploaded to the server,? but when we saw end users successfully working with the software on a daily basis.'

Depends on the scope of a project I suppose, but for me, I would add to that sentence "and in 5 years' time".

That draws in concerns such as flexibility of design, level and quality of documentation, ability to accomodate increasing volumes, anticipation of change, etc.

A lot of these things are anathema to the Agile dogmatist mindset (you ain't gonna need it!), and, dare I say it, the typical consultancy mindset (I've used my glorious methodology, now the maintenance guys can take over and I'll move on to the next gig - but first I'll blog about how great I feel about it.)

Given the investment in money, people and time for software of any real significance, just having something that is good enough today is, not, well, good enough.

The point that 'Agile' is now an overused cliche is well made. As is the use of 'Waterfall' to paint any project that doesn't call themselves 'Agile'. They're just labels that lazy people use to pigeonhole - kind of like music genres!

All I can add is, "AMEN BROTHER!" I totally agree.

Sunday, December 03, 2006

Apparently, I like bad music

Blender made a list of the 50 worst music artists. It should come as no surprise that I like artists on that list. The guilty were: Skinny Puppy, Oingo Boingo, Whitesnake, and Kansas. How many artists do you like make the list? Fess up now...

Metal

Tenacious D's performance on Saturday Night Live singing their song, "Metal" was awesome. I was in tears. Just remember, nothing can stop the metal. Let the metal flow! Jack Black and crew ROCK!

Jakarta Commons: Collections

Lately, I've been using the Jakarta Commons Collections library quite a bit since I've been back in Java 1.4 land. The library gives you everything you're used to with iteration methods available in Ruby and Smalltalk (do, collect, select, detect, etc). But, with the verbose and cumbersome syntax of anonymous methods the point of what you're trying to do gets lost. For example,
Collection activeAccounts=CollectionUtils.select(someAccounts, new Predicate() {
public boolean evaluate(Object object) {
return ((Account)each).isActive();
}
});
Wouldn't this be nicer:
Collection activeAccounts=CollectionUtils.select(someAccounts, Account.BY_ACTIVE);
One, it's lot less typing and reads much better in your logic. I've put the Predicate on the Account class. I really liked doing it this way and made my code read much more cleanly. Also, by having the Predicates defined on the objects that they were operating on, it made it easier to find which Predicates had already been defined. Everyone wins right? Well, no, I started using the same technique for Closures and Transformers too. My objects started to get crowded because I look putting my public static declarations at the top. Now, what to do?

Well, I was speaking to Matt Secoske one morning, we naturally started to discuss my dilemma of growing predicates and he had a simple answer: Put them in inner classes. At first, I scoffed at the idea, but after thinking about it, I came up with the following code:
public class Account {
public static final Predicates BY=new Predicates();

//Class stuff...

//Put this at the bottom of the class
static class Predicates {
public Predicate active() {
return new Predicate() {
public boolean evaluate(Object each) {
return ((Account)each).status.isActive();
}
};
}
}
}
I have no idea why I didn't like the idea at first. But now, my client code looks like this:
Collection activeAccounts=CollectionUtils.select(someAccounts, Account.BY.active());
The client reads the same, but now, I've gotten the implementation of the predicates out of the way. Everyone wins. I also put my transformers in their inner class named AS and one for closures called EACH. The important thing is that I keep meaningful information at the top and my client code reads well. Another thing to note is that now I can hide more information and expose less. You would be amazed at how much data is exposed in predicates. Yet, another nice side effect.

You will also notice that in the resulting code that I used a status instance variable to figure out if it was active so that I didn't have to duplicate the protocol of the status object through the Account object. My code has been getting simpler and it's been shocking me.

The point should always be to make the clients that use your objects life easier and more readable.

Amazon