How To Make Software Projects Fail
Bob Abooey writes: "SoftwareMarketSolution has an interesting interview of Joel Spolsky, of Joel on Software fame. Joel, a former programmer at Microsoft, discusses some of the reasons he thinks some very popular software companies or projects fail, including Netscape, Lotus 123, Borland, etc." This interview brings out some mild boiler-room stories which sound like they could be the basis of a good book, along the lines of Soul of a New Machine .
He says:
"My theory is that this happens because it's harder to read code than to write it."
He couldn't be more right. I've recently been asked to port some code from another group in the company. Upon first reading it, I found global variables being referenced from everywhere, and it looked terrible.
The more I looked at it though, the easier it got to read, and having an existing code base to work from made things much easier.
Plus, when I have problems with it, I can blame it on a "design error" by the previous programmers!
Actually, reading this interview shows how there where serious blunders performed by NS, Borland, etc. In each case, while MS improved their software, the other companies rewrote their software.
There is no longer anything that can be done with computers that is nontrivial and clearly legal. -- Paul Phillips
It is funny how every company he talks about lost to MS. Seriously though, one of the things he does say is:
Fortunately for Microsoft, they did this with parallel teams, and had never stopped working on the old code base, so they had something to ship, making it merely a financial disaster, not a strategic one.
IOW, have more money than God and throw it at any problem you're having trouble with. The minnows in the pond get beaten up by the 800lb gorilla (or something).
or (3), incessantly repeated nerdisms such as "if it was hard to write it should be hard to read" instill an improper sense into young, impressionable programmers.
Potato chips are a by-yourself food.
You may want to check out this article by Robert Cringely: Microsoft's C# Language Might Be the Death of Java, but Sun's the One to Blame.
A lot of truth in that...
I could not justify my existence if I were a turkey farmer. Would I terminate myself? Undoubtably, yes.
With your average application from scratch rewites are probably UnCool for the reasons mentioned in the article.
... the infamous 1 in a million "random" crash, etc.)
...
For other kinds of systems I'm going to have to argue that rewites can be very beneficial.
For systems where the development team has access to a regression test suite and the old (working) code at the same time rewrites are much more easily done. You simply treat the existing code like a prototype. Something that captures all of your requirements, but maybe not using a design that ended up working out (read as: turned into a freaking hairball as time passed!) You work through the old code, understand it, and then build up a new design that works out cleanly in all of the places where the old code was a hack.
When you are all done (or as you are working), you hit it with the test suite. This works out best if your process requires that all of those pesky little bugs found in the old code had to have test cases to reproduce them. (Obvisouly there are limits to this
Anyway, I think Joel's statement was just a little to broad. He's correct in some cases, but not all. Of course maybe I'm just one of those overly confident coder types
"There's no secret. You just press the accelerator to the floor and keep turning left." -- Bill Vukovich
This leads to a whole host of problems:
Many of them tend think they're smarter than people in non-engineering roles.
Pursuant to this, they don't think PR and marketing and sales are "hard" or really even "important".
Again after #1, they're always right when in disagreement with marketing or sales guys.
Most of them haven't developed in a decade+, so now they know just enough to be dangerous -- make micromanaging decisions about detailed subjects things they don't understand well enough, chase unnecessarily after bleeding edge tech, etc.
Fail to understand that not everyone wants to always work 14 hours a day.
Laugh off meetings, so that eventually nobody in the company knows whats going on.
As a result, nobody's heard of us (no marketing budget, no trade shows, no nothing) and nobody's buying our products (engineers tend to make lousy sales guys; despite what they might believe, nobody wants to listen to a 3-hour ridiculously detailed presentation on your product).
There's got to be a happy medium someplace.
Every year during my review, I just pray the words "slashdot.org" aren't mentioned.
Just a correction to a point raised in the interview:
Netscape made the "single worst strategic mistake that any software company can make" by deciding to rewrite their code from scratch.
Netscape didn't rewrite the browser from scratch. Back in April 1998, Communicator 4 was the current version; to get from there to the open-source Mozilla browser, everything that couldn't be distributed (code from other companies, and security code with export restrictions) was stripped out of the source code. What was left was made available as the start of Mozilla. It didn't even compile at first, but Mozilla didn't start from scratch.
Admittedly, the fact that this next-generation browser hardly worked at all for more than three years did keep Netscape from capturing any market share, but the browser had already been commoditized, and the battle had already been lost.
I think that the real browser battle is yet to come -- when the bulletproof and iron-clad Mozilla, carefully fine-tuned to scratch every developer's personal itch, is finally ready sometime next year to take on whatever Microsoft has got. I think that's when the real interesting things will happen -- not just on the technical and marketing fronts, but also on the legal front, as Microsoft finds ways to make sure Mozilla isn't a threat...
No, I'm not cynical. Honest.
Use 'slashdot stuff' in the subject line in any email you send me if you want to get past the spam filter.
I'll agree with your other points, but this:
Copious Comments - Lots of comments, clearly written and explanatory. [...] The best comment I heard was from a friend about a former coworkers code: "It's English with some C++ thrown inbetween the comments."
is nonsense. If your code isn't written well enough to make it obvious to another programmer what it does, then no amount of documentation will help the poor sop who comes along after you and has to maintain your code. Programming languages are just that--languages--and can be used to express concepts just as well (better, in some cases) than human languages. For example, if I see:
then it's perfectly obvious that it's freeing the contents of an array; I don't need you to tell me so in a comment, and in fact if you do, it gets in the way. As one of my university professors said, "Use comments to tell me something I don't know."Comments are good things, of course--used sparingly. But there is such a thing as "too much of a good thing."
I agree with the spririt of what he is saying - often the "rewrite" is an ego thing - one programmer wanting to write his code instead of reading someone else's, but there is no doubt that most serious professional programmers have looked at code that simply needs to be thrown away.
And this is the difference between academic code and commercial code. Ever looked at 90% of the research projects from graduate students? Most of them barely work, or only work on one specific set of hardware (and not anything else), or require a huge set of work-arounds to get the code up and running. The reason for this is because this is theoretical work. It doesn't matter how well it works (well, unless your thesis is on optimization, but that's different), only that it works well enough to demonstrate your research. Commercial software is the complete opposite. It has to work, and work well, on many different configurations of hardware, and many different versions of software (Windows 95 vs 98 vs 98se vs ME vs XP, Windows NT4 vs 2K vs XP, Mac OS 7.x vs 8.x vs 9.x vs OS X, and so on), or your potential customers aren't going to buy it.
You didn't read the interview, did you? One of the main points in there was that by throwing away your old code and re-writing from scratch, you're throwing away years of experience and bug fixes. To use the example he gave of the nasty function that was supposed to do something simple but had a whole bunch of seemingly useless extra crap in it, the point was that all those extra little things that you'd throw away in a rewrite were necessary bug fixes. You throw them away, and unless you wrote those bugfixes in the first place (not likely, and even if you did, not likely you would remember), you lose all that information. That means that your new, "cleaner" version is very likely going to have similar bugs. Perhaps even the same bugs you fixed in your older, crufty code. Rewriting your code from the ground up is not focusing on "quality" (it may be focusing on "quality of code", which is a pretty useless standard so long as your code is proprietary), but instead focusing on "triviality". The bottom line is that in business (any business, not just the software development business), the bottom line is what's important. If you don't like that, stick to academia. You'll be happier there, and your potential peers in the commercial arena will be happier having you there.
Irrelevant red herring, and a bad example to boot. You're equating a potentially dangerous situation (in your example, less solder means a less solid joint, which means the oil could leak) with a harmless situation (reusing your old code, crufty as it is). In one case you're making a conscious decision to be less safe, while in the other you're making a conscious decision to leverage the work that's already been done.
As I said, I don't think you read the article. If it makes financial sense (you will sell enough copies to recoup your extra development cost and extended time to market), then there's nothing wrong with re-writing code (though Joel did suggest looking at the old codebase while writing the new, so that you won't miss any of those one-off bug fixes that are neccessary but are also the source of the cruft). The problem is that it rarely makes much sense. Especially when you're in a competitive market (as all the examples he gave were -- when you're competing against Microsoft, the worst possible thing you can do is be more concerned about code quality than making a featureful, useable product that's available quickly).
Make me something that doesn't suck,and I'll pay for it, don't force me to upgrade every 20 minutes to a more bloated piece of crap...
Unfortunately, if I write software that doesn't suck, doesn't need patches, and does what you want, you'll buy one copy (Netware 3, WinZip, Eudora) and in 2 years I'll be bankrupt.
If I write software with tons of broken features and requiring constant upgrades for 'compatibility' and security (SAP, QuickBooks, and Windows 95), I'm guaranteed plenty of repeat customers.
Now if you'll excuse me, I need to go buy a $100 ink cartridge for my $30 printer.
I agree with you that sometimes the design is fundamentally, intrinsically flawed and needs to be thown out; but more often times you can revise and evolve code.
As far as Microsoft redesigning the OS with NT:
Microsoft is one of the few companies who can afford, financially, to have parallel development teams. When Microsoft started building NT they had help in funding the development because IBM was helping them (remember that NT started out of the OS/2 project that Microsoft was working on with IBM). And later on they had made such a fortune on Win95 + Office 95/97 that they had more than enough money to fund parallel development.
Microsoft realized that, at least in the early versions of NT, normal users would have a hard time administering NT and running a lot of the programs they wanted to use under NT. That is why they paid developers to keep developing Win9X/ME, EVEN AFTER they decided to redesign the OS. I would say that Win2k Pro is the first version of NT that most users would have no more problems with than if they were using Win9x.
Since most companies can't afford to keep parallel development teams in order to maintain the old product until the new product is "ready" for all their users, it usually (though not always, I think) makes more sense financially to try to evolve and revise the current code base.
Point 2: Microsoft IS, in most cases, following exactly the strategy that Joel outlines. Take Internet Explorer for example. Up until IE4, IE just plain sucked as a browser. Microsoft kept revising/evolving it though; With 4 it still had lots of annoying things about it, but was generally usable. With 5.x they fixed more bugs, got a lot of things working fairly well (of course, there were still some things that were annoying about it, especially from a web developers' perspective, like a bad implementation of Cascading Style Sheets, which still isn't quite right (but I'd hasten to add that Netscape 4.x's implementation of CSS is much worse; sometimes valid CSS would CRASH some of the 4.x browsers). Now they've released IE 6. Still not perfect, but adequate and productive for most users. The point of my writing about IE like this is that Microsoft has been able to, relatively quickly, revise their browser, whereas Mozilla/Netscape6 has basically become really useable only in the last 4 months or so (here's where I point out that I'm composing this in Mozilla under Linux).
So, I'd say that Joel's point is somewhat valid, and that Microsoft, in fact, does follow his logic, in most cases (Office, SQL Server/BackOffice, IE, etc).
>why are we listening to this guy?
Um.. possibly because this guy has a better track record that *you* do when it comes to pushing out reasonable quality *commercial* software, and on time?
Isn't there sometimes a happy medium between completely rewriting the whole codebase and continuing to hack it up?
This happy medium is described well by Bruce Eckel in Thinking in C++. He says in the chapter on design (paraphrased): "don't worry that getting some aspects of a design wrong will mean you have to rewrite everything. You won't - properly-written classes shield you from your mistakes." This is from the section that talks about the problems that occur early on in implementation, but applies equally to rewrites.
For example, maybe you can identify certain modules that can be isolated and rewritten, then tested rigorously against the old code to make sure they're functionally identical.
This is called refactoring and is now a widely-accepted industry standard practice for improving a codebase without rewriting it from scratch. The official web site is here.
--- Hot Shot City is particularly good.
No one seems to be taking up this position in their replies to you, so I'll give it a try...
Maybe NT really was a mistake. Maybe Microsoft would be even richer if they had just kept evolving Win9x and let it accrete more features.
Did Microsoft really gain anything from NT? I don't mean gain things that important to geeks (reliability, performance, cleanliness, etc), I mean gain anything that is important to being commercially successful.
Name one feature that NT has and 9x doesn't, which has resulted in increased revenue for Microsoft.
As copyright owner of this comment, I authorize everyone to defeat any technological measure which limits access to it.
> IOW, have more money than God and throw it at any problem you're having trouble with
Didn't work for IBM in the early 90's, didn't work for Detroit in the late 70's and early 80's, still doesn't work for the government.
I've finally had it: until slashdot gets article moderation, I am not coming back.
My God. So this is what Microsoft code looks like? It's a miracle it can be maintained at all. This sounds like sloppy coding by trial-and-error, at its worst. Code filled with "ugly little hairs and stuff" that "nobody knows why" is almost a guaranteed recipe for buggy, unstable code. If all these "bug fixes" were properly commented to begin with there would be no argument as to why they should be kept. Thank God for open source, where programmers are _proud_ to show off their code (well, a lot of them, anyway).
I would attribute the successfulness of Microsoft, and the failure of others, to factors other than the quality of its code.
Excellent point. My philosophy about commercial software is this:
Never forget why you're writing the code to begin with. The point is to get working, stable code out the door as fast as possible. Anything that does not accomplish this is a waste of time.
Doing your architecture work is fine, but do it on a whiteboard in your cube with your co-workers. Don't waste time holding formal design meetings and drafting useless documentation and diagrams because, honestly, nobody will ever read them.
Modularize/componentize your code as much as possible. Document what the module as a whole does and what data it requires and what data it returns . You shouldn't have to waste time commenting every single peice of code. If you''ve modularized and documented what the module does, any decent programmer can figure out the rest.
In addition to not hiring idiots, don't hire people who love to wallow in bureaucracy and process. Besides not getting jack shit done, they impede everybody else.
If you want to comment and spend hours drawing Visio diagrams, fine. Wait until after the product is released to do this. These do not accomplish the goal (see point #1).
Chris
You're utterly off the mark if you think you're going to provoke me into some Randroid rant in support of capitalism uber alles. Fact is, you know damn well as much as I do that the government does some things well, but other things it throws enormous sums of cash at are still extremely ineffective. You'll note I mentioned other behemoths that lumbered about throwing good money after bad, not just governments.
> The internet? Highways? Electric power (which failed privately)?
Show me a government owned power company in the USA. Regulation is not ownership, much (not all) of it comes because the monopoly was government-enforced in the first place, so they now have to control it. I work in a social service nonprofit, housing comes to mind as something the government consistently screws up (all the effective housing programs here are other nonprofits that don't receive government funds). This is all of course US-centric -- other nations governments might do some of these things well. It just further demonstrates that having the money does not mean it gets spent wisely in every case, which is the point you seem to be trying to sidetrack me from.
I've finally had it: until slashdot gets article moderation, I am not coming back.
[1st and foremost: I use and support Microsoft products. The software and OS's work "OK". No further explanation or flaming is necessary.]
Everything this guy says tells programmers to consider the bottom line, the almighty dollar. This attitude works in other industries, but will eventually bite them in the ass. (Automotive anyone?)
He's actually giving us the directions on how to beating MS. So, if you are producing such and are in this to make a fortune today instead of tomorrow... take notes they will be invaluable... for the near future.
However, we all know this is the worst advice for those of us who use and program open source software. We want simple code. We want it to do just the basics. If it's too basic for you, here's the code, feel free to add to it.
Remember the automotive industry? Japan (and Germany) started out with simple basic cars and trucks. And the typical American car buyer? "They're so small, so plain and slow." Hmmm, now these little 4-cylinders are blowing the doors off of the bigger American cars. Because each time they built their cars, they started out simple and refined each part before they added on.
MS is winning today, but soon people will like their programs and OS's like they demnd their cars now, reliable and economical. It will happen, but how long will it take?
Let's compare:
...assuming they are English speakers of course. Proof? I have programmed (I don't count the BASIC years) for ~10 years. I have been writing/speaking English for over twice that long. Which do you think I'm better at?
for (i = 0; i array_size; i++)
free(array[i]);
free(array);
and now let's look at:
// get rid of the array
for (i = 0; i array_size; i++)
free(array[i]);
free(array);
Has your life *really* been so harmed? Is this *really* so terrible? Comments should not be written with the thought that your university professor would know what everything else means. Comments should be written so that all of those folks without a PhD in CompSci. know what it means.
What if the next joe to hit your code doesn't have a degree? What if the recently-hired intern was just handed a "C in 21 days" book and told by the manager to "fix it" because the programming team is snowed in (or similarly unavailable) and the customer is screaming? (Yeah, try and tell me that's never happened...)
A fine use of comments is (for example) every ten lines to say, in general, what is going on. One thing I used to do is write a comment at least every 10-15 lines. Why? When the next joe who comes along has to read/edit my code, scanning through some periodically placed comments will *always* be quicker and easier than reading the code.
The code effectively shows my implementation, but may not show my intention. I have coded for years. I started dreaming in code several years ago. Shortly thereafter, the code actually worked when I typed it in the next morning. That isn't the point. How good a coder you are isn't the point.
When you have a hundred thousand lines of code to go through, comments become like "Cliff's Notes." For the quick patch (probably the majority of code being written by most people), comments are invaluable. Who cares if I didn't read Moby Dick if I can still pass the pop quiz? If I need to make an indepth study, I can still do this, but thank god for the "Cliff's Notes."
Now then, on to the "proper" use of comments.
1. Write out what you are planning to do in English. (or whatever else may be the dominant language in your development group) Fill in every step in the problem. This is NOT psuedo code. This is akin to: Find out who www.yahoo.com is, open a connection, ask for the main page, and check to see if our cache is still valid. If the cache is stale (the yahoo page has been updated), get a new copy of the main page. If the cache is still valid, pull the page from cache instead. Drop the page into the "ready" bin and send a message to the user that the page is here.
2. Make a copy and label it "documentation."
3. Go back to the original, fill in all of the logic in whatever programming language at the appropriate points in your "documentation," and label it "source file."
This means that your documentation is done, your code is adequately commented, and your algorithm and intent(!) are clearly defined for both your co-workers (and yourself when you have to fix something ten months from now). If you can't spell out the problem and the solution in your primary native language, you sure as hell better not be trying to spell it out in a programming language that members of your team have only been using for two years.
The only excuse not to do the above is laziness. For some people, laziness is not considered a bad thing. It was noted as being one of the main virtues of a hacker -- hubris, laziness, and impatience. Hell, according to this measure, I myself am lazy from time to time. But cut the bravado, the beating of the chest, the battle cries of "I'm smart enough to figure this out, so should you be," and call a spade a spade. Avoiding comments means that you are being lazy.
- I don't need to go outside, my CRT tan'll do me just fine.
while the POSIX system is just there as an afterthought
That is being generous. It is my personal opinion that Microsoft only included the POSIX subsystem in order to be "checklist compliant" to bid on government and commercial contracts that require POSIX compliance. Furthering my suspicions, they basically made the POSIX subsystem more or less useless by crippling it, and making it virtually impossible to run POSIX applications and Windows applications at the same time in any sort of useful manner. So bad was the POSIX subsystem that Interix and Cygwin were created to replace it as well as numerous other porting tools (WindU, MainWin), etc. Microsoft has since borgified Interix in order to make sure it never becomes any sort of serious way to wean Windows users off to other OSes. They want it to only be a one-way street.
Nope.
The right solution, which many would take if doing it again today, is to do it all in Unicode.
My Karma: ran over your Dogma
StrawberryFrog
People should try putting some damn comments in.
Early on in my programming career, I was looking at such a piece of code - something which was simple when first written (in C) 5 years previously, but had so many mods, the function was pushing 1000 lines (ugh). Some guy had put in this change, commented it as "for performance improvement", then commented it out with an extra comment explaining that it was taken out because it didn't work. At the time I thought "why is this guy making himself look like a dick?". Later I got it - he'd left it like that just to stop some other poor bastard making the same mistake (it was a calculation thing which we were always pushed to improve performance).
If you do something wierd or clever, for f*ck's sake put a comment in (do as I say, nbot as I do).
This sig made only from recycled ASCII
char *strcpy(char *dest, const char *src);
much easier to read than the Windows-style Help which is full of stuff like "LPCSTR lpBuf" and suchlike. The idea which is commonly called "Hungarian Notation" says that a variable name should include the type of the variable as a prefixed abbreviation in front of the name. This leads to stuff like:
byte[] baBuf;
whereas without Hungarian, it might be called:
byte[] message;
which would be much more meaningful.
Especially in object-oriented programming, the type of a variable is the least important piece of information about the variable, and has no place being abbreviated and prefixed to the name. The most important thing about a variable is what the programmer is using the variable for, and that information should be what the name of the variable tells another programmer. If somebody really wants to know the type of a variable, then their editor or IDE should tell them what it is. If it doesn't tell them automatically, then they should look at the variable declaration, which will state exactly what type the variable is. If programmers want the variable name to tell them the type, then what is the point of declarations? And why bother putting a comment near the declaration saying what the variable is for, because people aren't going to read the declaration or comment anyway, because they are just going to look at the Hungarian warts.
The argument that Hungarian notation reduces the possibility of assigning variables of different type to each other is long dead with compilers well capable of throwing errors if any incompatible type assignments are attended. I think that Hungarian notation is dead, or at least should be.
...
After the product is released, nobody will allow you the time you'd need to write comments or user documentation or Visio diagrams. The only effective way to produce documentation and commented code is to generate it as you go along.
I'm surprised you haven't yet been modded down as a Troll, you are so far off-base. See Dave Parnas' "Software Fundamentals" for a detailed exposition of why your approach is wrong, wrong, wrong.
Your objective should be to get working, stable, maintainable, supportable code out of the door. This means it's commented and documented (and, yes, diagrams count as documentation). If you fail to do this, you're failing your users and (ultimately) your company.
Dude, think about what you are saying. Do you want to keep maintaining your old crappy code or pass that job onto someone else? Or do you want to go write some new code?
Your perspective assumes your company requires a fixed amount of software. Think more imaginatively.
Better documentation means you can shove maintenance to a more junior programmer with less pushback.
Also, without good documentation, its a b*tch to try to outsource/handoff pieces of the code you don't want to bother writing.
Besides, I don't care how well documented your code is, you should always be able to convince a boss that its more efficient for you to make changes to it (even at higher salary) than some cheaper guy who has never seen the code before.
--LP
Ed Yourdon wrote a book a couple of years entitled "Death March: The Complete Software Developer's Guide to Surviving 'Mission Impossible' Projects".
Whenever I hear of a software project failing, I think of this book because it explains in gory details what happens when software is treated like fast food instead of architecture.
When Joel Spolsky gripes about "re-writing" as the cause to failure, he's both right and wrong at the same time. Rewrites don't kill projects, MISMANGED rewrites kill projects.
There are some other points that raise my suspicious about Spolsky's training and experience. Since the 90's, there has been a big effort in the industry to develop large scale products with some semblance of reuse. Hence, one of the determinat reasons for the lurch into object oriented program.
Spolsky descriptions sound to me like he's still thinking of code, and of failed projects that were lacked modularity. Nor did he give much attention to other major factors such as FEATURE CREEP, where a small system becomes spagetti over years and years of maintenance. Same with scalability, challenges definately occured in the past decade or so with the massive changes in processors, operating systems and their associated APIs/internals.
But again, it all gets down to one's approach. If you treat software development like you're flipping burgers for the lunch crowd, then you're going to have to deal with the indigestion that comes along with building a house sloppily.
healyourchurchwebsite.com - WWJB?