Tuesday, December 19, 2006

The Man Who Sold The World

Was Thomas Edison the world's first patent troll, or at least the most famous? Fortune's Business Innovation Insider displays a list of the "nine things Edison never actually invented." In case you were wondering, yes, Edison did sue rivals to enforce his patents.
Just for fun, compare the lives of Edison and his great rival Nikola Tesla. Edison was everything that Tesla was not. In particular, financially successful. However Tesla really was a great inventor. Without Tesla's polyphase alternating current power distribution technology, the world would not have developed the widespread use of electric power.
Which is not to say that Edison did not contribute anything...but his contributions were more developmental than inventive in nature.

Patently Absurd

Paul Kedrosky comments on the latest travesty in the abusive system that we use here in the US for "protecting" intellectual property related to computer software.
As someone who gets paid by creating IP, I am supposed to support the US patent system, right? But I cannot help but think, what if the attitude of the early innovators in software had been like that of the current industry? How would have kids like me grown up hacking the Apple ][ using the published source code of its ROM? How would the Mac or Windows been created without mimicking the various OSes that went before it? How would innovation have occurred at all, let alone at the pace at which we have grown?
I look at my career, and it only exists thanks to standing on the shoulders of the giants. Where will we tell the next generation of dead programmers to stand? If we do not cultivate the minds and collective knowledge of our industry, the future programmers may be standing in an unemployment line.
Patents are intended to protect the public good, not merely to enrich individuals. If we do not reform the patent system for software, and quickly, we run the risk of massive consolidation in intellectual capital. Without the entrepreneurism and sharing of ideas that have made the software industry an engine of economic growth, the future of the US will be much poorer as a result.

Thursday, December 14, 2006

Merb Is The Word

I have been playing around with Merb, which is a very cool project from Ezra Zygmuntowicz. Merb combines the Mongrel web server with a lightweight Ruby web framework. It has way less stuff in it than Rails, but is somewhat more than Camping.
Where this all started, was that I was looking for some way to use Mongrel to create a new REST web service for a client. This service has no UI, and basically just needs to front end a Ruby DSL that I have been working on. Another need was that I had to have something that can easily handle multithreading. Rails will block on a single thread, and also I do not need all of the Rails AJAXy goodness. So Rails seemed like a bit too much, and Camping not quite enough.
It was at this point that I discovered Merb. Merb handles threading very simply, by dispatching each new request to a new controller created on a new thread. It also has a very clean and simple support for rendering of HTML, JavaScript, and XML views. In my case, I only really cared about returning XML, so Merb seemed ideal for my needs on this project.
Starting a new Merb project requires some hand copying of files. There is a sample application included, which helps see some of what Merb can do, as well as showing how to setup your own project. At this point, Merb is very early in its lifecycle, so if you want to use it, prepare for a hands-on experience. The Merb code is very simple and clear, however, so it is not hard to see what is going on under the hood.
One of the main problems that Merb was designed to solve is better handling of long running server processes. One example of this is uploading files to your web server. Rails will block on each file upload until the upload is completed, which is a recipe for poor performance (read server unresponsive) if you will have a lot of requests to upload big files. The Merb sample app shows how to use Merb to deal with file uploads. And since Merb supports ActiveRecord, you could easily integrate a Rails app with a small Merb app or two to handle some performance bottlenecks.
Merb is much newer than Rails or Camping, but despite it not being even quite half-baked yet, the parts that are finished are delicious! Looks like it will be a really nice option for an alternative/adjunct to Rails. Now someone just needs to create a generator that lets you start a new Merb project...and some documentation/tutorials.

Monday, December 11, 2006

Resistance To Change

Obie Fernandez comments on Seth Godin's observation that he would be a lousy pilot. Maybe this explains why I do not have a pilot's license...
Obie notes that "innovators catch the most grief from management". But why would this be the case, when management is so eager to capitalize on said innovations? Perhaps a look at anthropology can help. A few years ago I watched a fantastic program on the Discovery Channel called "Walking With Cavemen." As one review of the DVD on Amazon states, "Using real actors and actresses, amazing make-up and special effects, Professor Winston takes us through the lives and times of our remote caveman ancestors." The part that impressed me the most was a example of why Neanderthal was eventually replaced by Homo sapiens, although the two lived side by side for thousands of years.
Homo sapiens was able to learn from experience, and change behavior based on new observations. The example used in the show was that by seeing a group of scavenger birds flying in a circle in the distance, and then noting that a dead animal was in the same location where the birds had been flying, a group of homo sapiens was able to find food the next time they saw birds flying in a circle. A group of Neaderthal was unble to make the connection, and starved to death.
Consequently, homo sapiens was able to survive climate changes that caused Neanderthal to become extinct. Simply enough, our capacity to change and adapt, which is our greatest survival trait as a species, is what most people actually resist the most.

Friday, December 08, 2006

That Ruby Is So Hot Right Now...

I was just reading the latest stats from the TIOBE Programming Community Index. What is this index? They say themselves that it "gives an indication of the popularity of programming languages." Yes, I know what Mark Twain had to say about stats, but I still love reading them! Anyhow, the latest and greatest December 2006 stats are fascinating as usual.
Ruby is still surging in popularity, in fact it has had the biggest rise in popularity over the last year of any language in the top 20. I know that Python/Django enthusiasts have been dissing Ruby heavily of late, but I refuse to get drawn in to any such nonsense. Any language that people actually use has good things going for it at something, or no one would use it at all. Especially any language that is reasonably popular.
Besides, dead programmers are eager to learn new languages. I myself am fluent in 7 of the top 20 languages, and able to fake my way thru a few others. And I'm sure that there are others out there who know more of the languages in this list than I do.
But my love affair with Ruby continues, and it sure looks like I am not the only one!

Friday, December 01, 2006

RubySSPI Gets Thru The Firewall

One of the biggest problem that Guerilla Rubyists have had getting our favorite language into the big companies that pay our bills, has been the corporate firewall. Using corporate Windows machines, behind corporate firewalls that use NTLM authentication to the corporate domain, has meant "no Ruby programmatic access to resources on the other side of the firewall." In other words, no RubyGems! Having to try to download every Gem (and every Gem that the Gem you want to install depends on) for a local install it at the very least a big pain in the behind. I have been feeling this pain for a couple of years now!

Recently Justin Bailey released a Gem called RubySSPI that patches the Net::HTTP class to support NTLM authentication. I was excited! I manually downloaded and installed it...but it did not work for me. Others had successfully used it, however, so I did not give up so easily.

I have been working with Justin Bailey to help him figure out why it was not working in our typical huge corporate environment, and we have achieved success! I was just able to download a Gem in the "normal" way. I'm sure he will uploading an updated version of the Gem soon...Thank you, Justin!

Saturday, November 25, 2006

New Hebruby Release

I have just released a new update of Hebruby, the Ruby hebrew date conversion library. It is now available as a proper Ruby gem, and has much improved documentation. If your Rails application needs to convert from julian date to a hebrew date, or from a hebrew date to a julian date, or display a date in hebrew (either in hebrew or transliterated into english) this gem is for you.
To install it, just:

gem install hebruby

Thank you to everyone who has helped with Hebruby, especially Joshua Harvey, and enjoy!

Sunday, November 19, 2006

Ruby Domain Specific Languages - The Basics (Part 3)

This is another installment in a series about creating domain specific languages with Ruby. In part 1 and part 2 of this series, I created a simple Ruby DSL to describe the relationship between Pets and Persons. Now I will extend the DSL, and use some cool Ruby metaprogramming tricks to demonstrate the power and benefits of using Ruby to create an internal DSL.
First, I want to simplify the syntax for declaring things in our DSL. Getting rid of the class definition stuff can make it a lot easier for domain experts to read. A simple, cool declarative style like Rake is what we want to end up with, something like this:

person "Dorothy" do
temperament :nice
food :sunflower_seeds, :carrot_juice
end

Furthermore, I want to extend our DSL to put all of the descriptions of Pets and Persons together into a PetShop. Here is our PetShop DSL:

shop = PetShop.create do
pet "Toto" do
friend_test do |person|
true unless person.temperament == :mean
end
end

pet "Tweety" do
friend_test do |person|
person.has_food?(:sunflower_seeds)
end
end

pet "Slugworth" do
friend_test do |person|
true # I like anyone
end
end

person "Dorothy" do
temperament :nice
food :sunflower_seeds, :carrot_juice
end

person "Witch" do
temperament :mean
food :cheetos, :soda
end
end

One interesting technique used is declaring the "pet" within the "do-end" block for the "petshop" object:

shop = PetShop.create do
pet "Toto" do
friend_test do |person|
true unless person.temperament == :mean
end
end

...
end

The little bit of DSL niceness is achieved using the class_eval method. The block of code within the "do" block is called in the context of the newly created object. Here is the Ruby code that achieves this for a new Pet:

def self.pet(name, &blk)
@pets = Hash.new
p = Pet.new(name)
p.class.class_eval(&blk) if block_given?
@pets[name] = p
p.copyvars
end


Now that we have declared all of the Pets and Persons in to the context of a PetShop, we can test the relationships between Pets and Persons is a more general purpose way then in my previous post. The older, more fragile code was this:

dog = Toto.new
bird = Tweety.new
snail = Slugworth.new

person = Dorothy.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"
puts

person = Witch.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts

The new, cleaner code is like this:

shop.people.each_value do person
shop.pets.each_value do pet
puts "Is #{pet.name} a friend of #{person.name}? #{pet.is_friend?(person)}"
end
end

And here is the output when we run the program:

Is Toto a friend of Witch? false
Is Slugworth a friend of Witch? true
Is Tweety a friend of Witch? false
Is Toto a friend of Dorothy? true
Is Slugworth a friend of Dorothy? true
Is Tweety a friend of Dorothy? true

We have simplified the syntax of our domain specific language, and added some additional functionality. We have also been able to reduce the amount of Ruby code required at the same time.

Here is the final version of the code:

class DSLThing
def copyvars
self.class.instance_variables.each do |var|
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end

class PetShop < DSLThing
attr_accessor :pets, :people

def self.create(&block)
f = PetShop.new
f.class.class_eval(&block) if block_given?
f.copyvars
return f
end

def self.pet(name, &blk)
@pets ||= Hash.new
p = Pet.new(name)
p.class.class_eval(&blk) if block_given?
@pets[name] = p
p.copyvars
end

def self.person(name, &blk)
@people ||= Hash.new
p = Person.new(name)
p.class.class_eval(&blk)
@people[name] = p
p.copyvars
end
end

class Animal < DSLThing
attr_accessor :name

def initialize(name=nil)
@name = name
end
end

class Person < Animal
attr_accessor :temperament

def initialize(name=nil)
super
end

def self.temperament(type)
@temperament = type
end

def self.food(*types_of_food)
@food = []
types_of_food.each do |food|
@food << food
end
end

def has_food?(type_of_food)
@food.include?(type_of_food)
end
end

class Pet < Animal
def initialize(name=nil)
super
end

def self.friend_test(&test)
@friend_test = test
end

def is_friend?(person)
@friend_test.call(person) == true
end
end

shop = PetShop.create do
pet "Toto" do
friend_test do |person|
true unless person.temperament == :mean
end
end

pet "Tweety" do
friend_test do |person|
person.has_food?(:sunflower_seeds)
end
end

pet "Slugworth" do
friend_test do |person|
true # I like anyone
end
end

person "Dorothy" do
temperament :nice
food :sunflower_seeds, :carrot_juice
end

person "Witch" do
temperament :mean
food :cheetos, :soda
end
end

shop.people.each_value do |person|
shop.pets.each_value do |pet|
puts "Is #{pet.name} a friend of #{person.name}? #{pet.is_friend?(person)}"
end
end

Monday, November 13, 2006

The Dark Side Of Metrics

I have usually been in favor of measurement of any possible aspect of the software development process. Proper techniques of gathering and analyzing metrics have been espoused since Capers Jones created the study of software measurement. I was first introduced to many of these concepts in the writings of Steve McConnell, particularly when his book Rapid Development first came out. If a thing cannot be measured, it cannot be easily studied or improved.
But any tool, no matter how well intentioned its purpose, can be used for ill. Any system that relies entirely on user entered information can by lied to. Such systems can be gamed, for various purposes. In a very political environment, a rogue group can manipulate their own metrics to gain power over other groups, gain budget, or simply steer the company in the direction of their own egos. Sometimes metrics can be used to hide something important. "But look at our metrics," protests the manager in charge of a spectacular failure.
Even worse, once this starts to happen, the "everybody's doing it" syndrome strikes, and it can spread like a disease. Pity the poor foolish team that actually tries to tell the truth within such a system once this dynamic sets in. They will be punished, sometimes severely, for "not measuring up to the standards of the company".
The best sorts of metrics are collected automatically. All sorts of interesting information can be learned from analysis of the source code repository. Other information can be assessed from other dynamic sources such as number of unit tests passed, or Fitnesse tests, or measuring Running Tested Features. The important thing is that it is a lot more reliable to use metrics that are not so easily fooled by people with various agendas.

Wednesday, November 08, 2006

Ruby Domain Specific Languages - The Basics (Part 2)

Previously, I was exploring the basics of DSL creation using Ruby. This post continues sharing my lessons learned while developing a prototype of a domain specific language in the mortgage industry. Since I cannot share the actual code itself belonging to my client, I will continue to extract the useful concepts into these simple examples.

Last time we created a simple Animal DSL class. The important part of that class is this bit that makes sure our DSL like syntax works for the declarative methods:

class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
self.class.instance_variables.each do |var|
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end

Now we will create a Person class that can interact with the Animals. Each Person will have a temperament (either mean or nice), and will be carrying some kind of food in their pocket to feed their pet. We will define people using our DSL as follows:


class Dorothy < Person
temperament :nice
food :sunflower_seeds, :carrot_juice
end

class Witch < Person
temperament :mean
food :cheetos, :soda
end


The implementation is very similar to the basic Animal class

class Person < Animal
attr_accessor :temperament

def self.temperament(type)
@temperament = type
end

def self.food(*types_of_food)
@food ||= []
types_of_food.each do |food|
@food << food
end
end

def has_food?(type_of_food)
@food.include?(type_of_food)
end
end


Since we are working with an array, the self.food method has a variable number of parameters, represented using the asterisk in front of the parameters list. The cool little idiom @food ||= [] returns with the current @food variable, or if it is nil, returns an empty array. There is also a has_food? method to tell us if a person is carrying a certain type of food.

Now let us introduce the Pet. We will use the power of Ruby blocks to tell each pet the rules about when it likes a person, or not. Here is the DSL we want to use for the Pets:

class Toto < Pet
friend_test do |person|
true unless person.temperament == :mean # I like anyone who is not mean
end

end

class Tweety < Pet
friend_test do |person|
true if person.has_food?(:sunflower_seeds) # I like anyone who has sunflower seeds
end
end

class Slugworth < Pet
friend_test do |person|
true # I like anyone
end
end


And now the implementation of the Pet class:

class Pet < Animal
def self.friend_test(&test)
@friend_test = test
end

def is_friend?(person)
@friend_test.call(person) == true
end
end


The friend_test method stores a block containing the test for that Pet, and the is_friend? method tests to see if a Pet will be friendly toward a particular Person.
Last, we put it all together with some simple code to display the interactions between the People and the Pets:

dog = Toto.new
bird = Tweety.new
snail = Slugworth.new

person = Dorothy.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"
puts

person = Witch.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"


The result of running this code is:

Toto is a friend of Dorothy: true
Tweety is a friend of Dorothy: true
Slugworth is a friend of Dorothy: true

Toto is a friend of Witch: false
Tweety is a friend of Witch: false
Slugworth is a friend of Witch: true

Using this simple Ruby DSL approach, it is very easy to add a new Person or Pet, just by entering the rules that define its behavior. As the objects in a system become more complex, one of the best ways to manage that complexity is to create an abstraction that hides the ugly bits.

Here is the full code for this example:

class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
self.class.instance_variables.each do |var|
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end

class Person < Animal
attr_accessor :temperament

def self.temperament(type)
@temperament = type
end

def self.food(*types_of_food)
@food ||= []
types_of_food.each do |food|
@food << food
end
end

def has_food?(type_of_food)
@food.include?(type_of_food)
end
end

class Pet < Animal
def self.friend_test(&test)
@friend_test = test
end

def is_friend?(person)
@friend_test.call(person) == true
end
end


class Toto < Pet
friend_test do |person|
true unless person.temperament == :mean
end

end

class Tweety < Pet
friend_test do |person|
person.has_food?(:sunflower_seeds)
end
end

class Slugworth < Pet
friend_test do |person|
true
end
end

class Dorothy < Person
temperament :nice
food :sunflower_seeds, :carrot_juice
end

class Witch < Person
temperament :mean
food :cheetos, :soda
end


dog = Toto.new
bird = Tweety.new
snail = Slugworth.new

person = Dorothy.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"
puts

person = Witch.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"

The Planning Game Vs. The Crying Game

James Shore just posted a very cool chapterette from his upcoming book on agile development called "The Planning Game". The concept simply enough is that customers and developers work together to plan what features are going to be implemented, and in what order. Customers know what features have the most value to the business, so they get to choose the order in which features are developed. Developers know about the costs, so they get to say how long something is going to take.
In the Planning Game, the play is not quite so simple as the description above might suggest. As each team discusses a feature from their perspective (cost vs. value), the requirements for that feature can come into clearer focus, or be negotiated to reduce their cost.
More often, what I have experienced is the "Crying Game": whoever cries the loudest gets their way. The outcome of the Crying Game is not a good one. Either arbitrary and unrealistic deadlines are set by customers, or the wrong solution is provided by the developers. The crying doesn't end there; everyone is crying later as the recriminations fly back and forth. The moral of the story is that internal cooperation yields a lot more business value than internal competition.

Saturday, November 04, 2006

Ruby Domain Specific Languages - The Basics (Part 1)


I have been working on a prototype of a Ruby domain specific language for one of my clients, a very large financial services company. I have learned a whole bunch of really interesting lessons, which I will share over a short series of posts as I make more progress.

The first thing I tried to do was create a basic bit of DSL tastiness like this:


class Dog < Animal
number_of_legs 4
end

class Bird < Animal
number_of_legs 2
end

class Snail < Animal
number_of_legs 0
end



My first implementation of the Animal class looked like this:


class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end
end




Just looking at this bit of code, it seems like it should work. However, when trying this, it doesn't work as expected.


pet = Dog.new
p pet.number_of_legs # prints nil




In Ruby EVERYTHING is an object. This includes the class objects themselves, not just the instances of class objects! This means that when the number_of_legs method is called, it is actually being called before the actual instance object itself has been created. We need to get to our instance variable, and one way is to copy the class-level instance variable to the instance itself when the actual instance is being initialized like this:


class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
instance_variable_set("@number_of_legs", self.class.instance_variable_get("@number_of_legs"))
end
end


Now the class works as expected:


pet = Dog.new
p pet.number_of_legs # prints 4




As you add new things to your DSL, having to copy each variable manually is boring. The final change is to copy every class instance variable automatically at initialization, as follows:


class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
self.class.instance_variables.each do var
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end


This is a lot cleaner, and is much more maintainable code.

Thursday, November 02, 2006

Gmail For Mobile Rocks


I just installed the brand new Gmail for Mobile on my Motorola RAZR. In just a matter of a couple moments, I was looking at my Gmail inbox! Gmail for Mobile is a Java-applet that runs on your Java enabled phone. Keeping the network traffic down this way is a lot better option that a WAP-based email solution, which is what I had tried and abandoned previously.


Not having a QWERTY keyboard is a big limitation for smartphones especially where something heavily textual like email is concerned. Gmail for Mobile deals with this thru a clever mapping of hotkeys to the most commonly used functions (delete, in my case).

Between Google Reader, and now this Gmail for Mobile, another bit of my online existence has been sucked into the Googlesphere...and I like it!

Monday, October 23, 2006

Ruby Can Now Take Over The World

I am still overwhelmed with excitement about the big news that John Lam, creator of RubyCLR has accepted a full time job with Microsoft. John's blog has the details here.
MS had already jumped into dynamic languages with the acquisition of IronPython. Now it only a matter of time until "Ruby#" or whatever MS will call it (since there is already a Ruby.NET project, which is heading in yet another direction). *nix purists and MS haters may be cringing, but I think it quite legitimizes the Ruby meme to naysayers who may have thought Ruby was just a fad.

Working in the big corporate space, one of the primary objections that I have encountered to implementing systems written in the Ruby language, is needing to run on Windows and use existing complex .NET services that are already deployed in the enterprise. A Ruby coming from Microsoft, on top of a Ruby coming from Sun (JRuby), just sends a clear message to corporate types that "This Ruby thing is real". Heh. Heh heh, even.

Many of us have been trying to get Ruby taken seriously for a while, and this is exactly the kind of ammo that dead programmers need to not just sneak Ruby in, but storm the castle walls! Ruby will rule!

Toward A Test-Driven Culture

We all have to move to a test-driven culture. We cannot think about testing as an afterthought, or as a necessary evil. Testing has to be baked into the culture of software development the same way that testing is baked into Ruby on Rails. It is there right from the beginning, and makes you feel guilty when you DON'T do it. The DNA of software development has to evolve to grow systems with neurons that make it so that a lack of testing feels like sticking your hand into a wall socket; you notice right away when it happens, and you take immediate action to make it stop.

Software testers are considered "lower on the food chain" then software developers or analysts. That means testers are compensated less than their developer or analyst counterparts. Even on many important projects, across both companies and industries, this is still the case. This amazes me, given how much of the world runs on software. If the software that runs your airplane's landing gear, or your electronic voting system, or whatever other ultra-critical system has not been sufficiently tested, lives can be at stake. Despite the fantastic work being done in the area of software quality, and the proliferation of practices that can dramatically reduce the cost of creating and maintaining a system, we still all too often see quality getting shortchanged on required resources.

So testing is good, and we need more of it, surely. But we need to go further, much further. Giving proper attention to test-driven development is great. But even all this is not enough. What we need to do is to apply a test-driven mentality to all aspects of business. Marketers have found that testing and measuring their marketing yields a far greater ROI then marketing based on opinion or theory. Salespeople have been measured by quotas, and the most successful sales organization performing testing for some time.

In particular, we need to move toward management philosophies that apply testing to business decisions, in particular those about processes. All too often, decisions have consequences often than those intended, perhaps failing in one of more objectives. A new process designed to streamline a company, can actually result in adding more burden with less efficiency.

Without the ability to test, management will eventually lose control over itself. With no feedback, failures may be looked at as successes, and vice versa. Management cannot be arbitrary; by carefully adopting a test-driven culture across all disciplines within an organization we can improve both the quality of our work, as well as the quality of the experience we have while doing that work.

Sunday, October 22, 2006

The Coolest New Device I've Seen For A While


I just saw a really neat new gadget called "The Device Patented Process Indicating Apparatus " for the first time. Check it out at http://www.processindicator.com/

It is a USB device that can be connected to take whatever data feed you desire, and use the "inscrutable dials", Ethereal Glowing Tube (EGT), and incandescent lamp on "The Device" to indicate whatever status you want. "The build is broken", "sales are up", or "there is a soccer game today" are only some of the neat automation possibilities that come to my mind without much effort.

The only process indicating apparatus you'll ever need, indeed! Too bad they are not yet for sale...I want one of these! It is the coolest thing I have seen since the "Ambient Orb".

http://www.ambientdevices.com/cat/orb/orborder.html

Thursday, October 12, 2006

Architect Is Not An Honorary Title

The job title "architect" seems to mean something different inside every organization. At far too many companies, it is almost an honorary title, being reserved as a promotion for long-term company loyalists who "know the business", instead of actually meaning anything related to the overarching technical design required for the successful release of quality software.

Knowing the business is great. In fact, knowing the business is essential. I hope that business experts abound within your organization. But "architecting" is not what these people are doing.

Here is a list of some of the knowledge, skills, or qualities that I think are required for anyone who wants to be called "architect". In no particular order:

- Speaks in terms of design patterns
- Uses open source/commercial off the shelf(COTS) software
- Can determine the least cost solution for a particular business need
- Desire for a career path in technology which is NOT management
- Knowledge of both current and next-generation technologies, so that development efforts can be synched up with other developers in the industry
- Knows how to avoid or get out of anti-patterns
- Embraces simplicity as a fundamental design principle
- Can embrace the good ideas of others
- Unafraid of change

Do you know who the architects are in your organization? Are these the qualities that they are known for?

Wednesday, October 11, 2006

Programming Zombies Will Crush You



This post on the "Creating Passionate Users" blog really sums up what makes a Dead Programmer, well....dead!

http://headrush.typepad.com/creating_passionate_users/2006/10/knocking_the_ex.html

A colleague of mine once quipped, "Why is it that at some point in most people's career, they suddenly decide that they now know everything and don't have anything else to learn?". That is around the point that they are past the point of no return converging on the "micro-manage every detail" side of the "Zombie Function" graph.


So what happens to these poor middle managers? Is it the tribal "showing the size of one's beak"? Or is it a kind of post traumatic stress disorder, brought on by being way into the "anxiety zone" (I will post about the state of flow soon).

Odd that the very factors like creativity and free-thinking that can most stimulate success, are the ones most likely to be blocked by management at many companies.

So what can a poor, Dead Programmer do about it? Speaking truth to power is both difficult and dangerous. If you really think you are ready to take on a monoculture within your organization, you had better prepare. Once you finally get your chance to pitch them, you will only get one chance. Writing down your ideas well in advance of this can refine them down to the size of information packet that management will be able to digest.

Focusing on new solutions instead of dwelling on the mistakes of the past is also a good idea. This is particularly true when speaking to the individuals who got the company into whatever mess it is in, in the first place. Be very diplomatic, but still take a firm stand ("tough love"?), and keep it far, far away from anything that can be taken personally.

Lastly, keep in mind that only benefits that will really impact the business are important enough to risk the firestorm that sometimes arises when confronting a zombie organization. When I say impact the business, I mean either bring in major new sources of revenue, or dramatically reduce the cost per running tested feature.

Small incremental improvements to the organization are best implemented from the bottom up in a "stealth mode" project. More about that next time...

Too Skilled For Programming?

This classic bit of wisdom from David Dossot explains many things about management philosophy that frequently make little sense to developers. If you ever wondered how some people ended up in management, the answer is here:

http://perso.wanadoo.fr/lothar/datastore/TooSkilledForProgramming.pdf

In a world where taller people tend to more successful, I guess it makes sense. But logic has nothing to do with it! And things that lack logic offend the sensibilities of any self-respecting Dead Programmer...

Time To Reboot The Dead Programmer Society!

It has been too long, WAY too long, since my last entry. That means it is now time to reboot this blog in a new, better location. So what is this so-called "Dead Programmer Society", you may wonder?

This site is dedicated to the Dead Programmers who dwell inside the corporate world. Not really so much dead, but slumbering.

Wake up, wake up... and carpe codex!