Today we're going to start with a thought experiment. You are one of the better coders in your company. All the proof I need is that you're reading this. Ok, that may be a little self-serving but it is true that the better coders I know are always reading something about coding. It might be a new language, or a new technique, a programming question and answer site, or even a site that likes to rag on bad code.
Based on how many Code Monkeys you know, it's easy to figure yourself in the top half of programmers, a 'good' coder if you will. An assumption that is easy to make is that the higher your productivity the higher your pay. Is this true? If you base it on simple experience, the answer is no. It's too easy to get a job right out of college and get mediocre raises and then find yourself interveriewing candidates for openings in your own group where you have to offer 'market rates' to attract anybody. If you've been there for 5+ years, given a company desperate to hire warm bodies, it doesn't take much for the new guy to be making 15-25% more than you even if he is a two-finger typist and can't spell SQL if you spotted him the 'S' and the 'Q'.
Now, I'm happy where I am but it didn't take much to trigger my bad habit of thinking up 'what-ifs'. The Stackoverflow podcast has been a good one for this sort of pondering. Jeff and Joel have enough real-world experience to bring a ton of wisdom to the discussion on programming as it's own topic and in episode #42 discuss underperforming programmers. I'd been reading about how star actors can command huge salaries based on their past work and the expected effect on the box-office if their name appeared on the marquee. That major-league sports can have individuals who make 10-times what the lowest paid athlete makes on a single team, it doesn't take much to ask why programming doesn't see the same effect.
I submitted this as a question to the Stackoverflow podcast which they spent a good 10 minutes on in episode 77. It didn't fit so well as a question on Stackoverflow itself, I suspect the culprit is the lack of code snippets. Interestingly enough I discovered the podcast when they were at episode 65 and decided to start listening back at #1 and was up to around #42 when I decided to contribute my question. So anyway, when I saw the summary for #77, I didn't have the audio handy so jumped over to the transcript wiki for #77 and read the transcript. It was a pleasant surprise at how engaged they were and that the question wasn't dismissed out-of-hand. When I downloaded the audio, to hear their discussion it only reinforced my reaction.
The range of talent can be mighty wide even if there is some disagreement on the empirical numbers. Joel Spolsky talks about the difficulty in finding great programmers, and uses similiar metaphores in a comparison with opera singers. Jeff has a similar take on Coding Horror. Finding great talent is hard because there are only so many people who can do what you need done.
There have been some good discussions that has surfaced. John Cook has a good argument based on lack of meaningful metrics. It's a question that has been around for awhile. Frank Wiles makes the claim that hiring average (or below) programmers actually costs your company money (followup post). Obviously when a company says they only hire the to 10%, they are deluding themselves or at least paying lip-service to wanting good programmers. Joel does a great job of shattering that particular illusion.
What about sales? In some fields top salesmen can bring home seven-figure incomes so we know that the wide range of incomes aren't limited to Hollywood and the big leagues. James Kwak picks up on John's post and supports Joel and Jeff contention that paying the top performers much more than the average, outside of easily measured areas like sales and movies, has a corrosive effect on the group and the best coders end up leaving for greener pastures while the dregs hang on for dear life or are eventually pushed out. I can't disagree. It seems that if you are underpaid you have to ask yourself Ann Lander's question, "Am I better off leaving or staying put?" Just realize that it's no use complaining to the company, the status quo works for them.
Tuesday, December 29, 2009
Monday, December 21, 2009
Life's Too Short To Work For Clowns.
One of the cliche's of our culture is the little boy who rebels against his parents and dreams of running away to join the circus. His mind is filled with the glamor of the Big Top, the exotic animals, the independence of wandering the country from one town to the next. He hasn't really thought about what it means to work in a circus. The Ringmaster did many menial jobs before arriving in the spotlight. The animals have to be cared for; double the time it takes to feed them when you consider both ends of the animal. Traveling from town to town may sound romantic until you realize it means you spend more time traveling than in one place, lots of lonely nights on the road regardless of the weather or climate because 'the show must go on" after all. The life of a circus is not just popcorn, parades, and pretty girls.
I ran across a quote in Christopher Duncan's, "The Career Programmer: Guerilla Tactics for an Imperfect World" that made me both laugh and sigh.
So the question becomes, do you work for clowns? Does the development process at your company make a circus look like a well-oiled machine? You might work for a clown.
I plan on putting together a complement to The Joel Test where instead of a list of things a company does before you consider working for them, The Clown Test would be a list of things that indicate you might work for clowns.
This might describe your boss,
he might be a Tech Clown.
My apologies to Jeff Foxworthy.
When you run across a good example of a Tech Clown, send 'em my way and I'll add it to the list for every one's enjoyment.
Bookmark this on Delicious
I ran across a quote in Christopher Duncan's, "The Career Programmer: Guerilla Tactics for an Imperfect World" that made me both laugh and sigh.
You need to consider one additional thing when trying to convince management the current approach to developing software needs improvement. What do you do if non of this sways them and they insist on continuing with chaotic development approaches that consistently create disasters and stress? Update your resume. Life's too short to work for clowns.
So the question becomes, do you work for clowns? Does the development process at your company make a circus look like a well-oiled machine? You might work for a clown.
I plan on putting together a complement to The Joel Test where instead of a list of things a company does before you consider working for them, The Clown Test would be a list of things that indicate you might work for clowns.
This might describe your boss,
- if he thinks an estimate is a promise,
- if he thinks developers are interchangeable with no effect on the schedule,
- if he thinks its ok for the lead developer to publicly berate a junior developer,
- if he thinks requirements documents are a waste of time,
- if he thinks the only place for designers is at a fashion show,
- if he thinks he just needs one good programmer who can code anything,
- if he thinks that people whine too much about teamwork,
- if he believes in Silver Bullets,
he might be a Tech Clown.
My apologies to Jeff Foxworthy.
When you run across a good example of a Tech Clown, send 'em my way and I'll add it to the list for every one's enjoyment.
Friday, December 11, 2009
The Myth of the Aging Developer
I question that I've heard throughout my career is, "What happens to older software developers?" The danger with this question is when the discussion turns to the implied version which is "The lack of older developers means that it is a young persons game." Nothing could be further from the truth..
My wife and I are both developers. We have both been working as developers for 15+ years. One thing we noticed was that there were a lot of people working as developers who really shouldn't be, they didn't have the aptitude, interest or sometimes even the background. It would be easy to dismiss the problem as a lack of proper education but that doesn't explain the developers who lack a CS degree but who can code circles around veteran devs. Those folks usually decide that programming is not for them and move on to different job. Some go into management, some become analysts, while others change careers completely.
What's left? The ones who are passionate about development and are interested in doing it right. They love learning new stuff and don't gripe about how things used to be in "The good ole' days." They might be grumpy but they usually know their stuff.
The main problem would be in finding management who doesn't have a pre-conceived notion about what makes a good developer. If they feel that only the younger ones have the stamina to keep up with the pace, I'd wonder whether those same employers were the same ones who believe that the 'Deathmarch' style of project management is standard operating procedure. They'd rather grind through fresh-meat developers (Code-Monkeys anyone?) than listen to the experienced ones and change their development process much less change their management style.
Lastly, I've noticed that doing nothing but coding holds less business value than being able to communicate with customers, users, management, and vendors. One reason you start coding less is because finding answers to ambiguous requirements takes more experience and provides more payback to the business.
My advice, to those who worry about their coding future, would be to find a place where they need experienced developers to help with the overall task of creating or maintaining software, that also gives you the opportunity to code regularly. That way you can have the time to keep up with industry changes while taking advantage of your understanding of software development.
Bookmark this on Delicious
My wife and I are both developers. We have both been working as developers for 15+ years. One thing we noticed was that there were a lot of people working as developers who really shouldn't be, they didn't have the aptitude, interest or sometimes even the background. It would be easy to dismiss the problem as a lack of proper education but that doesn't explain the developers who lack a CS degree but who can code circles around veteran devs. Those folks usually decide that programming is not for them and move on to different job. Some go into management, some become analysts, while others change careers completely.
What's left? The ones who are passionate about development and are interested in doing it right. They love learning new stuff and don't gripe about how things used to be in "The good ole' days." They might be grumpy but they usually know their stuff.
The main problem would be in finding management who doesn't have a pre-conceived notion about what makes a good developer. If they feel that only the younger ones have the stamina to keep up with the pace, I'd wonder whether those same employers were the same ones who believe that the 'Deathmarch' style of project management is standard operating procedure. They'd rather grind through fresh-meat developers (Code-Monkeys anyone?) than listen to the experienced ones and change their development process much less change their management style.
Lastly, I've noticed that doing nothing but coding holds less business value than being able to communicate with customers, users, management, and vendors. One reason you start coding less is because finding answers to ambiguous requirements takes more experience and provides more payback to the business.
My advice, to those who worry about their coding future, would be to find a place where they need experienced developers to help with the overall task of creating or maintaining software, that also gives you the opportunity to code regularly. That way you can have the time to keep up with industry changes while taking advantage of your understanding of software development.
Tuesday, December 08, 2009
What I learned about Cryptography
In preparing a presentation on cryptography for a graduate class, I was surprised by what I learned.
Cryptography has been used from ancient times through the Industrial Age to the modern day. It's been used for military, diplomatic, criminal, and commercial purposes.
In the simplest and oldest form, Greeks used strips of paper wrapped around sticks of a certain size called a scytale - rhymes with Italy.
Julius Caesar is one of the first known users of the simple letter substitution method. The modern day cousin is ROT13.
If he had anything confidential to say, he wrote it in cipher, that is, by so changing the order of the letters of the alphabet, that not a word could be made out. If anyone wishes to decipher these, and get at their meaning, he must substitute the fourth letter of the alphabet, namely D, for A, and so with the others.
—Suetonius, Life of Julius Caesar
Hiding messages (steganography) is as old as the ancients. An example would be a tattoo on a shaved head. The hair would grow back hiding the tattoo. A modern example is hiding text in the pixels of a digital image.
Charles Babbage is a name taught in every into to computer science class as a pioneer in computing machines. I never knew that he helped the English during the Crimean War by breaking cryptological codes.
Mary "Queen of Scots" was caught when one of her secret codes were broken.
The Voynich Manuscript may have been an elaborate hoax to defraud a king, who had a interest in mysteries like coded messages, out of a large amount of gold.
A mob boss used encrypted messages to give out orders to his lieutenants and was arrested when the police cracked his amateur code.
Cryptography is thousands of years old and is used all around us everyday.
Thursday, December 03, 2009
Programmers - Poets or Mathematicians?
Programming software is much like writing a story. Any given story can be told in a near-infinite number of ways and those who practice the craft will spend just as much time, if not more, arguing over the style of a work, as if their subjective opinion can suddenly become objective fact. Usually this leads to a contest of "If you don't agree with me, I'll just keep talking until you see reason" or otherwise known as talking the subject to death.
I thought I'd shine some light on an example of this issue in programming. There is a never-ending debate in programming circles about the 'proper' way to write code that creates some true/false decision. Stackoverflow has a good example of this.
Even though the single line version isn't the most complex, different people read through code in different ways. A single expression can be easily parsed by people who have a math background or are experienced coders. That's not the point. The expanded version reads more like a sentence than a formula. It's easy to forget that there are plenty of coders without a background in math. It really comes back to the preferred style of the reader. Do they prefer reading expressions and formulae or something more like human speech.
Homer's The Illiad and The Oddessy are ancient works dedicated to expressions of speech. They were originally poems that were passed down in an oral tradition and meant to be sung instead of read.
Euclid's Elements is a work dedicated to expressions of logic. It covers objective proofs and unambiguous facts and is the beginning of the mathematical tradition, if you will, of rigorous scientific thinking.
The problem we face in software is code is a form of human expression, with all the imprecision that entails, attempting to communicate with the utterly logical CPU; programmers will be forever trying to translate "An Ode to the Machine" into the Pythagorean Theorem.
Bookmark this on Delicious
I thought I'd shine some light on an example of this issue in programming. There is a never-ending debate in programming circles about the 'proper' way to write code that creates some true/false decision. Stackoverflow has a good example of this.
My personal pet peeve (petty but my teeth grind everytime I see it) is verbosely setting booleans, e.g.
bool isValid;
if (percentage >= 0 && percentage <= 100)
isValid = true;
else
isValid = false;whats wrong with
bool isValid = percentage >= 0 && percentage <= 100;
It's soooooo much more succinct and easier on the eye
Homer's The Illiad and The Oddessy are ancient works dedicated to expressions of speech. They were originally poems that were passed down in an oral tradition and meant to be sung instead of read.
Euclid's Elements is a work dedicated to expressions of logic. It covers objective proofs and unambiguous facts and is the beginning of the mathematical tradition, if you will, of rigorous scientific thinking.
The problem we face in software is code is a form of human expression, with all the imprecision that entails, attempting to communicate with the utterly logical CPU; programmers will be forever trying to translate "An Ode to the Machine" into the Pythagorean Theorem.
Tuesday, December 01, 2009
If Gulliver Were a Designer
The term 'Design' gets thrown around a lot in software developer circles. There are constant flamewars over favorite techniques and battles over what good design really entails. When those arguments start getting too ad hominem figure out whether the speaker is a Code Monkey before giving them much credence. Since I've already braved the waters, see "Have Design Will Travel" or "The Age of the Design Review", instead of safely avoiding the issue, I'm going to bravely (or foolishly) join the fray.
Realize that there is more than one type of 'Design'. Design in the large turns into architecture and is something that really only comes with experience. Designing at the lower levels, say at the individual class/object level is easier to cover. Today I'm writing about design in the small vs the large; Lilliput vs. Brobdingnag.
The issues with designing a class is the same regardless of platform or language. The key is whether an object should be autonomous or whether it is better for any given behavior to be spread out among objects with limited scope and distributed responsibility.
For each class the answer might be different. We end up with a spectrum along which we can place classes based upon the Density of Responsibility.
Let's say you favor letting the class perform all the behaviors itself, or as many as you can. Starting on the left side of this graph, when you make your class more autonomous, the size of the class will grow unless you continuously refactor it to make it more generic. This leads to a template. If no refactoring is done, the tendency is for the class to become more "god-like" because if there is some behavior it needs, it has a method for that - it can do anything and everything. The number of fields and methods grow and soon become both unmanageable and unavoidable. Since the class already does so much, coders would rather add to the monstrosity than try to piece it apart and cut the Gordian knot.
The right side of the graph has classes that depend on other classes to a large degree. If the dependency level is high but the individual class is small, that is a sign of a framework; each class doesn't do much and requires lots of dependent classes to accomplish some function. On the other hand, a highly-dependent class that also has a large amount of code is a sign that the class is full of spaghetti.
The key to this question is to determine where you feel more comfortable on the graph. In any event, individual classes will end up spread out on the graph unless some organizational principle is applied, which is how you can achieve the results of Template or Framework.
Having just written that, I would say that there is a correlation between class size and degree of organization. Robert C. Martin (or "Uncle Bob") covers similar ground with package dependencies in his very thorough paper on Design Principles and Design Patterns[pdf]. JDepend is an implementation of the ideas behind the graph on page 26 and complements static analysis tools such as Checkstyle and PMD.
Bookmark this on Delicious
Realize that there is more than one type of 'Design'. Design in the large turns into architecture and is something that really only comes with experience. Designing at the lower levels, say at the individual class/object level is easier to cover. Today I'm writing about design in the small vs the large; Lilliput vs. Brobdingnag.
The issues with designing a class is the same regardless of platform or language. The key is whether an object should be autonomous or whether it is better for any given behavior to be spread out among objects with limited scope and distributed responsibility.
For each class the answer might be different. We end up with a spectrum along which we can place classes based upon the Density of Responsibility.
(Level of responsibility for behavior)
Autonomy - - - - - - - - - - - - - Dependence
High
C - [god object] [spaghetti]
l -
a -
s -
s -
-
s -
i -
z -
e - [template] [framework]
low
Let's say you favor letting the class perform all the behaviors itself, or as many as you can. Starting on the left side of this graph, when you make your class more autonomous, the size of the class will grow unless you continuously refactor it to make it more generic. This leads to a template. If no refactoring is done, the tendency is for the class to become more "god-like" because if there is some behavior it needs, it has a method for that - it can do anything and everything. The number of fields and methods grow and soon become both unmanageable and unavoidable. Since the class already does so much, coders would rather add to the monstrosity than try to piece it apart and cut the Gordian knot.
The right side of the graph has classes that depend on other classes to a large degree. If the dependency level is high but the individual class is small, that is a sign of a framework; each class doesn't do much and requires lots of dependent classes to accomplish some function. On the other hand, a highly-dependent class that also has a large amount of code is a sign that the class is full of spaghetti.
The key to this question is to determine where you feel more comfortable on the graph. In any event, individual classes will end up spread out on the graph unless some organizational principle is applied, which is how you can achieve the results of Template or Framework.
Having just written that, I would say that there is a correlation between class size and degree of organization. Robert C. Martin (or "Uncle Bob") covers similar ground with package dependencies in his very thorough paper on Design Principles and Design Patterns[pdf]. JDepend is an implementation of the ideas behind the graph on page 26 and complements static analysis tools such as Checkstyle and PMD.
Monday, November 02, 2009
Extreme Programming is People
There has been an enormous about written in the blogosphere on ways to improve how we write software. Much of the virtual ink spilled on the Internet about Extreme Programming, or Agile, or SCRUM, gathers at opposite ends of the spectrum. Some focuses on how those practices make things better, usually in a overly enthusiastic way which invites the curt dismissal as nothing more than hype and hyperbole. Others constantly remind everyone that they've tried it and it didn't work which invites observations about anti-social programmers.
Both camps need to call a truce. They'll get much farther - and be happier - if they stop throwing grenades at each other and start talking to each other.
We can get both sides to agree that the previous ways of software development is problematic and certainly non-optimal, at least if the goal is to develop acceptable software in a reasonably quick, consistent, and effective manner.
Once we've agreed on common goals, we can discuss typical obstacles and plan ways to avoid or mitigate them. One of the biggest problems, and least discussed, is how people affect the processes in which they participate. There is a good article by Alistair Cockburn about this phenomenon. His paper is titled "Characterizing people as non-linear, first-order components in software development".
The Story of Joe and Al
So let's examine more of the laws and how they affect an effort to introduce Extreme Programming. People who use the 48 Laws as a handbook for how to live their lives are usually label as evil, justifiably so. I don't want this discussion to degenerate into name calling or dismissed because of guilt by association so let's create two personas as our antagonist and protagonist. We'll call the willing and manipulative one Joseph (think Stalin) and the unwitting and hapless one Al (think Flowers for Algernon).
Law #1 "Never Outshine The Master". Humans are sensitive about losing face in front of others. Joseph uses this to his advantage to keep from attracting the wrong kind of attention. Al is proud of his achievements and doesn't understand why others don't share in his celebration.
Law #2 "Never put too Much Trust in Friends, Learn how to use Enemies" - Joseph keeps reminding himself to watch out for number one. He doesn't want to put his fate into the hands of others which means fewer allies but also fewer fair-weather friends. Al, on the other hand, cannot comprehend the idea that people have hidden motives even while having repeated instances of being taken advantage of.
Law #3 "Conceal your Intentions" is "Do unto others before they have a chance to do it to you". Keep the knife hidden from your intended victim. Joseph believes that life is a zero-sum game. Since he values himself over all others, he won't lose any sleep taking what he wants so he'll have more. He's interested in power and control, if he takes it from you it means you'll be powerless to respond after his power grab is fate de'compli. Al doesn't have the mental capacity to think one thing while saying or acting another. George Orwell's "Doublespeak" would be a foreign concept.
Law #7 "Get others to do the Work for you, but Always Take the Credit". Some poor soul on StackOverflow called this a "Seagull Manager - a scavenger who takes all the credit for your hard earned work and hangs around you like a bad smell." This will be a common behavior for Joseph who lacks scruples and thinks those who let him get away with it deserve to have their credit stolen. Al believes what society preaches in public, the value of hard work, work hard and keep your nose clean and you'll get what's coming to you, etc. He has the pride of the workman where good work will be recognized and rewarded. Combine that with no ability to detect deceit in others and you end up with someone who becomes the pawn of others. Naively believing the promises of their antagonists.
You can't approach a social situation as if everyone has the same motivations. Workplaces have plenty of Josephs blending in waiting for any situation to turn to their own personal advantage, and Algernons trying in vain to be accepted. If we don't recognize that, we'll be like farmers watering their crops with beer, "It tastes good to me so it must also be good for growing corn."
Bookmark this on Delicious
Both camps need to call a truce. They'll get much farther - and be happier - if they stop throwing grenades at each other and start talking to each other.
We can get both sides to agree that the previous ways of software development is problematic and certainly non-optimal, at least if the goal is to develop acceptable software in a reasonably quick, consistent, and effective manner.
Once we've agreed on common goals, we can discuss typical obstacles and plan ways to avoid or mitigate them. One of the biggest problems, and least discussed, is how people affect the processes in which they participate. There is a good article by Alistair Cockburn about this phenomenon. His paper is titled "Characterizing people as non-linear, first-order components in software development".
The Story of Joe and Al
So let's examine more of the laws and how they affect an effort to introduce Extreme Programming. People who use the 48 Laws as a handbook for how to live their lives are usually label as evil, justifiably so. I don't want this discussion to degenerate into name calling or dismissed because of guilt by association so let's create two personas as our antagonist and protagonist. We'll call the willing and manipulative one Joseph (think Stalin) and the unwitting and hapless one Al (think Flowers for Algernon).
Law #1 "Never Outshine The Master". Humans are sensitive about losing face in front of others. Joseph uses this to his advantage to keep from attracting the wrong kind of attention. Al is proud of his achievements and doesn't understand why others don't share in his celebration.
Law #2 "Never put too Much Trust in Friends, Learn how to use Enemies" - Joseph keeps reminding himself to watch out for number one. He doesn't want to put his fate into the hands of others which means fewer allies but also fewer fair-weather friends. Al, on the other hand, cannot comprehend the idea that people have hidden motives even while having repeated instances of being taken advantage of.
Law #3 "Conceal your Intentions" is "Do unto others before they have a chance to do it to you". Keep the knife hidden from your intended victim. Joseph believes that life is a zero-sum game. Since he values himself over all others, he won't lose any sleep taking what he wants so he'll have more. He's interested in power and control, if he takes it from you it means you'll be powerless to respond after his power grab is fate de'compli. Al doesn't have the mental capacity to think one thing while saying or acting another. George Orwell's "Doublespeak" would be a foreign concept.
Law #7 "Get others to do the Work for you, but Always Take the Credit". Some poor soul on StackOverflow called this a "Seagull Manager - a scavenger who takes all the credit for your hard earned work and hangs around you like a bad smell." This will be a common behavior for Joseph who lacks scruples and thinks those who let him get away with it deserve to have their credit stolen. Al believes what society preaches in public, the value of hard work, work hard and keep your nose clean and you'll get what's coming to you, etc. He has the pride of the workman where good work will be recognized and rewarded. Combine that with no ability to detect deceit in others and you end up with someone who becomes the pawn of others. Naively believing the promises of their antagonists.
You can't approach a social situation as if everyone has the same motivations. Workplaces have plenty of Josephs blending in waiting for any situation to turn to their own personal advantage, and Algernons trying in vain to be accepted. If we don't recognize that, we'll be like farmers watering their crops with beer, "It tastes good to me so it must also be good for growing corn."
Wednesday, October 28, 2009
Chapter 5 - The Programming Team
This continues my review of "The Psychology of Computer Programming" by Gerald M. Weinberg.
So far we've had individual programmers either working solo or in an environment where other programmers work but on separate tasks. As long as a single person can maintain the conception of the program, conflict resolution involves the thinking of a single individual, regardless how much advice is available or heeded. When a problem is too large for one person to hold in their mind at once, the scale of the problem goes up due to the increasing communication needs but is now one of a different kind. In this second case,
Sometimes we are our own worst enemy. If we want to stay our of our own way, we need to remember in software development, people are the biggest cause of failure.
For Managers:
- Are your hiring practices such that you get more uniformity on teams that you would like? When making up teams, do you try to see that a good "mix" of people is on each one, or do you strive in the opposite direction?
- Do you ever do things to try to inflate the appearance of your technical competence in front of the people who work for you? Describe some of these incidents, and also some incidents in which it was discovered that your technical competence was in at least one respect inferieor to one of the people who work for you. What were the consequences of that discovery, and do they justify attempting to cover up?
- In setting your own working goals, what part is set by what is passed down from above, and what part is set by what comes up from below? Are you satisfied with this arrangement, or would you like to alter it in some ways?
For Programmers:
- What part of programming work do you do best? Are you permitted to contribute that best part of your work to your team, and is it generally recognized that it is the best part of your work?
- Has your manager ever done anything to make you doubt his honesty? If so, describe the incident, what ultimately happened to your doubt, and how your work was affected.
Bookmark this on Delicious
So far we've had individual programmers either working solo or in an environment where other programmers work but on separate tasks. As long as a single person can maintain the conception of the program, conflict resolution involves the thinking of a single individual, regardless how much advice is available or heeded. When a problem is too large for one person to hold in their mind at once, the scale of the problem goes up due to the increasing communication needs but is now one of a different kind. In this second case,
"conflicting technical demands are translated into potential interpersonal conflicts, and a social mechanism must be formed to resolve them"This is part of the territory. Two people with solutions that are mutually exclusive. Programmers are proud of their intelligence and are more than willing to argue their side.
How A Team Forms
"As a rough rule, three programmers organized into a team can do only twice the work of a single programmer of the same ability"I'm no longer as convinced of this as I once was. It really depends on how well defined the separation is between the modules.
Establishing And Accepting Goals
"Social psychologists have verified in other contexts that failure of one or more members to share the group goals affects the group performance -- not only through that member's share but through a reduced performance on the part of the others, for they invariably perceive the division within the group or the indifference of one of the members."A non-programming example of this is when football teams get a new coach; the TV pundits like to use the phrase "They've bought into the new system" meaning that the players have taken the coaches goals for their own. A common programming example you might see in a development shop is where the current toolset and technology stack used is from Microsoft and there is that one guy who keeps muttering under his breath that "Microsoft sucks". His lack of cooperation will be felt by the rest of the team. The result may be that they avoid him instead of sharing the new trick they learned to solve some daily annoyance. No one wants to pair-program with him. The price being paid, at a minimum, is the reduced productivity of the frustrated Microsoft-hater.
The Team In Crisis
"The replacement of a leader--or any team member--is probably the most frequent and typical crisis in the life of a team. The effect of adding or removing a member depends quite sensitively on the group structure, and many a manager has been unpleasantly surprised at the change in performance resulting from the removal or addition of an 'insignificant' group member. "
If we need proof that programming is a social activity, we need look no further. Unless you are the sole programmer working at a company or on a project, there will always be a social aspect to what you do. I'll go even farther and say that unless you are the only person who will use the application, there will inevitably be people involved, from the person who asked you to write the app to the person who will be using the app.
"A member who is competent but who does not get along with the others can be an even more serious problem for the democratic group than an out-and-out incompetent. In an authoritarian group, such a member would not have much contact with others on a working basis anyway, so as long as he gets along adequately with the leader, he presents no particular problem. Indeed, some programmers prefer to work under a strong, centralized leader in order that they do not have to socialize with their fellow workers. But in a democratic team, an antisocial member cuts lines of communications and is a constant impediment to consensus in team meetings."
Sometimes we are our own worst enemy. If we want to stay our of our own way, we need to remember in software development, people are the biggest cause of failure.
Summary
Questions
For Managers:
- Are your hiring practices such that you get more uniformity on teams that you would like? When making up teams, do you try to see that a good "mix" of people is on each one, or do you strive in the opposite direction?
- Do you ever do things to try to inflate the appearance of your technical competence in front of the people who work for you? Describe some of these incidents, and also some incidents in which it was discovered that your technical competence was in at least one respect inferieor to one of the people who work for you. What were the consequences of that discovery, and do they justify attempting to cover up?
- In setting your own working goals, what part is set by what is passed down from above, and what part is set by what comes up from below? Are you satisfied with this arrangement, or would you like to alter it in some ways?
For Programmers:
- What part of programming work do you do best? Are you permitted to contribute that best part of your work to your team, and is it generally recognized that it is the best part of your work?
- Has your manager ever done anything to make you doubt his honesty? If so, describe the incident, what ultimately happened to your doubt, and how your work was affected.
Thursday, October 01, 2009
Peanut Butter Programming
When I first started messing with dynamic web pages it was using Perl and CGI. It was fun at first getting a page to respond based on some algorithm. It was also easy to overlook the growing mound of HTML strings embedded in your program. It soon became apparent that this approach doesn't scale very well. Keeping track of which tag needed to be closed and when was too much like keeping track of dynamic memory allocations in C.
Java came along with Java Servlet Pages (JSPs) and it seemed like a huge improvement. By inverting the relationship between code and HTML, you didn't have to have your HTML all strung out in little bits in the program. When you wanted to include some program logic in your page, you had two choices: write an extension so your logic could be expressed like an HTML tag, or you could embed it as a code-snippet directly in with the HTML. While there were plenty of examples of how to create your own tags, the overwhelming amount of JSP code I've seen took the other approach. To the extreme. When some behavior was needed in multiple places, sometimes it refactored into a common file and then referred to from multiple pages. Other times (which translates to whenever possible), it was copied and pasted around with the justification of "I just need it to work". The result was a file with little bits of program strung out through your HTML. Sometimes mixing two things can prove to be a good thing. remember the the TV commercial for peanut butter cups? "You have your peanut butter in my chocolate! No, you have your chocolate in my peanut butter!" Unlike that TV commercial, mixing HTML and code is a recipe for heartburn. Peanut butter may be tasty but will stick to everything it touches and you'll end up with a greasy mess to clean up if you're not careful. That's why I call this "Peanut Butter Programming".
Why do developers keep using approaches like 'cut-n-paste' even though they usually know better? When the choice is between doing the expedient thing and the right, people typically want to do the right thing but only to a point. If 'cut-n-paste' is simpler or easier than doing the right thing, the playing field becomes so tilted that some other motivation needs to be strong enough to deter choosing the short-term solution. Code standards are one example of that kind of motivation. They express a value judgment that the increasing maintenance costs of supporting bad code is not worth the time saved by taking short-cuts. If the programmer knows he'll have to face his peers and explain why he took a short-cut, his choice becomes "I can do it quick-and-dirty (QaD) in 5 minutes instead of the right way which would take 15 minutes. But if I do it QaD, I'll have to spend 30 minutes arguing at the code-review. It's not worth the argument so I'll just do it the right way and save myself the trouble." This sort of balancing act shows up naturally during pair-programming where having the second coder around makes it harder to justify writing messy code on the first pass.
Recently, I went to a class on Microsoft's ASP.NET technology. Setting aside any feelings for the company, the way they approached the problem of mixing code and HTML was to make it easier to do the right thing. They introduced the concept of a separate 'Code Behind' file which contains the C# or VB code for a given page. By making it easy to manipulate objects on the page and respond to events while keeping the code separate, they've made the right way also be the easiest way.
Even experienced developers will justify taking a short-cut, however short-sighted, if doing the right thing is hard enough to do relative to the short-cut. Different people have different tolerance level for short-cuts. Understanding why people do the things they do isn't easy but gives us the perspective needed to address the problem.
Bookmark this on Delicious
Java came along with Java Servlet Pages (JSPs) and it seemed like a huge improvement. By inverting the relationship between code and HTML, you didn't have to have your HTML all strung out in little bits in the program. When you wanted to include some program logic in your page, you had two choices: write an extension so your logic could be expressed like an HTML tag, or you could embed it as a code-snippet directly in with the HTML. While there were plenty of examples of how to create your own tags, the overwhelming amount of JSP code I've seen took the other approach. To the extreme. When some behavior was needed in multiple places, sometimes it refactored into a common file and then referred to from multiple pages. Other times (which translates to whenever possible), it was copied and pasted around with the justification of "I just need it to work". The result was a file with little bits of program strung out through your HTML. Sometimes mixing two things can prove to be a good thing. remember the the TV commercial for peanut butter cups? "You have your peanut butter in my chocolate! No, you have your chocolate in my peanut butter!" Unlike that TV commercial, mixing HTML and code is a recipe for heartburn. Peanut butter may be tasty but will stick to everything it touches and you'll end up with a greasy mess to clean up if you're not careful. That's why I call this "Peanut Butter Programming".
Why do developers keep using approaches like 'cut-n-paste' even though they usually know better? When the choice is between doing the expedient thing and the right, people typically want to do the right thing but only to a point. If 'cut-n-paste' is simpler or easier than doing the right thing, the playing field becomes so tilted that some other motivation needs to be strong enough to deter choosing the short-term solution. Code standards are one example of that kind of motivation. They express a value judgment that the increasing maintenance costs of supporting bad code is not worth the time saved by taking short-cuts. If the programmer knows he'll have to face his peers and explain why he took a short-cut, his choice becomes "I can do it quick-and-dirty (QaD) in 5 minutes instead of the right way which would take 15 minutes. But if I do it QaD, I'll have to spend 30 minutes arguing at the code-review. It's not worth the argument so I'll just do it the right way and save myself the trouble." This sort of balancing act shows up naturally during pair-programming where having the second coder around makes it harder to justify writing messy code on the first pass.
Recently, I went to a class on Microsoft's ASP.NET technology. Setting aside any feelings for the company, the way they approached the problem of mixing code and HTML was to make it easier to do the right thing. They introduced the concept of a separate 'Code Behind' file which contains the C# or VB code for a given page. By making it easy to manipulate objects on the page and respond to events while keeping the code separate, they've made the right way also be the easiest way.
Even experienced developers will justify taking a short-cut, however short-sighted, if doing the right thing is hard enough to do relative to the short-cut. Different people have different tolerance level for short-cuts. Understanding why people do the things they do isn't easy but gives us the perspective needed to address the problem.
Monday, September 21, 2009
Software as Literature
Alternative title: Sonnets to CPUs
Have you ever noticed that code follows some basic patterns? JUnit uses Setup(), Test(), Teardown().
I’ve playfully mixed writing and coding below.
Bookmark this on Delicious
Have you ever noticed that code follows some basic patterns? JUnit uses Setup(), Test(), Teardown().
I’ve playfully mixed writing and coding below.
//[Play about A Monarch's Destiny, in three acts]
Public KingdomFuture tellTheTaleOfMyRule(Kingdom landMyFatherLeftMe)
{
//[1st Act: Build Drama]
Vassal mySubjects = SoliloquyAboutMyKingdom.getMyPeasants();
Boolean mySubjectsLoyalty = testOfLoyalty(mySubject);
Vassal theCaptainOfTheGuard = SoliloquyAboutMyKingdom.getMyTrustedRightHandMan();
Boolean myTrustedServantsLoyalty = testOfLoyalty(theCaptainOfTheGuard);
KingdomFuture historysTaleOfMyRule = KingdomFuture.UNDECIDED;
//[2nd Act: Drama plays out]
if ( mySubjectsLoyalty == TRUE
&& myTrustedServantsLoyalty == TRUE)
{
HeapPraiseUpon(theCaptainOfTheGuard);
historysTaleOfMyRule = ExpandKingdomByForce(mySubjects);
}
if ( mySubjectsLoyalty == FALSE
&& myTrustedServantsLoyalty == FALSE)
{
ArrestTraitor(theCaptainOfTheGuard);
historysTaleOfMyRule = ImposeDispicableLaws(mySubjects);
}
//[3rd Act: resolve drama]
if ( deceptionHiddenSuccessfully(theCaptainOfTheGuard) )
{
return oldRulerOverthrown;
}
else
{
return historysTaleOfMyRule;
}
}
Monday, September 14, 2009
Discontinuous Integration
Refactoring is becoming a commonplace term thrown around these days. The expectation is building that refactoring is something that all good developers do and if you don't, you must be in one of "those" types of companies. You know the ones, they don't use a version control system or have a repeatable build, i.e. Continuous Integration, much less a well-defined deployment procedure.
If you are lucky enough to be building the first version of a product, you can refactor to your hearts content. There is no existing code to worry about breaking. If you are changing an existing system refactoring isn't always simple or straightforward. Even if you have the most automated CI and 100% code coverage of unit tests you'll still face the practical issues of deployment and business dependencies.
Let's say you operated the worlds most modern airline reservation system. It's written in the latest language and has all the buzzwords, highly available, highly reliable, highly scalable, etc. It has tons of automated tests so you are 100% confident that nothing will break. Now, since you have business partners like travel agencies and customers looking to book a flight or retrieve flight information, they have a stake in your deployment. The customers may tolerage a "Down for maintenencem, come back later." message but your partners will take a dim view of your downtime. They'll insist you tell them in advance so they can prepare any necessary changes in their systems or alert their support staff in case there are issues after the deployment.
Another example would be a large back-office accounting system. Whatever level of confidence you have in your code. you still have to deal with the myriad inputs and outputs of the system and disrupting the processing schedule for a code migration. No amount of automated testing/build/migration will ever solve these types of complexities.
The point is that considerations like these limit the opportunities to deploy code changes and increase the cost of change even when that change is guaranteed to work.
Refactoring is good but there are practical considerations why it's not done to the degree it could be in some shops. Keep that in mind next time you want to pass judgement on the perceived lack of refactoring somewhere.
Bookmark this on Delicious
If you are lucky enough to be building the first version of a product, you can refactor to your hearts content. There is no existing code to worry about breaking. If you are changing an existing system refactoring isn't always simple or straightforward. Even if you have the most automated CI and 100% code coverage of unit tests you'll still face the practical issues of deployment and business dependencies.
Let's say you operated the worlds most modern airline reservation system. It's written in the latest language and has all the buzzwords, highly available, highly reliable, highly scalable, etc. It has tons of automated tests so you are 100% confident that nothing will break. Now, since you have business partners like travel agencies and customers looking to book a flight or retrieve flight information, they have a stake in your deployment. The customers may tolerage a "Down for maintenencem, come back later." message but your partners will take a dim view of your downtime. They'll insist you tell them in advance so they can prepare any necessary changes in their systems or alert their support staff in case there are issues after the deployment.
Another example would be a large back-office accounting system. Whatever level of confidence you have in your code. you still have to deal with the myriad inputs and outputs of the system and disrupting the processing schedule for a code migration. No amount of automated testing/build/migration will ever solve these types of complexities.
The point is that considerations like these limit the opportunities to deploy code changes and increase the cost of change even when that change is guaranteed to work.
Refactoring is good but there are practical considerations why it's not done to the degree it could be in some shops. Keep that in mind next time you want to pass judgement on the perceived lack of refactoring somewhere.
Monday, August 31, 2009
In Search of Wisdom
The other day I was reading StackOverflow, a forum for developers to ask and answer technical questions, and ran across a post from a discouraged student. The responses had one thing in common: programmers know that they must keep learning. Tomorrow's hot new technology is just as soon to be yesterday's lost and forgotten relic. The best programmers are not the experts in a given niche but the ones who are comfortable with learning as a way of life. They know that they do not know and accept it. This makes them resistant to dictated dogma; a good example being Joel Spolsky's "Emperor's New Clothes" treatment of C-style strings. They are then freed from the ups and downs of the technological tide and are not battered by the constant waves of the newest, latest fad, nor do they feel deserted when some favored tech is washed away into the sea or wrecked upon the shoals.
Socrates is said to have walked the streets of Athens looking for a wise man. Wisdom is usually associated with knowledge but since it is impossible to know everything, true Wisdom is the awareness that you don't know. You can know a little about some things or a lot about a few. Those who believe they do know are blinded by their own ego and are thus willing to dismiss all doubts and set a course powered by a self-fulfilling sense of certainty. This describes how many a tribe of men met their tragic fate. Technology is not immune from the siren's song of certainty hence the never-ending search for the always-elusive "Silver Bullet".
When it comes to Wisdom, what sets apart the Codewright from the Code Monkey? A healthy dose of self-doubt. Doubt enough to realize that risks should not be dismissed solely because they are improbable. Doubt enough to allow the most skillful to help do the work, the most far-sighted to help guard the course, the most cynical to help figure the schedule. Doubt enough to keep unjustified self-confidence from enabling acts of hubris. This is just as true for teams as well. The best teams are the ones who understand both their strengths and their weaknesses. A group of individual superstars who can't learn to play together isn't always guaranteed success while a bunch of unknown amateurs who work has a cohesive unit can perform miracles.
Software development as a field naturally attracts those who are willing to accept the reality that there will always be more to learn. It is a good sign, one that indicates our chosen field will never stagnate. There will always be something to discover, a constantly flowing river of new challenges to overcome and puzzles to solve. The search for Wisdom is not for a desired destination, but of a fulfilling journey.
Wednesday, July 15, 2009
Tower of Babbling
When I started coding at my first job almost 20 years ago, it was at an OS/2 shop using C and Presentation Manager. I had several different languages in college so I wasn't too phased by the 1-2 week C training course we got. What I wasn't prepared for was memory management, C style string handling, message-driven applications, just to name a few.
I began my dislike of C early with the insanity called string handling. I was pleased when I found out that Joel agrees with me. Although there are plenty of people who will defend how 'intuitive' the string functions are, I knew there were much simpler ways to manipulate strings as long as you didn't need one larger than 255 characters, in which case using a char* buffer would be fine. Writing apps in something other than C was dismissed offhand with statements like, "C is much closer to the metal", "You don't have the run-time bloat of other languages", or "You have so much more control with C" which almost sounds like a masculinity test or something. Think lumberjacks and "my chainsaw is bigger so only the strongest can use it" type argument. Nowadays, this type of behavior would remind me of The Code Monkey.
Even 2 decades ago, it was possible to call code written in one language to call code written in another; in school we called assembly graphics routines from within Ada code for one class assignment. Notable exceptions are running compiled code from within scripts or executing a system command from within compiled code; but rarely do we write a library in C++ to use in our Java app. When Java first appeared and it was still slow, I never understood the resistance to writing the main app in Java and moving the bottleneck code into some C/C++ dll and called using JNI. It's like we use the "language X sucks at a, b, and c so we can't use it" as a shield that keeps us from having to design multi-language applications.
So, after all these years, what keeps us from writing multi-language apps?
Bookmark this on Delicious
I began my dislike of C early with the insanity called string handling. I was pleased when I found out that Joel agrees with me. Although there are plenty of people who will defend how 'intuitive' the string functions are, I knew there were much simpler ways to manipulate strings as long as you didn't need one larger than 255 characters, in which case using a char* buffer would be fine. Writing apps in something other than C was dismissed offhand with statements like, "C is much closer to the metal", "You don't have the run-time bloat of other languages", or "You have so much more control with C" which almost sounds like a masculinity test or something. Think lumberjacks and "my chainsaw is bigger so only the strongest can use it" type argument. Nowadays, this type of behavior would remind me of The Code Monkey.
Even 2 decades ago, it was possible to call code written in one language to call code written in another; in school we called assembly graphics routines from within Ada code for one class assignment. Notable exceptions are running compiled code from within scripts or executing a system command from within compiled code; but rarely do we write a library in C++ to use in our Java app. When Java first appeared and it was still slow, I never understood the resistance to writing the main app in Java and moving the bottleneck code into some C/C++ dll and called using JNI. It's like we use the "language X sucks at a, b, and c so we can't use it" as a shield that keeps us from having to design multi-language applications.
So, after all these years, what keeps us from writing multi-language apps?
Monday, July 06, 2009
An Apprentice of His Very Own
In my career as a developer, I reached a point where the amount of work that needed to be done was much greater than I had time to do myself. Budget realities aside, there was a lot of coding tasks like writing more unit tests or keeping various diagrams up-to-date that would be tedious but easy to accomplish as long as a basic understanding of development was present. Wouldn't it be nice to be able to afford to hire your own apprentice? Someone maybe still in college who had some exposure to coding but was still wet behind the ears enough to keep quiet and learn by osmosis.
At the time, I had visions of a helper who could take rough UML diagrams, like from scratch paper or from a white-board session, and update the project documentation. As each change came through, they would create new versions and archive old ones like a file clerk from decades ago.
First off, a fresh-from-college developer might consider that type of work as beneath him or her. I'd argue that learning the processes is just as valuable as learning how to code. Did they learn about version control, shared builds or managing a large code-base in school? Of course not, but experience with those types of processes are what most junior developers lack.
Secondly, if your job is consistently repeatable enough to explain to an apprentice, why are you there in the first place? The apprentice is much cheaper and easier to replace. More than likely, you job is one of those ones which is hard to explain because it relies on your experience and training to understand how to approach the problem and the possible/practical solutions.
Usually I stay away from comparing software with construction but in this respect, iron workers have a similar problem: how to bring on new blood without getting anyone hurt or jeopardizing the project. Even the most junior iron worker needs to understand how to do his small part and stay safe. The head iron worker needs to trust that his men won't need explicit instructions for every task and that when a crisis erupts, they'll understand what the priorities are without having to stop and have a meeting.
So, what you end up needing is someone who wants to learn, has the patience to listen, the intelligence to follow directions, the determination to keep doing hard work even when they don't know the importance of their contribution, and the wisdom to understand that not all knowledge comes from a book. The next step is to think about how to carve up your work so someone can help you with it. That will have to wait for another day.
Bookmark this on Delicious
At the time, I had visions of a helper who could take rough UML diagrams, like from scratch paper or from a white-board session, and update the project documentation. As each change came through, they would create new versions and archive old ones like a file clerk from decades ago.
First off, a fresh-from-college developer might consider that type of work as beneath him or her. I'd argue that learning the processes is just as valuable as learning how to code. Did they learn about version control, shared builds or managing a large code-base in school? Of course not, but experience with those types of processes are what most junior developers lack.
Secondly, if your job is consistently repeatable enough to explain to an apprentice, why are you there in the first place? The apprentice is much cheaper and easier to replace. More than likely, you job is one of those ones which is hard to explain because it relies on your experience and training to understand how to approach the problem and the possible/practical solutions.
Usually I stay away from comparing software with construction but in this respect, iron workers have a similar problem: how to bring on new blood without getting anyone hurt or jeopardizing the project. Even the most junior iron worker needs to understand how to do his small part and stay safe. The head iron worker needs to trust that his men won't need explicit instructions for every task and that when a crisis erupts, they'll understand what the priorities are without having to stop and have a meeting.
So, what you end up needing is someone who wants to learn, has the patience to listen, the intelligence to follow directions, the determination to keep doing hard work even when they don't know the importance of their contribution, and the wisdom to understand that not all knowledge comes from a book. The next step is to think about how to carve up your work so someone can help you with it. That will have to wait for another day.
Wednesday, June 24, 2009
What Did You Say?
This says it all. Most of the time research focuses on if new stuff is possible. The real 'Silver Bullet' would be to find a way to solve the communication problem. Click on the image to embiggen.
Wednesday, June 17, 2009
We Have Met The Enemy
In the previous post "Why Extreme Programming Fails"I attempted to shine a light on a dirty little secret of software development. The biggest obstacle was, is, and shall be, the people writing software. Do I condone the 48 Laws of Power, of course not. But to ignore the realities of human behavior in building software would be as foolish as building an elaborate sandcastle on a beach below the high-tide line and expect to hold back the water from destroying all your hard work. Programming is a social activity. See my review of Weinberg's book at http://codewright.blogspot.com/2009/04/programming-as-social-activity.html.
Sun Tzu wrote that you should know yourself and your opponent to have the best chance of victory. Understanding your team is the best place to start to ward off non-technical issues. Admitting that people have hidden motives is not to say those motives are good but to realize how situations should be approached or to understand why a given developer is so hard to work with. The 48 Laws are stated in an almost malevolent way in an effort to illustrate how people act at the extreme. Law #1, "Never Outshine the Master" can be taken either as a command for those who want to curry favor or it can be taken as a reason why a long-time developer may not take it well when showed up on a coding task by a new hire. At their foundation, the laws show behavior issues where ego, mistrust, control, and laziness are the motivations instead of loyalty, honesty, or integrity. We don't have the luxury of assuming everybody in the workforce is on the up-and-up or motivated to do a good job; once we learn that lesson we can begin to steer our own course, taking detours around those who put obstacles in our way instead of being at the mercy of those whose desires are as capricious as they are destructive.
Bookmark this on Delicious
Sun Tzu wrote that you should know yourself and your opponent to have the best chance of victory. Understanding your team is the best place to start to ward off non-technical issues. Admitting that people have hidden motives is not to say those motives are good but to realize how situations should be approached or to understand why a given developer is so hard to work with. The 48 Laws are stated in an almost malevolent way in an effort to illustrate how people act at the extreme. Law #1, "Never Outshine the Master" can be taken either as a command for those who want to curry favor or it can be taken as a reason why a long-time developer may not take it well when showed up on a coding task by a new hire. At their foundation, the laws show behavior issues where ego, mistrust, control, and laziness are the motivations instead of loyalty, honesty, or integrity. We don't have the luxury of assuming everybody in the workforce is on the up-and-up or motivated to do a good job; once we learn that lesson we can begin to steer our own course, taking detours around those who put obstacles in our way instead of being at the mercy of those whose desires are as capricious as they are destructive.
Monday, June 01, 2009
Why Extreme Programming Fails
In the decades of the young life of software development, we've discovered many behaviors, processes, and techniques which have nothing to do with software yet continue to hold back progress. We ask time and time again why the mythical silver bullet is still searched for by those who have already agreed that it is a fools errand. Why are death-marches allowed to form when the futility is obvious to all but the oblivious? Why are proven techniques not mandated by management or agreed to by the workers who constantly complain about the current poor practices? This is true whether we're discussing XP or Agile or SCRUM.
We can use rational thought to decipher the mystery, attempting to achieve clarity. However much success is possible in finding rational explanations, there comes a time when we must recognize the difference between clarity and understanding. We can state things extremely clearly and succinctly and still fail to understand why people continue their unproductive habits or why change is viewed by those in charge with such disdain.
Submitted here for your edification, The 48 Laws of Power.
Why does that developer refuse to pair with someone? There are lots of reasons, i.e. Law #1 - Never Outshine the Master or law #30 - Make your Accomplishments Seem Effortless, are good places to start. Why is Continuous Integration scoffed at? See law #11 - Learn to Keep People Dependent on You
The words 'politics' or 'management' may seem like pejoratives but they serve as simple placeholders for the understanding of human behavior. At their worst, they can be weapons in a Machiavellian conflict while at their best they can be the protective shield against those who see your efforts as a challenge to their plans. Is every use of these laws an instance of plotting and scheming? No, never forget that human nature operates below the level of conscious thought; these behaviors are ancient artifacts used for thousands of years to survive in a violent and irrational world. Disagree with them all you'd like but ignoring them can easily cost you your job.
Bookmark this on Delicious
We can use rational thought to decipher the mystery, attempting to achieve clarity. However much success is possible in finding rational explanations, there comes a time when we must recognize the difference between clarity and understanding. We can state things extremely clearly and succinctly and still fail to understand why people continue their unproductive habits or why change is viewed by those in charge with such disdain.
Submitted here for your edification, The 48 Laws of Power.
Why does that developer refuse to pair with someone? There are lots of reasons, i.e. Law #1 - Never Outshine the Master or law #30 - Make your Accomplishments Seem Effortless, are good places to start. Why is Continuous Integration scoffed at? See law #11 - Learn to Keep People Dependent on You
The words 'politics' or 'management' may seem like pejoratives but they serve as simple placeholders for the understanding of human behavior. At their worst, they can be weapons in a Machiavellian conflict while at their best they can be the protective shield against those who see your efforts as a challenge to their plans. Is every use of these laws an instance of plotting and scheming? No, never forget that human nature operates below the level of conscious thought; these behaviors are ancient artifacts used for thousands of years to survive in a violent and irrational world. Disagree with them all you'd like but ignoring them can easily cost you your job.
Friday, May 22, 2009
The Education of a Codewright
I know one of the first questions is, 'What is a Codewright?' Outside of a programmers editor by the same name, which I've never used, I think of a codewright in the same vein as you might a Shipwright. He is the guy who is in charge of designing a ship and making sure that its construction will be of such a standard that the finished product, a ship, will fulfill the purposes for which it was designed.
The next question is "How does one become a Codewright?" Is it an innate talent improved through practice, or a skill that can be taught? Considering the anecdotes of the genius programmer who never studied as a programmer, let's examine the subject of education; Joel On Software covered the ivory tower with this post about The Perils of Java Schools.
Even though I'm a Java advocate, it might surprise some of you that I actually agree with the premise of Joel's article. I disagree somewhat about Java's role in the problem. The way I see it, Java is a symptom of the disease that the 'JavaSchools' have contracted. I saw the same dichotomy when I was in college which was well before Java was released. Some instructors saw their role as people who prepared you for a job working in the corporate IT shop doing COBOL.
Lucky for us we had a few professors who wanted to make sure we had a grounding in theory and knew how to think through a problem. One in particular would do things like give you a quick hour on the syntax of Ada and the compiler with which he was currently toying and then give you a program and the assignment was to find and fix a bug he would describe. In another class, operating systems, we wrote a program to simulate different task schedulers complete with keeping track of a simulated memory heap and managing the task list like an old time-share system (waiting on i/o, actively running, ready to run, etc.) so we could see the effect of different scheduling policies and their implementation challenges. He wanted us to think, not just regurgitate a pre-digested answer.
This description of a 'JavaSchool' just indicates a school that thinks of itself as a trade-school. While his separation of M.I.T and Duke is appropriate, the Java tag is just unfortunate. There are several other candidate languages that could have had the same fate befall them. This trade-school behavior is evidence that industry doesn't want good programmers, it wants lots and lots of o.k. ones. It isn't much different from the Industrial Revolution changing our high schools during the previous turn of the century from places of learning (anyone learn Latin in H.S. anymore?) to an 'education' factory churning out workers with a mass-produced education that was just enough to get them one of the mass-produced jobs at the burgeoning new mass-production factories.
A Codewright is someone who drives his or her own education and does not rely on someone else to make such decisions. A Codewright is someone who enjoys learning because it means they can do what they love that much better. A Codewright transcends education and explores the world of truth for no other reason than, "because it's there"; anticipating that tidbit of knowledge that will provide the spark of inspiration for the next masterwork, knowing it to be just around the next corner or over the next hill. A Codewright keeps their feet on the ground, always the pragmatist; and their eyes on the stars, always the dreamer.
Lucky for us we had a few professors who wanted to make sure we had a grounding in theory and knew how to think through a problem. One in particular would do things like give you a quick hour on the syntax of Ada and the compiler with which he was currently toying and then give you a program and the assignment was to find and fix a bug he would describe. In another class, operating systems, we wrote a program to simulate different task schedulers complete with keeping track of a simulated memory heap and managing the task list like an old time-share system (waiting on i/o, actively running, ready to run, etc.) so we could see the effect of different scheduling policies and their implementation challenges. He wanted us to think, not just regurgitate a pre-digested answer.
This description of a 'JavaSchool' just indicates a school that thinks of itself as a trade-school. While his separation of M.I.T and Duke is appropriate, the Java tag is just unfortunate. There are several other candidate languages that could have had the same fate befall them. This trade-school behavior is evidence that industry doesn't want good programmers, it wants lots and lots of o.k. ones. It isn't much different from the Industrial Revolution changing our high schools during the previous turn of the century from places of learning (anyone learn Latin in H.S. anymore?) to an 'education' factory churning out workers with a mass-produced education that was just enough to get them one of the mass-produced jobs at the burgeoning new mass-production factories.
A Codewright is someone who drives his or her own education and does not rely on someone else to make such decisions. A Codewright is someone who enjoys learning because it means they can do what they love that much better. A Codewright transcends education and explores the world of truth for no other reason than, "because it's there"; anticipating that tidbit of knowledge that will provide the spark of inspiration for the next masterwork, knowing it to be just around the next corner or over the next hill. A Codewright keeps their feet on the ground, always the pragmatist; and their eyes on the stars, always the dreamer.
Monday, May 11, 2009
The Myth of Code Construction
Ever work with a developer who avoided letting anyone see their code, refused to program in pairs or participate in a code review? They say "This is my code" as if they have sole right of refusal on the final product regardless of who else may be paying the bill.
Great writers still have editors. No matter how great a writer you are, you still have to submit your work to an editor before it will be published. Let's examine the idea of putting code into production as a form of publication.
Before we jump into a new analogy, we should look at the current state of affairs. If engineering were a family construction would be the successful older brother leaving software as the immature younger brother, never quite living up to the accolades of the elder sibling yet endlessly compared nonetheless.
In general, the phases in software are: analysis, design, construction, test, deployment, and training. When you want to build a building of any size, let's use a downtown skyscraper as an example. If we continue the comparison we'd start with analysis which includes many factors like the target location or how many square feet are required. The location can impose limitations to the footprint which then dictates how many floors would be needed to achieve the required square footage. Such trade-offs are examined and decided upon during the design phase. Construction is all about execution with limited opportunity for design changes. How do you test a building, what does that even mean? You might might test the subsystems, like elevators, fire alarms, etc. but how do you test the entire building? The closest we can come in scale might be the opening and closing the retractable roof of an almost complete stadium like the new Cowboy's stadium (this being written in May of 2009). How do you deploy a building? You don't, you open it for business. There is no pull of the lever where what did not exist suddenly does. As for iterations, the closest construction can come is building a new wing on an existing building, adding a room to the house at hand. The cost and effort of remodeling can end up being a significant ratio to the original price of the house.
Now let's discuss a comparison of software development with writing a book. A publisher decides the market is ready for a new book on ant farming. They either have recent submissions by authors interested in writing such a book or they solicit existing authors who have experience in the subject matter. In any event, they request an outline of the book with maybe a sample of one chapter to gauge the material matches what the publish wants. The author or authors work at creating the manuscript all the while knowing that editors will read the book and suggest changes. Editors who are not experts in the content but are experts in the publishing of books. Even the highest-paid authors - Mary Higgins-Clark, Stephen King, or J. K. Rowlings to name a few - will all submit their work to the editors pen.
When the manuscript is complete and the editors happy, there are still other contributors to the final product, researchers, artists, designers, and the like who do things like create illustrations, populate an index, check facts, or plan the visual layout of the chapters. All these activities are coordinated by the publisher who has a target date for when the book will be printed, planning a marketing blitz to coincide with the publish date. Getting the manuscript done is important but still is a small part of the whole effort and if an author cannot produce on time, a lot of investment by the publisher goes to waste; a good way to dissuade the publishing company to find an author who can deliver. The key is that it doesn't have to be perfect but does have to be complete. If there is enough demand, it is easier to publish a new edition rather than hold off on the initial printing. Testing is as easy as a small test run where the final product can be validated by all contributors before scaling up into production-sized runs; images replaced, a new cover chosen, typos fixed. Printing becomes like running the build with a target of production. This means that "build" isn't a phase, it's an activity; unlike any in construction. Deployment becomes a straightforward, if not simple matter, of distributing copies of the book to various retail book-sellers or their distributors.
My suggestion is for the software developers of the world realize that allowing our craft to be constantly compared to the construction industry is to remain the little boy, wanting to live up to the expectations of those who came before, never earning the respect or acceptance they so long for. Look instead to the world of publishing, where writing is still an art and yet the businesspeople have found a way to make money without rejecting the fundamental nature of writing, be that a novel, the latest tech book, why not the latest edition of your favorite word processor?
p.s. Kudos to the wife for the idea.
Bookmark this on Delicious
Great writers still have editors. No matter how great a writer you are, you still have to submit your work to an editor before it will be published. Let's examine the idea of putting code into production as a form of publication.
Before we jump into a new analogy, we should look at the current state of affairs. If engineering were a family construction would be the successful older brother leaving software as the immature younger brother, never quite living up to the accolades of the elder sibling yet endlessly compared nonetheless.
In general, the phases in software are: analysis, design, construction, test, deployment, and training. When you want to build a building of any size, let's use a downtown skyscraper as an example. If we continue the comparison we'd start with analysis which includes many factors like the target location or how many square feet are required. The location can impose limitations to the footprint which then dictates how many floors would be needed to achieve the required square footage. Such trade-offs are examined and decided upon during the design phase. Construction is all about execution with limited opportunity for design changes. How do you test a building, what does that even mean? You might might test the subsystems, like elevators, fire alarms, etc. but how do you test the entire building? The closest we can come in scale might be the opening and closing the retractable roof of an almost complete stadium like the new Cowboy's stadium (this being written in May of 2009). How do you deploy a building? You don't, you open it for business. There is no pull of the lever where what did not exist suddenly does. As for iterations, the closest construction can come is building a new wing on an existing building, adding a room to the house at hand. The cost and effort of remodeling can end up being a significant ratio to the original price of the house.
Now let's discuss a comparison of software development with writing a book. A publisher decides the market is ready for a new book on ant farming. They either have recent submissions by authors interested in writing such a book or they solicit existing authors who have experience in the subject matter. In any event, they request an outline of the book with maybe a sample of one chapter to gauge the material matches what the publish wants. The author or authors work at creating the manuscript all the while knowing that editors will read the book and suggest changes. Editors who are not experts in the content but are experts in the publishing of books. Even the highest-paid authors - Mary Higgins-Clark, Stephen King, or J. K. Rowlings to name a few - will all submit their work to the editors pen.
When the manuscript is complete and the editors happy, there are still other contributors to the final product, researchers, artists, designers, and the like who do things like create illustrations, populate an index, check facts, or plan the visual layout of the chapters. All these activities are coordinated by the publisher who has a target date for when the book will be printed, planning a marketing blitz to coincide with the publish date. Getting the manuscript done is important but still is a small part of the whole effort and if an author cannot produce on time, a lot of investment by the publisher goes to waste; a good way to dissuade the publishing company to find an author who can deliver. The key is that it doesn't have to be perfect but does have to be complete. If there is enough demand, it is easier to publish a new edition rather than hold off on the initial printing. Testing is as easy as a small test run where the final product can be validated by all contributors before scaling up into production-sized runs; images replaced, a new cover chosen, typos fixed. Printing becomes like running the build with a target of production. This means that "build" isn't a phase, it's an activity; unlike any in construction. Deployment becomes a straightforward, if not simple matter, of distributing copies of the book to various retail book-sellers or their distributors.
My suggestion is for the software developers of the world realize that allowing our craft to be constantly compared to the construction industry is to remain the little boy, wanting to live up to the expectations of those who came before, never earning the respect or acceptance they so long for. Look instead to the world of publishing, where writing is still an art and yet the businesspeople have found a way to make money without rejecting the fundamental nature of writing, be that a novel, the latest tech book, why not the latest edition of your favorite word processor?
p.s. Kudos to the wife for the idea.
Wednesday, April 29, 2009
An Estimate By Any Other Name
Terri Vajdi, a colleague of mine, sent me this response to my post on estimating. She always had the most thorough estimates I've seen in my career, so I have a lot of respect for what she has to say.
http://www.apl.jhu.edu/Classes/635431/felikson/Publications/No_Silver_Bullet_Brooks.html
Anyone else have "Estimation Stories" to share?
Bookmark this on Delicious
Since I drill down to assume the details of the requirements when it's missing, I equate this to all the missed requirements to a certain percentage. I read the requirements and try to envision the amount of code, junits, number of iterations, and unit testing for each iteration, Code Review and implementing the changes based on the Code Review, etc...Sometimes I'm too eager and go light on my estimates which would mean even more work later and for which I've been criticized when the unknown issues would crop up and the project would run late. Terri has the right idea. She passed along this link:
So, I come up with an estimate for each of these and then multiply it by the percentage/factor for the missing pieces. Add this the estimate for the missing pieces to my estimate to come up with the estimate that I turn over to my manager. In majority of cases, I break even and come close to the estimate that I have given. Of course, this is with putting a lot of overtime to meet my estimate. Remember we do not live in and ideal world and there are a lot of mishaps. This is just my two cents. Of course, I'm a quality oriented individual and I do not like to revisit my code once it's in Production. I figure that number of iterations after it has gone to Production is very very expensive. I'd rather spent it up front. So far, I've been able to stick to my methodology and have been able to spend my time wisely on other assignments once the code is in Production.
http://www.apl.jhu.edu/
Anyone else have "Estimation Stories" to share?
Thursday, April 23, 2009
Realistic Irrationality
When faced with management's abdication of responsibility for their own decisions, the pragmatic developer will be faced with a decision: to live in the manager's fantasy world, which may involve constantly beating their head against a brick wall or looking for greener pastures, full of craftsmen wanting to deliver software on-time, that works, and is maintainable. This must be closely related to the management style which is unable to prioritize. The hallmark of this occurs during the negotiation desperation of a late project; trying to reign in project scope and attempting to decide which features to cut from the current iteration. When the question is, 'Which features are the highest priority? ' an answer of 'They're all top priority' is not only suspect but probably irrational. The trade offs between better, faster, cheaper are not to be trifled with; this article at softwarereality.com has a good take on the subject. If only this was a tall tale meant to scare young developers; sadly I've experienced this one myself. Feel free to send me your 'Irrational Management' stories, they make good telling at those Agile 'standups' like ghost stories around the campfire...
http://thedailywtf.com/Articles/Deploy!--Deploy!-Deploy!.aspx
Bookmark this on Delicious
http://thedailywtf.com/Articles/Deploy!--Deploy!-Deploy!.aspx
Wednesday, April 15, 2009
In My Estimation
There I was at my first real programming job and my team lead comes by and drops a bomb. "How long will it take to make the change?", he asks. I hope I kept the panic from my face. "Wait a minute!", I was thinking, "Did I miss the class on estimation in college?" No, I didn't. They didn't have one. Hmmm, what do I tell my boss, "sorry, can't help you!", "I have no idea", or even better "they didn't teach that in school"? If I close my eyes and pull a number out of my estimation orifice I could look like a ill-trained idiot programmer by guessing too high or try to please by low-balling it which could easily backfire. Why did I want to be a programmer again, someone remind me. It surely wasn't to look incompetent to a guy that hasn't coded in over 20 years.
Why is estimation still so hard and what are we doing about it?
Bookmark this on Delicious
Why is estimation still so hard and what are we doing about it?
Monday, April 06, 2009
Programming as a Social Activity
What do we imagine when we consider the individual programmer? There are many stories that liken the programmer to the cowboy who finds himself in a small remote town rife with lawlessness and misery. The cowboy grudgingly accepts the job as sheriff, to right wrongs and otherwise do deeds of much heroism; riding off into the sunset, when the crisis has been averted, to the wails of the local townfolk who think they are losing their only defense against the chaos that comes with frontier life. Is this how individual programmers actually work or is this a delusion used to supplicate the ego of socially inadequate developers?
This continues my review of "The Psychology of Computer Programming" by Gerald M. Weinberg. The previous chapter Chapter 3 - How Can We Study Programming discusses the difficulty of studying behaviors which are hard to isolate, repeat, or tranlate into an experimental setting. Chapter 2 - What Makes a Good Program evaluates the subjective and objective criteria for judging programs. The beginning of the series of reviews is Chapter 1 - Reading Programs. Techrepublic.com has a review of the same book which reinforces this book's classic status.
In Part 2 of "The Psychology of Computer Programming", Weinberg describes three different ways that programmers are organized: the group, the team, and the project. Chapter 4 is titled "The Programming Group". He starts with the observation that when programmers work together in the same environment, they inevitably seek each other out for help or advice and expresses the premise that the lone programmer is at a serious disadvantage.
The first lesson is that in any assemblage of people there are formal and informal groups. Formal hierarchies like an organization chart might be nice for the manager types but do not begin to describe the various interactions between individuals in a group. One good story is from back in the batch-scheduled era when it was difficult to know whether your job had run and its output was available, which was accomplished by posted completed jobs on a board outside the computer area. Programmers in remote offices might waste half an hour coming over just to find their results were not ready. As it happened, there was secretary who sat in a location which allowed her to see the result board. When a programmer who was waiting for a job to complete happened to call her for a date. When the conversation turned back to work, she mentioned that he must have work to get back to. He told her that he was waiting for a job to complete. She volunteered that she could see the board from where she was sitting and asked him in which job he was interested. This began an informal service which quickly became known to the outlying programmers. The service became popular enough to disrupt the work of the secretary and need the attention of the administration. Wisely acknowledging that the service could not just be cut off, they decided to implement a sort of job posting hot-line, even using the secretary's original phone number, where a recording would give the latest job completion posting. Here an informal and inefficient solution was replaced with a formal but efficient one.
This contrasts with a second story where a university computing center provided a common room for working on programming problems and an adjoining room with graduate students available to answer questions ("consulting services" was the term used in the book), and at one end of the common area were vending machines. When students complained about the noise from the crowd of students around the vending machines, the administration removed the offending machines. Not long after the removal of the vending machines, another delegation came to the administration with a complaint, there wasn't enough consulting services. As it turns out, the students who were making all the noise were actually discussing their programs and helping each other with them, answering all sorts trivial questions in an informal setting. The administration, unable to believe that the removal of the vending machines was the actual problem tried to increase the number of consultants available with little success as fewer graduate students were willing to deal with the ever increasing number of mundane and trivial problems. The formal solution was not nearly as effective as the old informal one.
Does the environment in which you work affect your productivity? Companies are all about getting the most for the least so it is no surprise that in devising the seating arrangements of programmers, minimum cost usually trumps maximum productivity. There are exceptions like early Microsoft and their "every programmer gets an office with a door" mantra, to more recent examples like Fog Creek, who also take a programmer-first approach. In Weinburg's words,
"Thus, if we are going to attack the problems of making good programs, and if we are going to start at the fundamental level of meeting specifications, we are going to have to do something about the perfectly normal human tendency to believe that ones "own" program is correct in the face of hard physical evidence to the contrary."
This explains the unconscious motivations behind the resistance to code-reviews, pair-programming, or any other effort to get them to loosen their hold on "their" code. If we saw this type of behavior in a toddler, we would immediately recognize it as childish, as in "James doesn't want to share his code with the others." Will James feel like he is losing something if he has to let others play with his code? It would go a long way to explain things I've seen in my programming career.
Why aren't there more groups like this? Weinburg asserts that such groups are not an isolated case. They regard their practices as valuable proprietary information, implying they think other would copy them if given a chance. These groups are very satisfied and stable which reduces the opportunities for programmers to have encountered these groups. Also, gypsy programmers - who never settle in one place - encourage the myth that the best programming is the product of genius, to justify ever-increasing consulting rates.
The last word of this section is on how there is an advantage to making your code as readable as possible for other programmers for that means that those who come after will have a chance to learn from such code without feeling the need to have it deciphered or translated. So, the best code isn't the stuff that is hardest to read but the easiest to read. Easier to test, maintain, understand, and learn from; who could argue with that?
One danger programming environments face is the tendency to fixate or lock into some behavior, habit, or tool. Programming language is a common example. Even if another language is better suited for a problem, the language of choice will be preferred. More people know it, there are more tools available (to the group), more library routines, etc. In other words, it's "how we do things here" which makes choosing a different language like paddling upstream, lots of resistance and little to show for a great deal of effort.
Another fixation is the social environment which either encourages or discourages egoless programming. If the new guy is ridiculed when asking another for help or advice, he is less likely to seek assistance the next time. If, on the other hand, someone pays him the implied compliment by asking him to look over a program, he is more likely to feel secure enough to seek advice.
To understand how programmers perform in a group setting, you must consider formal and informal structures, the physical environment, and even the social interactions in play between members of the group. These are lessons which are still worth learning today. The hard question we must ask ourselves is why we keep searching for new solutions when we have not addressed the issues identified four decades ago. I maintain that the Agile Manifesto or the Manifesto for Software Craftsmanship, is but a few of the efforts to awaken the courage of individual programmers to affect change around them, and cause a groundswell of change which might have the momentum to disturb the inertia of the status-quo.
Sample questions:
For managers: What is your honest opinion of people who are not trying to "move up" in your organization, but who seem satisfied with the kind of work they do and the amount of money they get? To what extent is your view influenced by your own feelings for yourself?
For programmers: Do you refer to your work as "my" program? Try passing one week without using the personal possessive in reference to programs, and take notes on the effects you observe.
p.s - These chapters are large enough that I may break them down so each section is its own post.
Bookmark this on Delicious
This continues my review of "The Psychology of Computer Programming" by Gerald M. Weinberg. The previous chapter Chapter 3 - How Can We Study Programming discusses the difficulty of studying behaviors which are hard to isolate, repeat, or tranlate into an experimental setting. Chapter 2 - What Makes a Good Program evaluates the subjective and objective criteria for judging programs. The beginning of the series of reviews is Chapter 1 - Reading Programs. Techrepublic.com has a review of the same book which reinforces this book's classic status.
In Part 2 of "The Psychology of Computer Programming", Weinberg describes three different ways that programmers are organized: the group, the team, and the project. Chapter 4 is titled "The Programming Group". He starts with the observation that when programmers work together in the same environment, they inevitably seek each other out for help or advice and expresses the premise that the lone programmer is at a serious disadvantage.
Formal and Informal Organization
The first lesson is that in any assemblage of people there are formal and informal groups. Formal hierarchies like an organization chart might be nice for the manager types but do not begin to describe the various interactions between individuals in a group. One good story is from back in the batch-scheduled era when it was difficult to know whether your job had run and its output was available, which was accomplished by posted completed jobs on a board outside the computer area. Programmers in remote offices might waste half an hour coming over just to find their results were not ready. As it happened, there was secretary who sat in a location which allowed her to see the result board. When a programmer who was waiting for a job to complete happened to call her for a date. When the conversation turned back to work, she mentioned that he must have work to get back to. He told her that he was waiting for a job to complete. She volunteered that she could see the board from where she was sitting and asked him in which job he was interested. This began an informal service which quickly became known to the outlying programmers. The service became popular enough to disrupt the work of the secretary and need the attention of the administration. Wisely acknowledging that the service could not just be cut off, they decided to implement a sort of job posting hot-line, even using the secretary's original phone number, where a recording would give the latest job completion posting. Here an informal and inefficient solution was replaced with a formal but efficient one.
This contrasts with a second story where a university computing center provided a common room for working on programming problems and an adjoining room with graduate students available to answer questions ("consulting services" was the term used in the book), and at one end of the common area were vending machines. When students complained about the noise from the crowd of students around the vending machines, the administration removed the offending machines. Not long after the removal of the vending machines, another delegation came to the administration with a complaint, there wasn't enough consulting services. As it turns out, the students who were making all the noise were actually discussing their programs and helping each other with them, answering all sorts trivial questions in an informal setting. The administration, unable to believe that the removal of the vending machines was the actual problem tried to increase the number of consultants available with little success as fewer graduate students were willing to deal with the ever increasing number of mundane and trivial problems. The formal solution was not nearly as effective as the old informal one.
Physical Environment and Social Organization
Does the environment in which you work affect your productivity? Companies are all about getting the most for the least so it is no surprise that in devising the seating arrangements of programmers, minimum cost usually trumps maximum productivity. There are exceptions like early Microsoft and their "every programmer gets an office with a door" mantra, to more recent examples like Fog Creek, who also take a programmer-first approach. In Weinburg's words,
"Someone should definitely study the depressing effect that the all-too-common half partitions have on programmer productivity. They manage to cut off all useful communication while permitting all disturbing sound and movement to penetrate."Another example was the building that replaced the old manual elevator with an automatic one. This was unfortunate for the programmers because the old elevator operator had run an informal pickup and delivery service for them between their floor -- the eighth-- and the machine room -- the basement. They saved the cost of the elevator operator but cost their programmers much time every day going back and forth to the basement of the building.
Error and Ego
"If asked, most programmers would probably say they preferred to work alone in a place where they wouldn't be disturbed by other people"Programmers tend to get invested in the programs they write, attached to them we'll say. This causes behaviors that are counter-productive. What's wrong with "owning" programs, after all artists "own" paintings; authors "own" books; architects "own" buildings. When we go to the bookstore we can get a good idea about the quality of a book if it by a familiar author. Wouldn't the same hold true for programs and their authors?
"The ideas expressed in the preceding paragraph are possibly the most formidable barrier to improved programming that we shall encounter."
"The admiration of individual programmers cannot lead to an emulation of their work, but only to an affectation of their mannerisms. This is the same phenomenon we see in "art colonies," where everyone knows how to look like an artist, but few, if any, know how to paint like one."Another problem with the idea of ownership happens when we start to evaluate or judge a work. Art is to a large degree subjective so the artist can dismiss the opinions of critics. Can a programmer dismiss the judgement of a computer? If we took the "ownership" association to its logical end we would reason something like this:
"This program is defective. This program is part of me, an extension of myself, even carrying my name. I am defective."Obviously that does not happen. Programmers do not quit just because of a single bug or logic flaw but they will tend to overlook problems and strive to prove the program is correct even in the face of mounting evidence to the contrary. Proving the program is wrong turns into a minefield of self-worth where bugs become the buried mines which will injure the pride of the programmer who can't help but react in defense of his own sense of self-worth.
"Thus, if we are going to attack the problems of making good programs, and if we are going to start at the fundamental level of meeting specifications, we are going to have to do something about the perfectly normal human tendency to believe that ones "own" program is correct in the face of hard physical evidence to the contrary."
This explains the unconscious motivations behind the resistance to code-reviews, pair-programming, or any other effort to get them to loosen their hold on "their" code. If we saw this type of behavior in a toddler, we would immediately recognize it as childish, as in "James doesn't want to share his code with the others." Will James feel like he is losing something if he has to let others play with his code? It would go a long way to explain things I've seen in my programming career.
Egoless Programming
So, what do we do? The manager could insist that the coders work harder at finding the bugs in their code. He could even go around and ask them to show him the bugs in their code. Applying even the smallest amount of psychology would tell us that this will backfire. The average person will feel he is on trial and very easily take it personally. If we can change the social environment of the group, we have a chance to affect change in the values of the programmers of that group. This is possible, we know of egoless programming groups since the very early days of programming."John von Neumann himself was perhaps the first programmer to recognize his inadequacies with respect to examination of his own work. Those who knew him have said that he was constantly asserting what a lousy programmer he was, and that he incessantly pushed his programs on other people to read for errors and clumsiness. Yet the common image today of von Neumann is of the unparalleled computing genius--flawless in his every action. And indeed, there can be no doubt of von Neumann's Genius. His very ability to realize his human limitations put him head and shoulders above the average programmer today."Weinburg tells another story of a programmer from the early days of space tracking systems. "Bill" was confident in a loop and gave it to "Marilyn" to informally review, as was common practice in the group. Marilyn found seventeen bugs in only thirteen statements. Bill chalked it up to a 'bad programming day' and became more and more amused as each bug was found. He took it as proof that it just wasn't his day and used the rest of the day giving everyone a laugh at his expense. Marilyn, on the other hand, did not have any false confidence in her own ability and took the code to a third person. She knew that she had looked at it so much she wasn't going to be able to see any more errors. She needed fresh eyes. With others help, she found three more errors before the day was over. The epilogue was that no more errors were found in the code despite diabolical testing and being in production in over a dozen installations even after nine years.
Why aren't there more groups like this? Weinburg asserts that such groups are not an isolated case. They regard their practices as valuable proprietary information, implying they think other would copy them if given a chance. These groups are very satisfied and stable which reduces the opportunities for programmers to have encountered these groups. Also, gypsy programmers - who never settle in one place - encourage the myth that the best programming is the product of genius, to justify ever-increasing consulting rates.
The last word of this section is on how there is an advantage to making your code as readable as possible for other programmers for that means that those who come after will have a chance to learn from such code without feeling the need to have it deciphered or translated. So, the best code isn't the stuff that is hardest to read but the easiest to read. Easier to test, maintain, understand, and learn from; who could argue with that?
Creating and Maintaining the Programming Environment
One danger programming environments face is the tendency to fixate or lock into some behavior, habit, or tool. Programming language is a common example. Even if another language is better suited for a problem, the language of choice will be preferred. More people know it, there are more tools available (to the group), more library routines, etc. In other words, it's "how we do things here" which makes choosing a different language like paddling upstream, lots of resistance and little to show for a great deal of effort.
Another fixation is the social environment which either encourages or discourages egoless programming. If the new guy is ridiculed when asking another for help or advice, he is less likely to seek assistance the next time. If, on the other hand, someone pays him the implied compliment by asking him to look over a program, he is more likely to feel secure enough to seek advice.
"To a large extent, we behave the way we see people behaving around us, so a functioning programming group will tend to socialize new members to its philosophy of programming."On the subject of egoless programming and management, Weinburg astutely describes the culture shear between common management and uncommon programming groups. Remember that this book came out almost 40 years ago; you can draw your own conclusions about how much things have changed.
"Managers tend to select themselves from the 'aggressive' component of society and have difficulty appreciating the fact that other people do not completely share their goals of money and prestige. They are especially at a loss to understand the smooth functioning of a programming group based on mutual respect for individual talent and cooperation in the common cause. Instead, the tend to view people as working for money or under threat -- as they themselves do."Another example given is of a group that was particularly success and producing a new system. The achievement was noticed by the company's management who decided to give them a cash award. Typically, they wanted to give the award to the groups manager but were bewildered when the manager would not accept it unless the whole group got the award. The groups manager understood that the group acted as a team and that responsibility for success could not be attributed to a single individual. Other managers thought he wanted more money, others thought he was trying to setup a "prima donna" group. The company decide to force him to take it and break up the group -- which seemed to have unhealthy ideas. For those doubters out there, I have personally witnessed this same scenario in my career. The moral of the story? Again, Weinburg says it as well as anyone,
"Had the management been more aware of what this group had to offer, and had they been more flexible, they might have worked out a solution that would have permitted this group to influence the work of other groups in a favorable way. But this is not easily done by managers, who tend to feel that when work gets done it is the direct result of the actions of some leader of outstanding ability. Even when the manager appreciates the work of the group, it is not consistent with his own philosophy to see the productivity of the group as a property of the group, not as a sum of the contributions of the individual members."
Summary
To understand how programmers perform in a group setting, you must consider formal and informal structures, the physical environment, and even the social interactions in play between members of the group. These are lessons which are still worth learning today. The hard question we must ask ourselves is why we keep searching for new solutions when we have not addressed the issues identified four decades ago. I maintain that the Agile Manifesto or the Manifesto for Software Craftsmanship, is but a few of the efforts to awaken the courage of individual programmers to affect change around them, and cause a groundswell of change which might have the momentum to disturb the inertia of the status-quo.
Sample questions:
For managers: What is your honest opinion of people who are not trying to "move up" in your organization, but who seem satisfied with the kind of work they do and the amount of money they get? To what extent is your view influenced by your own feelings for yourself?
For programmers: Do you refer to your work as "my" program? Try passing one week without using the personal possessive in reference to programs, and take notes on the effects you observe.
p.s - These chapters are large enough that I may break them down so each section is its own post.
Thursday, March 26, 2009
Risky Words
Taking a break from the book review to post something small but still significant.
Clarity is a very useful tool to manage risk. If something isn’t clear, we’re at risk of getting something wrong. Many times your best risk management tools are your own ears. Nuance in language can be fun when you're flirting with someone at a bar, tossing out double-entendres but when preciseness or clarity is valued, like in requirements specifications, nuance can be a killer.
Bookmark this on Delicious
Clarity is a very useful tool to manage risk. If something isn’t clear, we’re at risk of getting something wrong. Many times your best risk management tools are your own ears. Nuance in language can be fun when you're flirting with someone at a bar, tossing out double-entendres but when preciseness or clarity is valued, like in requirements specifications, nuance can be a killer.
Friday, March 06, 2009
Chapter 3 - How Can We Study Programming?
This is a continuation of the review of Gerald M. Weinberg's book, The Psychology of Computer Programming. The review begins here for Chapter 1 - Reading Programs. The post on Chapter 2 can be found here.
What chance have we to understand the human factor? How do you study programming when the important majority of it takes place between one's ears?
The author tells a story about a student having difficulty with a particular PL/I programming problem:
When it was finished the author asked the student to recall the thought processes -- the difficulties -- he had experienced with this statement, here is that list.
From this single instance of introspection, we could come up with "Laws of Programming"
If your census showed that programmers never nested parentheses more than 5 levels deep, does that mean they are unable to?
Here is a very interesting section where the author describes the costs of conducting experiments on programmers using typical experimental psychology methods. How do you collect data without influencing the results. To a degree it is somewhat like the problem of testing the performance of a program. The modifications necessary to observe the programs use of memory or CPU time actually uses memory and CPU time so how can you know your results haven't been skewed?
You could do experiments using programming majors in school but would the results apply to professionals? You could study professionals but that could be prohibitively expensive. The author describes doing an experiment using one-quarter time of nine experienced programmers for three months. The average salary was $14,000 [I'm assuming annually - ed.], add in overhead (workspace, machine time, etc.) came to $20,000 apiece, or $1250 apiece over the course of the study. Add to that the experimenters salaries and so forth and the bill comes to $30,000 for nine subjects. [In 1970 dollars! - ed.] Using the Inflation Calculator ($30,000 in 1970 compared to 2009) this comes out to a cost of $163,254.90. Serious money, just to study programming.
The answer is that it is expensive to study programmers in groups. Plus, you can't put a number of trainees together and call them a 'team'.
The question is, when will we learn that we are the problem?
This ends Part 1 - Programming as Human Performance. Next up is Part 2 Chapter 4 - Programming as a Social Activity
Bookmark this on Delicious
What chance have we to understand the human factor? How do you study programming when the important majority of it takes place between one's ears?
Perhaps programming is too complex a behavior to be studied and must remain largely a mysterious process.
INTROSPECTION
Although some modern students of human behavior tend to discredit it as nonscientific, introspection has always been the first foundation stone of their science.
The author tells a story about a student having difficulty with a particular PL/I programming problem:
ANGLES(I)=2*ATAND(SQRT((S-A(IND(I,1)))*(S-A(IND(I,2))))/(S*(S-A(IND(I,3))))));
When it was finished the author asked the student to recall the thought processes -- the difficulties -- he had experienced with this statement, here is that list.
- He had trouble getting the parentheses matched, because there were so many of them.
- The original ANGLES(i) was a structure, not an arry, so the compiler complained of an illegal subscript list, but he had not been able to find the problem because there were so many subscript lists.
- When the program finally got into execution, there were these further difficulties:
- IND was a matrix on another page of the listing, and he had trouble finding it.
- Even though the parentheses were now matched, one pair was in the wrong place and was most difficult to find.
- The last difficulty turned out to be a problem of precision caused by capricious declaration of different data types, by the large expression, and by the division--which would not have been necessary if the two-argument form of ATAND had been used.
None of these insights could be obtained without introspection of this sort, yet thousands of programmers [millions now days - ed.] each day have theses same problems and simply grumble that they are having "bugs." Without the introspection, they will simply continue to have "bugs" until, in the end, the bugs will have them.
From this single instance of introspection, we could come up with "Laws of Programming"
- The mind cannot cope with more than five levels of parentheses.
- Compiler diagnostics should be more explicit.
- PL/I precision rules are too complicated to use.
Although each of these statements might turn out to be a "law" in the psychology of programming, writing it on the basis of a single introspective example hardly qualifies it as a law. To be a "law," a principle must be explored so as to set limits to its application, because all laws have limits. Indeed, the limits are Usually more important to know than the laws themselves, and it is only by investigating a multitude of cases that limits can be set. Thus, without introspections, investigation would be sterile, but without investigation, introspection will be of questionable value in application.
OBSERVATION
One way to follow up introspection is by observation of what people actually do, as opposed to what they think they do.Like the study of parentheses and how many levels of nesting programmers use.
One of the problems with observation, however, is that it tells us what people do do, but not necessarily what they can do.
If your census showed that programmers never nested parentheses more than 5 levels deep, does that mean they are unable to?
A second problem with observation is deciding just what it is we are observing.All you know about the programmers who limit themselves to 5 levels of parentheses is a simple fact, to know why they don't use 6 or more would of course require introspection on the programmers part. If you were designing a language, would you limit the size of arrays to three dimensions simply because you've never seen anyone use more?
A third problem with observation is the problem of interference of the observer with the subject being observed.This is called the "Hawthorne Effect". The act of observing workers actually affected their performance, a kind of uncertainty principle.
EXPERIMENT
Here is a very interesting section where the author describes the costs of conducting experiments on programmers using typical experimental psychology methods. How do you collect data without influencing the results. To a degree it is somewhat like the problem of testing the performance of a program. The modifications necessary to observe the programs use of memory or CPU time actually uses memory and CPU time so how can you know your results haven't been skewed?
You could do experiments using programming majors in school but would the results apply to professionals? You could study professionals but that could be prohibitively expensive. The author describes doing an experiment using one-quarter time of nine experienced programmers for three months. The average salary was $14,000 [I'm assuming annually - ed.], add in overhead (workspace, machine time, etc.) came to $20,000 apiece, or $1250 apiece over the course of the study. Add to that the experimenters salaries and so forth and the bill comes to $30,000 for nine subjects. [In 1970 dollars! - ed.] Using the Inflation Calculator ($30,000 in 1970 compared to 2009) this comes out to a cost of $163,254.90. Serious money, just to study programming.
... we must deal with one other problem, which is important because of a seldom-questioned view of programming. That view is that programming is an individual activity, not a social activity.
Not that the individual level is unimportant, but we might start by asking why, if the average programmer spends two-thirds of his time working with other people rather than working alone (yes, it's true!), that 99 percent of the studies have been on individual programmers.
The answer is that it is expensive to study programmers in groups. Plus, you can't put a number of trainees together and call them a 'team'.
Putting a bunch of people to work on the same problem doesn't make them a team--as the sloppy performance in all-star games should teach us.
The neglect of social effects also casts doubt upon all individual studies, since these studies force the individual to separate himself from his normal working environment. In one of our studies, one of the programmers came to me when he had finished coding and asked who could check his work. In his home group, this was standard practice at this point in development, but it was not allowed during the study -- lest it should "invalidate" the results.
Looking back, it seems that forcing programmers to work in isolation is like trying to study the swimming behavior of frogs by cutting off their legs and putting those legs in the water to watch them swim. After all, everyone knows that the frog swims with its legs, so why complicate the experiments with all the rest of the frog?
PSYCHOLOGICAL MEASUREMENT
For the present, most of the work in the psychology of programming is going to have to be "looking for questions."I conjecture that we will move beyond looking for questions only when we start believing and acting on the questions that we've found over the almost 40 years since this book was published. This is definitely not a programming problem. When the software managers are able to dictate practices based on a whim or the local political winds, "We don't have time to do code reviews! Why can't you just make it work? I don't understand why it's constantly breaking!", you might start looking for answers in the abnormal psychology section of the library.
USING BEHAVIORAL SCIENCE DATA
Because of the nature of programming, there is not much hope that actual results can be transferred directly from other fields to ours. Our use of results has to be for insights, not for answers.So maybe all those comparisons with engineering and construction are invalid on the face of it. We might look at Paul Graham's book Hackers and Painters for insight.
Finally, as we pass successfully through all this, we may find ourselves in a sufficiently objective frame of mind to examine some of the myths of programming -- the articles of programming faith. Faith, as Bertrand Russell pointed out, is the belief in something for which there is no evidence; and myths, as Ambrose Bierce once defined them, are the sacred beliefs of other people. Perhaps we shall simply carry away our old beliefs unchanged, but if just one unfounded programming myth should die as a result, this book will have been worth the effort.
SUMMARY
Common pitfalls:
- Using introspection without validation.
- Use of observation on an overly narrow base.
- Observing the wrong variables, or failing to observe the right ones.
- Interfering with the observed phenomenon.
- Generating too much data and not enough information.
- Overly constraining experiments.
- Depending excessively on trainees as subjects.
- Failing to study group effects and group behaviour.
- Measuring what is simple to measure.
- Using unjustified precision.
The question is, when will we learn that we are the problem?
This ends Part 1 - Programming as Human Performance. Next up is Part 2 Chapter 4 - Programming as a Social Activity
Subscribe to:
Posts (Atom)