If you ask a software developer what they spend their time doing, they'll tell you that they spend most of their time writing code.
However, if you actually observe what software developers spend their time doing, you'll find that they spend most of their time trying to understand code:
Peter Hallam explains:
Why is 5x more time spent modifying code than writing new code? New code becomes old code almost instantly. Write some new code. Go for coffee. All of sudden you've got old code. Brand spanking new code reflects at most only the initial design however most design doesn't happen up front. Most development projects use the iterative development methodology. Design, code, test, repeat. Repeat a lot. Only the coding in the first iteration qualifies as all new code. After the first iteration coding quickly shifts to be more and more modifying rather than new coding. Also, almost all code changes made while bug fixing falls into the modifying code category. Look at [the Visual Studio development team]; our stabilization (aka bug fixing) milestones are as long as our new feature milestones. Modifying code consumes much more of a professional developer's time than writing new code.Why is 3x more time spend understanding code than modifying code? Before modifying code, you must first understand what it does. This is true of any refactoring of existing code - you must understand the behavior of the code so that you can guarantee that the refactoring didn't change anything unintended. When debugging, much more time is spent understanding the problem than actually fixing it. Once you've fixed the problem, you need to understand the new code to ensure that the fix was valid. Even when writing new code, you never start from scratch. You'll be calling existing code to do most of your work. Either user written code or a library supplied by Microsoft, or a third party for which no source is available. Before calling this existing code you must understand it in precise detail. When writing my first XML enabled app, I spent much more time figuring out the details of the XML class libraries than I did actually writing code. When adding new features you must understand the existing features so that you can reuse where appropriate. Understanding code is by far the activity at which professional developers spend most of their time.
I think the way most developers "understand" code is to rewrite it. Joel thinks rewriting code is always a bad idea. I'm not so sure it's that cut and dried. According to The Universe in a Nutshell, here's what was written on Richard Feynman's blackboard at the time of his death:
What I cannot create, I do not understand.
It's not that developers want to rewrite everything; it's that very few developers are smart enough to understand code without rewriting it. And as much as I believe in the virtue of reading code, I'm convinced that the only way to get better at writing code is to write code. Lots of it. Good, bad, and everything in between. Nobody wants developers to reinvent the wheel (again), but reading about how a wheel works is a poor substitute for the experience of driving around on a few wheels of your own creation.
Understanding someone else's code-- really comprehending how it all fits together-- takes a herculean amount of mental effort. And, even then, is source code truly the best way to understand an application? After reading Nate Comb's thought provoking blog entry, I wonder:
Would Martians wishing to understand the rules of the World of Warcraft (WoW) be better off trying to read its source code or watching video of millions of hours of screen capture?The challenge of Reginald's interview question is this: "If someone were to read the source code, do you think they could learn how to play [Monopoly]?"
In some ways this challenge hints of the reward of "downhill synthesis" over an "uphill analysis": who really knows what the rules of WoW are except by grace of the analysis of a million fan websites and trial and error. Do the developers really know?
I've worked on plenty of applications where, even with the crutch of source code I wrote myself, I had trouble explaining exactly how the application works. Imagine how difficult that explanation becomes with three, five, or twenty developers involved.
Does the source code really tell the story of the application? I'm not so sure. Maybe the best way to understand an application is, paradoxically, to ignore the source code altogether. If you want to know how the application really works, observe carefully how users use it. Then go write your own version.
I think also a lot of developers feel that they can create cleaner code by rewriting. When you refactor code it still smells of the old code for a long time, and it takes a lot of work to clean that smell out.
I think Joel is right, it's stupid to re-write the entire thing. But then there are different ways and mentalities of rewriting.
I've "rewritten" several medium sized applications by starting a new project, copying and pasting chunks of code from the old application, reordering and rewriting bits. It could be argued I was rewriting it, but in fact it was just a method of refactoring. A method of refactoring that leaves less of the old smell.
I was still re-learning what the code did. Sometimes by reading carefuly the code, and sometimes by observing the functionality. But I think I would have to agree with Joel, I've never "rewritten" a mature program, something with lots of bug fixes from lots of people. You have to really understand the code and what the strange bug fixes are in order to think about how you can rework the code to include those fixes logically, rather than attatched on the end. And if you can't work that out, then I guess it's probably best to leave it.
[ICR] on September 21, 2006 2:11 AMI find that well written unit tests help to understand code. What is the code doing? Well what does the programmer expect it to do? A test will tell you. Of course, you then need to understand the test.
Haacked on September 21, 2006 2:42 AMThis is where test infection pays off. Want to learn the rules of monopoly? At a minimum the tests should cover the basic rules, and makes it a lot easier to understand the outward-facing aspects, and ignore the internal details for the most part. Have a case that isn't covered in a test? Write a new one, if it doesn't pass, then you need to dig into internals.
I definitely agree that tests should play a big part of this. But like Simon, I agree that tests aren't a silver bullet for understanding. Since most code has *zero* tests, this may be a moot point. Starting by adding some tests is a capital idea.
One of my bosses/mentors once told me that the best programmers are maintenance programmers; not because its glamorous but because its hard.
Sure, I've talked about this before..
http://www.codinghorror.com/blog/archives/000610.html
Jeff Atwood on September 21, 2006 3:20 AMJoel doesn't say you should never rewrite. He just says don't rewrite from scratch. There's a continuum of combinations of reading and writing code:
a) throwing it all away and rewriting from scratch
b) global refactoring
c) writing small throwaway code chunks to help understand a large codebase
d) understanding by reading, say using a debugger
e) nodding off staring at the code, trying to understand by osmosis
Joel says only that a) is a bad idea.
Kartik Agaram on September 21, 2006 3:23 AMRewrites are usually a guise for I want to add programming language X to my resume, so lets rewrite this component in language X, although in some cases technology has evolved which dictates a major change.
Back when I was mostly a VB.NET programmer, I had to manually convert any C# code that I wanted to integrate into my code base. It wasn't a meaningful conversion, but doing the C# - VB.NET conversion forced me to look very closely at the code I was adding. I'd often add features or refactor the code as I went; it was rarely a straight port by the time I was through.
Now that I'm officially language agnostic, I miss that a little bit.
Jeff Atwood on September 21, 2006 3:25 AMyeah ...great post.
I thought you had a great point when you spoke about WoW... Similarly if you can get to pair with somebody who has written the code(i understand thats not always possible) ... on some of the features/bugs which you understand. That for me is the fastest way of understanding the app.
Kay on September 21, 2006 3:27 AMan old canard: if civil engineers built bridges the way software engineers build applications, they (bridges) would all fall down in a month.
the point, of course, is that software engineering, after 50 years, still has little in common with real engineering (sorry about your feelings). we insist on doing it different just because we want to. and because platforms change along the way. and there are few rules to guide us. code is hard to understand because it doesn't obey a few basic laws; there is no Newton in this melieu.
OTOH, if one is a mainframe COBOL coder, nothing much has changed in 40 years; they're still writing another General Ledger just like the first one.
there are really few innovations in the 5 decades: disc drives, RS-232, relational databases, VVVVLSI, GUI. fact is, java/vb/smalltalk/foobar coders view data much as COBOL-ers did and do. there still a lot of batch programmers out here; most don't know since they see objects as different from file records. would that it were so.
one my favorite quotes:
It's easier to understand 600 tables than 100,000 lines of code.
-- PaulC[on comp.databases.theory]/2005
such is the path out of darkness. take it.
I think we need some better UML style tools so we can get a "birds eye view" of code more. A big part of my time is spent rewritting code that was poorly designed in the first place ( by me ). That's because is hard to design it correctly up front, rather you take a stab at it and improve it bit by bit.
OmegaSupreme on September 21, 2006 4:39 AMI don't rewrite source code, I edit my additions into it for probing.
Zingus on September 21, 2006 5:46 AM"What I cannot create, I do not understand."
By all accounts Feynman was brilliant, but perhaps in his last days he went a bit... ga-ga. Not quite the whole up quark, if you know what I mean. Even for an academic it's unusual to completely disregard resourcing constraints in the way the above quote does. Since Jeff Atwood seems to have made the same mistake as Feynman, he can at least take comfort that great minds omit alike. :-)
And resources, or lack thereof, are the pivotal player in this analyse/hypothesise dilemma.
As a developer you want to get to the solution with least cost and greatest quality that you can.
When you're faced with a significant learning curve in understanding old code (or a new technology) versus the time it takes to hypothesise a behaviour and reinvent your own wheel to test it, it's an economic decision. Analysing existing code takes time, but it offers greater accuracy and quality. Building your own in a quick and dirty manner saves time, but it doesn't tell you any of the details of the original.
There is no magic bullet universal answer to this. You can't reliably fix bugs without understanding the source because it may happen at a level of abstraction invisible to the program's clients. Maybe you don't have the source.
Usually you won't have the luxury of choice in this issue. If you do, it's a matter of judgement to decide case-by-case as to which alternative is best - a decision influenced by effort estimates, skill, deadlines, availability of test environments, and bunch of other _resource_ constraints.
Understanding is *the* fundamental problem of code maintenance, both for the developer and any other hapless soul who must follow in his footsteps.
For anyone who must maintain, or even rewrite a component, an invaluable resource is what I call a POPS (principles of operation) document, generally a text file a couple of pages long which describes briefly how the component works, and items such as what it connects to, what it persists, its states, and especially debugging tips. There are no rules except to try to be helpful to anyone reading unfamiliar code, especially someone debugging in that area.
I have found that time spent writing these is well repaid.
Geo on September 21, 2006 6:28 AMUnderstanding code is definitely the hardest job for a coder, I agree. We might write our own code, then 1000 lines later, realize that we need to go back and change was we previously wrote, and forget how we implemented something! Or, even worse, we're told to update code that somebody else, who has a different understanding and style of coding that you do (more than likely), has written.
Of course, this is why encapsulation is a beautiful thing. Designate a class or function to do one particular thing, that way when you go to the function to understand it (hopefully with comments to help), you know that it's supposed to perform one task. What probably mades the task of understanding a huge amount of code, in my opinion, is going through hundreds or even thousands of lines of code and trying put get all the puzzle pieces put together in your head without losing any of them.
If you're writing new code, yeah, at least 50% of it you will probably have to go back and change later because of something you didn't forsee. But this is why they harp so much on comments in school. I remember one of my co-workers trying to understand the code for a map-image generator written by another company and the only comment we found in the code was "here the iteration begins." That comment was useless! The more documentation there is, the less daunting the task of understand code bcomes.
Straevaras on September 21, 2006 6:48 AMThere are exceptions:
Say you have a wizard where the pages you see depend on which options you choose. It's a lot quicker to check out a switch statement in the code than it is to try and work out all the possible combinations from the interface.
Looks about right to me. I spend more time re-reading (and re-reading) my code than anything else. Seems to annoy the boss, but it gets the job done.
I would expect that kind of ratio on anything beyond a simple "Hello, World"
Jim Lang on September 21, 2006 7:14 AM"What I cannot create, I do not understand."
This is different than, "What I do not create, I do not understand."
I agree that understanding code is very important. But the implication in this article seems to be that if you don't understand some code, you should rewrite it. I don't agree with that at all. Perhaps if you don't have access to the person who wrote it, or you can't figure it out after stepping through it, it might need rewriting.
Chris on September 21, 2006 7:28 AMI was just asked by the wife last night how I learned best. She asked because I was bitching about getting some of my roles changed at work and I was learning a homegrown system from another developer - a case where I can't look at the code.
I explained that I probably learned best by first needing to understand the basic concept, and then to actually understand how why it works I take it apart and rebuild it myself in a way I know how.
Usually along the way I learn new techniques and commands and so fourth, but I totally agree that rebuilding is where the value lies.
While 95% of the time rebuilding is not better than fixing, many times I feel that rebuilding is the only way I can insure that I can continue support the application - even though I might have built it in the first place!
There is a reason there are very few people driving 1978 Cadillacs today. At some point everyone has to ditch the old to make way for the new. But in code world the turn around happens regulary - more like a lease instead of a buy.
Brian on September 21, 2006 7:29 AMyup, rewriting is better than reading.
there is this thing that frequently happens to me. someone says "where is such n such" and i say "oh it's up in parkfield" (or some other suburb). they ask "do you know how to get there?" and i say, "well sort of. but, no, not really. see, i've been driven there before, but i've never driven myself there. so, actually, no i don't know the way."
and that's like everything. if you've sort of looked at it... well that's nothing compared to putting yourself in the driver's seat.
I am currently in the position where i had to take over somebody's code - and i can tell you nothing is more time consuming and mentally draining that using another person's thought around an issue and trying to make it your own in terms of continued use.
I had to make a call if i wanted to rewrite a six month project or make use of what has been done already where the latter was the prefered option for my boss and i did just that and i can honestly say that understanding what bits of codes do in a system that has a primary objective and with the developer having his own secondary objective in terms of how he would solve a problem makes it a huge mountain to climb.
Gary on September 21, 2006 7:46 AMPeople here seem to be confusing rewriting in order to understand with rewriting in order to replace. Rewriting a function in a separate file is a good way to understand what a function does. After it has served that purpose, you can just throw your code away.
a href="http://www.objectmentor.com/resources/listArticles?key=topictopic=Craftsman"http://www.objectmentor.com/resources/listArticles?key=topictopic=Craftsman/a
Craftsman #4 is an interesting related read.
I remember a quote: The time necessary do understand code is equal to the time to write it.
Not useful in any way, but not far off the truth i think.
beza1e1 on September 21, 2006 8:48 AMDead on, Jeff. Like so many other things there is a big difference in seeing and understanding how something is done and actually doing it yourself. You can watch Tiger Woods hit a shot off the tee and you can basically figure out what he's doing to make it happen. But can you really know how a golf swing works if you've never played golf yourself? Nopers.
Being a relatively new programmer I cringe when I look back even a year ago at some of the code that I wrote. But the act of coding various applications on my own has allowed me to learn and grow and gain invaluable experience that I never would have obtained simply by analyzing existing code, reading some coding books, etc.
I believe it's not always necessary to start from scratch verses rewriting. But, I do believe it is in the doing that you gain the knowing.
Great post! I have found that with many of my projects I begin the coding, rework modify that code, and if I have time rewrite the code with a better understanding of how it should all come together.
Bill on September 21, 2006 9:04 AMJoel is right -- rewriting (as in writing new code from scratch) is usually a stupid thing to do.
Refactoring (as in: reorganizing the code, for example, to hide irrelevant detail) is also often overkill.
More than 90% of the time, simply manually reformatting the code slightly -- adding white space, making sure everything is properly indented -- is all I need to quickly get a feeling of fluency with unfamiliar code.
JohnK on September 21, 2006 9:07 AMI was going to avoid this thread as I knew I wouldn't be able to read it without taking ill but, then for some stupid reason, I dove into it.
OmegaSupreme had me on his side here right up until the comment about hard to design. I have heard that argument from developers over and over and over again and it is frankly rubbish.
"I think we need some better UML style tools so we can get a "birds eye view" ... because is hard to design it correctly up front ...".
Then Straevarus here left me cringing as he brought back memories ...
"We might write our own code, then 1000 lines later, realize that we need to go back and change was we previously wrote"
... memories of 4000 line methods written by "the code guru" at my former employer; methods with a cyclomatic complexity rating well above 70 (when I stopped counting). Methods that contained switch statements nested inside switch statements - something that should NEVER be done as there is no excuse for that kind of cryptic stupidity.
The fact that one realizes 1000 lines later that they need to change something the wrote 1000 lines earlier is 9 times out of 10 (I know, cause I've done it) because they never stopped to figure out what they were building in the first place. Chunks of code separated by that distance should have few if any dependencies that would result in that level of change being needed.
Finally, as I was imagining bungee diving without the bungee, some sanity intruded into the discussion.
"Take a thousand (+ 1) classes on communicating, influencing, and negotiating with customers and managers and your coding will be reduced by 80%, guaranteed". Wstephen
"The point, of course, is that software engineering, after 50 years, still has little in common with real engineering (sorry about your feelings). we insist on doing it different just because we want to." Buggy Fun Bunny
These comments cut to the bone of the problem. The majority of developers seem to refuse to partake in work related communication with others; many sit in their cubicles all day coding and this they consider productive (regardless of how many times they rewrote the same code/classes because they never understood what the code/classes were really supposed to be doing).
For some reason, the software development industry tolerates if not encourages the hacking out of solutions without any thought process. Software is complex; this is true. But so is a bridge from Prince Edward Island to the mainland designed to withstand St. Lawrence River ice floes. So is a Pentium processor. The difference being that with the bridge, the engineers only got one chance to get it right. With the Pentium, they got more chances but magnitudes lower than developers seem to require to produce their "complex" apps.
Rewriting a function to understand it, IMHO, is a clear indicator that either the reader has no patience or the function was abyssmally written in the first place.
Have a nice day.
Tim Dudra on September 21, 2006 9:11 AM"If I had eight hours to chop down a tree, I'd spend six sharpening my axe." ~ Abraham Lincoln. Task strategy doesn't change, only people and context change.
If I rewrite code because I don't undertand the original code, I am only prove my impatience. And I suggest most rewriting is done because we are unable to get management to understand just how much effort and time that is required to complete any particular task or project -- so we just code to fill the time.
Take a thousand (+ 1) classes on communicating, influencing, and negotiating with customers and managers and your coding will be reduced by 80%, guaranteed.
Wstephen on September 21, 2006 9:36 AMGreat post that directly answers why Joel has NOT jumped the shark. Writing a relatively small amount of code for a basic compiler, to preserve a non-trivial code base - especially when it simultaneously resolves other platform/porting concerns - seems like an obvious good move to me.
Jeff Szczepanski on September 21, 2006 9:59 AMisn't this why lisp wins big time? doesn't it let u abstract away the details so that the 'green' portion of the pie chart shrinks (in direct proportion to your code's lispyness)?
iamnottellingyou on September 21, 2006 10:26 AMThings like just how some threads synchronise with each other - and even which code runs on which thread(s) - really don't just fall out of the source code like that.
I'm gearing up to write code documentation for our DOS-emulating library for Windows CE/Pocket PC. DOS-emulating in the sense that you take a program's source code written in C for a Symbol series 3000 DOS hand-held computer and recompile it with eVC 4.0 and link to the library to get a Windows CE (GUI) application which presents a text-mode UI, with as few source code changes as possible. As you know, DOS was largely an 'execute all these things in this order' environment - highly imperative - while Windows GUI programming is event-driven. Our library also has to emulate all the things that were interrupt-driven on the original platform.
So in my library, the user program runs on the main thread, while another thread actually creates the main window and runs the UI, and there are a couple of other background threads for monitoring battery status and other things that Windows CE only offers via blocking APIs. This gets asynchronous screen updates. For a long time I actually used nested message loops to do it, but that meant you only got screen updates whenever some library function that blocked (e.g. waiting for a keypress, the equivalent of Sleep()) was called. Things like indexing a file would have to effectively Sleep(1) from time to time to show screen updates.
Unfortunately, moving the UI to another thread also means that input arrives on the UI thread, not the application's thread. So there's some pretty crazy synchronisation to ensure that the keyboard buffer is not corrupted by the concurrent threads and to unblock the main thread when a key is available. None of this is particularly obvious directly from the source code, even with some pretty big comments.
Basically, trying to learn something from the source code itself - depending on quality of source - can be like trying to work out where you are in the country using a 1:10,000 (or worse) scale map.
As for learning a project - I've been maintaining and enhancing an application server written in VB6 for the last three and a half years, and I still don't know all of it. I only correctly learned some details of the protocol this year, and that's with a document that purports to describe the protocol. Without that document, I'd never have understood it, or been able to fix some egregious errors - when splitting a message into multiple UDP packets, it sends a packet number and total packet count, and formerly assumed that the payload was a fixed 1500 bytes for all packets bar the last (being therefore too big for any network without fragmentation, due to an misunderstanding by the original programmer); I was able finally to make the packet size variable even within a message with only minor changes to the decoding code.
That said, there are some limitations of the VB environment which will eventually occasion a rewrite with some other language. Making a service can be done with the NTSVC.OCX sample from MSDN, but it's not a good implementation of a service. We can't multithread the main server EXE which limits scalability. Perhaps the answer is to move from having a socket interface (the Winsock control couldn't scale any further) which plugs into a VB application, to plugging a VB COM component (using much of the existing code) into a C++ host.
Mike Dimmick on September 21, 2006 10:37 AMPlease for the love of $deity, can people please stop referring to -any- code change as "refactoring"?
The whole point of refactoring, as originally posited, is that the change improves internal quality while not changing external functionality.
Referring to "refactoring" when talking about rewriting an app is like calling static typing proof of correctness.
No! Bad programmer! Step away from the buzzword!
Jeremy Dunck on September 21, 2006 11:10 AM
Sometimes I want to rewrite my own stuff. And it has nothing to do with not understanding it.
My general theory is that a software that is 10 years old (or is at version 10) NEEDS a rewrite.
Because you designed it to do something, but then you added more and more features, sometimes in directions that you have never imagined.
Then it looks like a Toyota Tercel, with added spoilers, extra fuel tank, two more weels, an electrical and a rocket engine.
The second reason is because you learned a lot of lessons (hopefully). And languages and compilers changed, OSes changed ("I see, this is a work-around for a Win 3.1 bug!!!").
So, maybe for marketing and executives rewriting is allways a bad idea. But not for an engineer.
This is where test infection pays off. Want to learn the rules of monopoly? At a minimum the tests should cover the basic rules, and makes it a lot easier to understand the outward-facing aspects, and ignore the internal details for the most part. Have a case that isn't covered in a test? Write a new one, if it doesn't pass, then you need to dig into internals.
Still feel the need to rewrite something for clarity? With proper test coverage, then you can do real refactoring as needed. I only rewrite/refactor sections I can't understand with a cursory glance. The only times I will rewrite a whole package from scratch:
* If the code has significantly more bad-smells than good-smells, insufficient or non-existent test coverage, and I can't even begin to understand what the developer was thinking.
* When I realize a library has taken completely the wrong approach, could benefit from a clean slate and I want to change the external interface.
Nice 3D perspective on that pie chart -- a classic method of influencing the viewer's interpretation of the data according to your own bias, that is, it makes the "understanding" section look bigger than it really ought to be.
Reed on September 21, 2006 12:22 PMEnter ye in at the strait gate: for wide is the gate, and broad is the way, that leadeth to destruction, and many there be which go in thereat:
Because strait is the gate, and narrow is the way, which leadeth unto life, and few there be that find it.
WOW, like Everquest, has mountains of broken code hidden inside it. If your hypothetical Martians tried reading the code, or worse, the comments, they would come away with a very wrong concept of how it works.
A recent EQ patch tried to "fix" the spell interruption that one gets from being pounded by monsters. The "skill" used to prevent the interruption was called channeling. Channeling + interrupts were broken since beta 7 years ago. Trying to retrofit the intended code into a live thriving system just about broke the system. Complaints from the player base ended up getting the "fix" backed out and the broken system restored.
Most of the "nerfs" or "bug fixes" involve players discovering what the code permits them to do, which is very different from what the developers intend. Field Marshal Helmuth von Moltke put it as "no plan survives contact with the enemy" (I would have guessed von Clauswitz).
So, for most games, actually watching players will derive a very different set of rules than the designers/coders intended. For your homework to prove this theory, one need only play Magic the Gathering, or Cosmic Encounters.
The running gag among evercrack players is "broken as intended."
Peter on September 21, 2006 12:54 PMI have to disagree with the gist of this post. It is rarely better to rewrite code. Rewriting code is just the easy way out. One of my bosses/mentors once told me that the best programmers are maintenance programmers; not because its glamorous but because its hard.
As others have pointed out, rewriting an app from scratch introduces bugs and decreases functionality you weren't aware of. How can you rewrite that which you don't understand? That's no different than trying to write a project with incomplete user specs.
I've been a maintenance programmer for the last 10 years, and there's nothing as frustrating as having to support someone else's poorly written code (ever notice how ANY code you didn't write yourself is "lousy"). But if someone is paying you to maintain an application, then that means there's probably some users somewhere relying on it to do their job. Rewriting their application because you don't want to take the time to grok someone else's source code may be in your (short term) best interests, but its not in the user's (and they're why we're here in the first place, right?).
Now there are some obvious exceptions to this: if the application is as lousy as the source code (i.e. its not providing enough value to the user), then rewriting probably makes sense. Similarly, if you're upgrading to a new platform, or introducing major new functionality, then rewriting is probably the way to go. But it should be the exception, not the norm.
Anything you didn't write is going to look crappy at first, but until you understand exactly what its doing, and how it works, how good of a judge can you be? You need to take the time to absorb the code before you can really have an educated opinion on the code's worth.
What I always do to get started is tackle one of the larger, seeminly important procedures/modules and (like someone suggested earlier) start cleaning up. Start formatting the code to fit your programming standards (personal or company): proper indenting, whitespaces, variable notation/capitalization, etc. Doing this seems anally retentive, but it helps you understand what the original author was trying to do. As you start to understand, comment heavily. Add your notes explaining what the code is doing, and more importantly, WHY the code is doing what its doing. Its also important to clean up any out-dated comments you find. After you've done this to a few pieces of source code, then reevaluate whether or not it should be rewritten. You'll make a much more informed decision.
Gotta run, but two quick ways to protect yourself from confusion on your own source code: complete unit tests extensive commenting. These two items will help make what you write today less confusing tomorrow (whether its you or someone else doing the reading).
Take care,
Bob O'Malley
I agree with you Jeff, 100%. It's not just what the code does but the individual developer's style, way of looking at things and dissecting; then re-assembling the problem is so diversified that it sometimes makes it impossible to modify without extensively re-writing portions of it.
And do you know what? I've been at this off and on for 20 years and I have never seen two developers source code that was even remotely alike when it came to solving a complex problem.
I've even compared left handed and right handed coders work and they are as different from each other as well as the other left or right handed developers.
As the old saying goes 'coding is an art' and no two artist are alike...
I think that it is interesting that (In my experience) it is usualy the "OK" code that gets re-written:
- Only a fool would re-write good code.
- Only a genius can understand bad code well enough to dare to re-write it. (Unless it can be re-written from the spec.)
- Hence the only code that you can easily re-write is the middling code.
Most of us have either written a particular code base or more likely have inherited someone code that was not documented well (if at all). Spending the time and understanding the code and determining what the refactoring of code will do is crucial. That prevents that amounts of subsequent bug fixes you have to do to address your original bug fix. In some cases, a bug that is reported is really a change in requirements. When your requirements change significantly enough that the current code is not doing the right thing, then at that point rewriting code is more of an option.
I have used some tools that generate a Kiviat Graph of the "inherited" code at my work and what I see in a general failure to follow 'standards'. I typically refactor/rewrite code to follow the standards and document as I go. Not necessarily for me, but for the next poor schmoe that is going to inherit my code.
-Tim
Tim on September 22, 2006 3:12 AMIf builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.
I keep reading this again and again, in a form or another.
Each new bridge is a rewrite of a previous one, with slight improvements!
If programmers would rewrite again and again a text editor, in 4000 years they will manage to make a stable one.
Just a bit of patience people!
(and even after thousands of years of bridge-building we can get it wrong, remember Tacoma :-)
Submitting the form deleted my initial quote:
"If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization."
But is ok, I am patient, in 4000 years all the blogging software will be perfect.
Mihai on September 22, 2006 3:41 AMGreetings,
Understanding does not require rewriting. It requires the ABILITY to rewrite.
One of the most valuable traits I have found in myself, as a software developer is the ability to look at a product, a service, an API, and think, 'How would I have built this?', and then apply a few small tests to see if my 'design intuition' is basically right. If everything looks right, I can then design my interactions with that software under the presumption that it'll do 'the right thing', and generally be right.
The worst job experience I ever had was with a company where NOTHING they built was designed the way I would have built it, and the design decisions (or even the forces that created the design decisions) weren't documented at all. Every time I tried to make a change, or build on top of their existing framework, something broke, often someones pet optimization.
In fact, the only developers who could adapt the existing systems were the 'old school' devs who had been there for 3+ years. After a year I got out of there, suffering from anxiety, near depression, and questioning my ability as a developer. Within days at my new job, I was a productive, confident developer again, as the frameworks I was building on top of (and the code my coworkers were writing) had no undocumented 'magic tricks' or convoluted optimizations, and most of our design decisions were sensible. We didn't need to read every line of the source to avoid unpleasant surprises, we just had to think how it SHOULD be implemented, and we were generally right.
A professional developer should be able to, at a glance (or with a few moments of uffish thought) say how they would have designed a system, and not be very far off. This requires the ABILITY to rewrite it, but not the necessity of actually rewriting it. At a certain point, in fact, you can make the call that, 'based on the developers experience (or inexperience), they probably wrote it like this:...'. Similarly, when you see a misbehavior, you can go, 'Ah. Based on what I know, and my experience, someone probably made *this* design decision, and it's mistaken in *this* circumstance. Look *here* for the issue.'
It may also help that I spent many years doing reverse engineering work professionally, so I see many things in this context.
I don't know any phrase for it other than 'design intuition', and it's incredibly helpful in everything from over-the-phone-debugging to bug reporting in packages you just use, to building good designs up front.
As for the concept of software development versus engineering branches, I pretty strongly disagree with the idea that software development is an 'engineering' field. It is more a creative field. There are certainly uncreative developers, and projects which require no creativity, but those are not the areas to be working in if you're a professional programmer, as those are the areas that will be marginalized.
This also isn't to argue that there isn't creativity in engineering, but that the constraints of most engineering is physical, universal, and well defined, whereas the constraints of software development are more mental, often project-specific, and cannot be very clearly defined, often because they involve people, and people just aren't well defined. :)
As for:
"If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization."
I always saw this as indicating the idea that programmers re-use, and build atop those who came before. I never saw it as a negative, really.
If programmers wrote programs the way builders build buildings, all software would come with its own Operating System.
It is true that re-writing large applications is a bad idea, but re-writing small to medium sized applications is a whole different kettle of fish.
I for one, have re-written some small projects and ended up further, with cleaner code and more tests, than I would have trying to hack the old code.
Andrew Chilton on September 22, 2006 5:30 AMIt is true that re-writing large applications is a bad idea, but re-writing small to medium sized applications is a whole different kettle of fish.
I for one, have re-written some small projects and ended up further, with cleaner code and more tests, than I would have trying to hack the old code.
Andrew Chilton on September 22, 2006 5:34 AMFeynmann didn't say "what I do not create, I do not understand." What he said was "cannot" - invert the clauses, and you'll see his meaning.
mjh on September 22, 2006 5:39 AMA factor in favour of rewriting is that the use that the system was originally coded to deal with may not in fact be how it is used.
Say you designed a system that could store it's data in an xml database, a rdbms, flat files or quantum singularities for reasons of flexibility. After five years you find that you only use it with an rdbms - well there is a lot of code you can take an axe to resulting in a smaller code base, easier testing and maintenance and it will be easier to add new features to the leaner system.
Now that you know that you are dealing with rdbms you can get closer to the metal, so to speak, and start to get better performance by working with the SQL rather than some abstracted query language that needed to be translated into XQuery, file system calls or quantum mechanics.
Ack, no. That was a horrible rephrashing of Weinberg's Second Law. It properly goes:
"If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization."
I have had experience creating, maintaining, and converting large complex business applications that use relational databases and have some reactions to the other bloggers.
Documentation and comments, when they exist at all, must be considered as unreliable, either because they were never done well initially or because they were not updated as changes to the design, database, or application were made.
All the comments about difficulty of reading existing source code are true, regardless of language. Even if the code is your own, and it is commented and documented, it can require significant effort to understand enough to make changes or to fix problems.
Refactoring/rewriting parts of source code to fix problems is tempting, although must be done carefully to avoid unintended consequences. Normally attempting to make minimum changes to resolve the current task is moat appropriate.
The only reliable bases for understanding are the source code and the database schemas, although reviewing inputs and outputs are sometimes useful also, given difficulty with other means.
Reviewing contents of tables and extracting smaller modules from the source code and running them in isolation are very useful techniques.
Attempting to reverse engineer major program logic and business rules by running the application and looking at the output will fail to produce reliable results, in real-world cases, altough may be very useful in limited cases.
There are several reasons for this, but the primary ones are the degree of complexity of some of the rules, the difficulty of determining the interaction between the program and the database, and the fact that the same external input may produce different outputs, because of the history stored in the database.
Bud Pass on September 22, 2006 9:04 AMFeynman was bang on. What we do not understand, we cannot create (except by chance rearrangment of everything in all possible combinations).
We can create engines because we understand how to rearrange raw materials, and we understand some of how raw materials came to be, but eventually our understanding ends and we are left with something we cannot create, but can only gather from the universe around us. We're down around the nucleon level at the moment, though, which is pretty far.
Jimbo on September 22, 2006 9:18 AMRewriting code is INSANE.
Programmers are INSANE.
Rule 1:
Only rewrite code IF the architecture is out of alignment with the requirements. Reason--it costs a whole lot more to patch a misfit architecture than to fix it. Notice I said misfit not 'eligant'. (Note: modularize--it minimizes the scope of re-writes)
Rule 2:
Read rule #1!
Most programmers don't know how to write "intention-revealing" code.
Code that answers WHY the function is doing what it's doing.
Much head-scratching comes from figuring out what the goal of a piece of code is, and (unfortunately) fixing it so it actually achieves that goal.
"rewriting" is a vague term. I rarely rewrite, but often refactor. For example, if I change a method's name and argument-list from "frpt(int x)" to "printFooReport(FileDescriptor anOpenFile)" that can make finding the bug in code that did "close(x); frpt(x);" easier to spot.
There are lots of code smells, but the most common is probably are those that violate the SRP - http://c2.com/cgi/wiki?SingleResponsibilityPrinciple - a method that does 5 very different things (and should be 5 methods), or a class that has 15 responsibilities (and should be split into 15 classes) can be VERY hard to read and understand.
That's why I prefer reading and writing Python code! I find my old code (older than a few months) very understandable. Also, other people's code is also quite understandable. I have tried other languages but I didn't find them as easy to pick up old code as in Python.
If you object about significant white space, spend an hour writing Python code and you will probably not notice it anymore.
Ko on September 22, 2006 1:06 PMWhat I'm suprised no one has mentioned is how bad Joel's example of Netscape Navigator looks in hindsight for his position. Since then, the rewritten code base has, through the Firefox project, become the second most popular web browser out there, and probably the biggest competator to Microsoft out there in that space.
Maybe you could make the case that a Firefox based on legacy Navigator code would have been just as succesful, but that steals a few bases in my mind without something to back it up.
There are other examples where rewriting from the ground up have not been spectacular failures. Take Windows -- NT was a completly different entity from Windows 3.x and 9x.
Or take the multitude of COBOL applications that were simply replaced rather than ported from mainframes to commodity PC hardware.
Colin Wyers on September 22, 2006 1:27 PM"As for the concept of software development versus engineering branches, I pretty strongly disagree with the idea that software development is an 'engineering' field. It is more a creative field."
Software development is not art; it never was nor ever should be intended as a creative field. You want to be creative, go into freakin' marketing or sales. With software you are supposed to be building a system that, given a predictable set of inputs, performs a specific task and generates a predictable set of outputs. This is engineering; not art.
My dad was a civil engineer and there was an element of intuition to that job too but the engineer doesn't have their intuitive flash and immediately sneak off into a corner all by their lonesome and dig a hole for a piling or throw up a main support beam. No, an _engineer_ presents the inspiration, epiphany or boneheaded idea to their peers where as a group they consider its merits/demerits and decide if it will be a valuable addition to the plan. The idea is honed to as near perfection as they can take it before they try to realize it.
Many developers (if not most) on the other hand won't present the idea to others because a) they are afraid it is boneheaded and others will criticize their fragile ego - better to have the computer break the news them in private or b) they are afraid somebody will point out that it is a great idea but it really isn't necessary to rewrite that stable piece of code in order to employ the idea or c) "My precious, my precious, don't touch my precious".
Software is art, not because it should be or necessarily must be, it is art because, like those modern artists who throw paint into a jet blast or weld cruddy pieces of metal onto other cruddy pieces of metal, it is built in an ad hoc manner, without any plan, without any direction and without any concern for the future.
An artist will paint a purple background, slap a white oval onto it and run four green stripes across it. It looks like rancid bacon on fried EggBeaters being eaten off of a 90 year old ladies purple sweater but what it really is is a juxtaposition of the emerging environmental movement against the discord of global warming.
This strikes a deep chord with me. I notice that I often end up rebuilding/writing something, even sample programs.
One purpose of my rebuilding is to get confirmation in small chunks. Another purpose is to demonstrate the function of the program. I want a form that provides a demonstration and explanation that I can comprehend without too much difficulty. This usually means that I will have ended up refactoring the internal structure of the program. I may also end up re-engineering the program from an abstracted understanding of its essential purpose (as well as repairing places where it is underspecified, as well as I can tell).
I don't think about this very much, although I have wondered whether it is some sort of character flaw that has me need to restate most programs in order to understand them.
But I think Keith Ray has identified what it is I am responding to. It is the need to understand the intention of the program and have that reflected in the way I express it. Whether that helps someone else reuse the code or not, I cannot be sure about.
orcmid on September 23, 2006 2:11 AMThat pie graph looks like its made in Microsoft Excel 2007
David on September 23, 2006 4:58 AMYou know, good documentation of the design philosophy behind a class would solve this.
Also, with so much data for WoW, the best way to determine optimized behaviours would be to run analysis on the patterns of the top ranked players. You've got the users, exploit them.
bago on September 23, 2006 5:15 AMI've always felt that a programmer who's only reasoning for a rewrite of a functioning, stable applicaiton was that the code wasn't understandable is an idiot. The fact is, if the program works, then the code is understandable and it may contain reasons, unknown to you, that something was done a certain way. The "rewrite" mantra is the mantra of the weak and inexperienced.
In the case of obviously buggy software you may just decide to rewrite something instead of inheriting their bugs.
In those cases where you know you wrote something with "prototype" in mind: REWRITE
Stephen on September 23, 2006 5:28 AMIt is with great interest that I read this article, however, I would like to submit a few corrections to the "where-developers-spend-their-time" graph..
here is a more accurate version, based on my own personal experience:
http://www.img2u.com/index.php?id=233
Ulic on September 23, 2006 6:36 AMThese posts are very enlightening. I have been writing my own code for 20 years and have finally decided to go to college for programming. The notion that I will spend most of my time understanding code is perplexing in that there is NOT ONE class dedicated to the methodology of 'understanding' someone elses code. If there is, I haven't found it. There has to be some sort of universal rubric that can, at the very least, be the foundation upon which new programmers (or those new to a company) can build upon. If a programmer really spends 70+% of there time doing this, shouldn't there be more in-house methodology devoted to this? If there is, where is it?
TechGuyDave on September 23, 2006 7:09 AMTechGuyDave,
My opinion would be that there is no emphasis on reading other people's code in university and college because "that's not fun". The last U course I taught, in January 2006, gave the students the option to build their own code or read and modify a substantial amount of existing code. In general, there were three categories of response:
1) a great deal of whining "there's too much code - how can we understand it", usually espoused after they had destroyed the natural organization of the code by eliminating the directories that housed the code for various components (so they could build it in Visual Studio when I had suggested they use Cygwin and g++ because the build scripts were all done inside the Cygwin environment),
2) a whole lot of "we weren't able to understand it so we wrote our own" coupled with "there was way too much homework assigned"
and finally
3) about 5-10% of the students read, modified and submitted the code that was provided and then sat back and relaxed and watched the others suffer since the workload was quite manageable if you just used Cygwin, the existing build scripts and the existing code.
It was a very interesting exercise in student psychology that, I suspect, is indicative of developer psychology as well. Rather than tackle an area outside their comfort zone (install and learn the Cygwin environment and g++) they decided to stick with what they were comfortable in (Visual Studio) and suffer lots of downstream pain to avoid near term pain.
One economist, writing about the idea of property and the rationale for private property, wrote something to the effect that economic models tend to be based on the "efficient optimizer" model of human behaviour, namely that humans will act in their best interests and will make efficient use of their own resources. He stated that in reality humans are "efficient short-term optimizers". We naturally look for short-term benefit gladly ignoring or deferring pain downstream (i.e., down "time"). We must fight our nature to make a _rational_ decision to suffer the pain early to avoid the pain later. In the software industry, because corporations tolerate if not encourage the hacker, software developers _almost_always_ dive into code (because it is fun - near term benefit) and produce complex, frankensteinian nightmares of code which result in significant long term pain.
Alternatively, if we learned to fight our nature and stop, think and design up front (the pain of having to think hard) in order to make the long term experience "profitable" (in terms of ease and fun "coding, not bug fixing and patching"), we might approach engineering status and build a piece of code that doesn't require 2000 "test runs and crashes" before it is stable.
Tim Dudra on September 23, 2006 1:30 PMThe author wrote "it's that very few developers are smart enough to understand code without rewriting it". I'm sorry, but if you don't understand the code, how are you supposed to rewrite it correctly? As Joel pointed out, old code had a lot of work-arounds (and tricks) added up over time, and unless you understand that code and its dependency with other code, you should just leave it alone (or add more work-around to fix a bug). Having said that, I'm not at all against rewritting code: if you understand a bad code 100% and sure that you can write better code to replace it, go ahead and do it.
Nguyen on September 24, 2006 10:44 AMWith regards to Feynman being ga-ga: At least based on his own biographical essays, it is clear throughout his life that he understood theories better when he worked out the details himself, so it was not a newly formed view at the time of his death. However, Feynman was a genius and so was well able to do the work to walk through a theory in detail. This does not mean that everyone is compelled to do the same, or that this works best for everyone.
There are more than just the two choices: read the source code, or rewrite to understand the problem domain. Almost all code nowadays builds upon other code, sometimes closed source, and people still manage to build lots of useful software on top of it.
Isaac Lin on September 25, 2006 2:51 AMIt seems this is oversimplified -- i.e., it's true of that part of my job in which I'm interacting with the code, but it is not true of the bulk of my job, which is non-coding requests, and/or groking just what is being said in a defect report.
bryan on September 25, 2006 9:06 AMI suppose it's kinda sad how true that pie chart is, but at the end of the day if you don't spend as much time trying to understand the code all you end up doing is wasting an extra hour on recompiling bad code that was never written properly in the first place.
nofrillz on September 26, 2006 11:52 AMWhy would you think that reading source code in isolation is any way to understand how a program works in the first place? Of course you have to know what an application does before you can work on it. Of course you have to understand how to use it. But you still have to read the code to modify it. It's not an either-or choice, you have to do both.
And the idea of re-writing code because you don't understand it strikes me as self-indulgent and amateur. Re-write to make it better, sure. But don't re-write because you don't understand.
Dean on October 27, 2006 8:26 AMThe real problem is that very few developers are able to write good OO code in the first place.
Legacy Code: Code which noone has the stomache to maintain.
Most refactorings i do on the job are turning code vomit into a slightly more OO design so i am then ABLE to make a fix/add a feature.
brian on January 5, 2007 9:25 AMI agree with the original post. A few other comments...
1. Rewrite code only after you fully understand what it is that you are rewriting.
2. Don't rewrite code because you don't understand it. It's tempting, but you might miss critical concepts that are imbedded in the implemetation thats non-intiutive to you. In other words, the other guy might have a messy implementation, but it might be for a complex problem.
I have been coding for many years, and this is something that i learned early on:
The poorest coder implements a simple task in a complicated way. That one i rewrite every time.
The average coder implements a complicated task in a complicated way. That one i might refactor if possible.
The superior coder implements a complicated task in a simple way. That one i tip my hat and try to learn.
Coders typically want to rewrite code implemented in a complicated way.
The best you can hope for is a simple task that you can implement in a simple way and get home for 5.
John on March 16, 2007 10:54 AMIf you have the privelege of having the person who originally wrote the code have a stab at asking that person to walk you through the semantics of it. Just a couple days ago I was able to save a week's worth of code/re-writting because the developer who wrote the original piece was able to walk me through what he did and w/in an hour I was ready to modify his stuff...I know that most developers would rather die rather than look for help or look "weak" but if you're choosing to take the path of least resistance ask if you think you can cut on waisted effort.
Jarocho
Jarocho on April 6, 2007 6:10 AMNice post,rewrite is easier.
article rewrite on June 24, 2008 9:54 AMThis post struck a chord for me... I've been working at this fun little web dev shop for just over a year, a nice no-bull workplace. What absolutely baffles me on a daily basis is that the other two coders are old school, in the sense that they write strictly procedural code with practically no separation between logic and presentation. The scary thing is they're all very good at it, which seems so fundamentally wrong to me :)
I'm coming from the opposite camp. I like OO, I like reusable modules, I _really_ like logic separation so I can throw new clothes on an old app and sell it to someone else. Needless to say, every time I crack open an old site, I start tensing up as I stare down the business end of a few dozen ad-hoc SQL queries, optimistic data validation routines and long HTML+code paragraphs that lack any structure whatsoever.
After a year, I've become a bit more comfortable cutting through the mess, but that's largely because I blank out my mind and focus solely on fixing the bug or changing the text, without paying any attention to context beyond what's directly needed. I'm like a horse with blinders, avoiding distraction at all costs. If I don't, sooner or later I will cave in to the primal urge to rewrite the whole codebase from scratch, and my coworkers will hate me for forcing my neat structures and encapsulated building blocks down their throats.
Here is my personal experience.
I have not yet re-written an application that did not greatly improve the application functionality, extensibility, reduce amount of code and do it in less time than expected.
Not once.
One of the problems with patch working ANY existing application is that unless the change is minor you end up having to fully understand the application as well as all the existing code anyway and the process of understanding the existing code is basically to read and “write it” in your mind. This takes at best the exact same amount of time as it would to re-write, usually more.
Now, I do want to point out it really depends on how many issues there are and where the problems are located and it does take some instinct to figure out when you are about to re-write all the code in your head anyway in order to understand it.
Let me begin by saying I've been reading this site for a while but I never felt the need to comment, until now. I agree with the main point of this article but I also feel that in order for you to understand the article a programmer may need to observe the program in action, use the program themselves, read the code, and then step through the code using a debugger. When I am given a large project that requires some revision they are the steps I take; it cuts down the time from the begging to the end of the coding process.
I have a brother that is a computer science professor. Some of his programming exercises allow a student to go out and find code that closely matches what they need, understand it, and then make changes to suit their needs. I feel this is the best way to teach a programming course because it isn’t too often that a programmer will start from scratch (a blank page). It not only teaches the students to be resourceful but it teaches them good techniques (through trial and error) on how to read and understand code that was written by others.
Aaron on February 6, 2010 9:52 PMI forgot to add, another reason for the huge chuck of the chart being understanding code is that a lot of the time programmers will write code, let it sit for a while, then come back to it. In order for that programmer to complete the code they first must reread it to ensure they understand what they did and what direction they were going.
Aaron on February 6, 2010 9:52 PMThere is one minor flaw in the concept of just rewrite everyting. When you rewrite it, you will introduce new bugs. Then you will have to fix them, at which point it is old code again, and you will need to rewrite it again, making new, different errors.
Isolating the area where the error is, and what the real need and intention of that piece of code, then rewriting only that one small piece (small enough to reasonably be assured that it can be done bug free) may be a better solution. However, it does not get you out of the business of reading and understanding old code.
Conclusion: Rewriting is easier and faster, but the final product is no better than the original. Only by fully understanding what was done, and why it is right and wrong, can we make contunual incremental improvements.
Grant Johnson on February 6, 2010 9:52 PMRewrites are usually a guise for I want to add programming language X to my resume, so lets rewrite this component in language X, although in some cases technology has evolved which dictates a major change.
Programmers should spend more time on design of the application and components, then there wouldn't be the need to rewrite it. If the design is good, then maintaining and addng improvements should be rather easy.
I spend most of my time rummaging through code to figure out how it works so I can either fix it or add enhancements without breaking antyhing. Sometimes an innocent small change can wreak havoc on the system.
When designing something from scratch, keep in mind that your system will need to be modified and updated. If you make allowances for this, the design can be carried forward, thus eliminating the need for rewrite. Writing code is easy part. Good application designs are hard to come by.
Jon Raynor on February 6, 2010 9:52 PMJeff,
This is a great article. I know from a personal point I have been known to rewrite portions of code that is hard to follow and understand just to try and get an understanding of what the original programmer was thinking. Your comment about how hard it is to explain what an application does makes me think of some the work I am currently doing. Supporting an application
I think the best way to understand what an application is doing is kind of like what you mentioned with taking a car out for a spin with your own wheels. Actually running the application and seeing how it behaves in different situations really helps shed some light for me (as well as reading the massive amounts of source code and highlighting different sections). Thank you very much for your time and I hope you have a good day.
Brandon
'Haacked' is right that having good clear tests are a useful element in understanding code - they document what the code is intended to do.
They're certainly not enough on their own though... tests may tell you what a single class does, but they don 't tell you how the components fit together.
Simon Geard on February 6, 2010 9:52 PMGood blog. Here are a few thoughts:
A lot of functioning code uses major hacks (Linux Kernel for example). I'm assuming that most people advocating rewriting code are Java programmers because I doubt they would even attempt to rewrite some of the assembler code in the kernel, or rewrite some binary "blob" code for wireless device drivers. And that's about as ugly as code gets.
If the bridge works for many years and doesn't fall, nobody cares if it looks ugly or very few can understand how it stays up (but suspension bridges do look pretty nice).
I agree that software sucks because nowhere near enough time is spent designing and re-designing. I've seen developers cringe when their code was examined by qualified people. I've seen end users marvel at the stupidity of a user interface. I've seen buggy apps that will NEVER WORK. That's when you redesign, review (as many times as is necessary), and THEN rewrite.
Finally, I personally have been part of development teams making software that served NO ACTUAL PURPOSE. The ideas which spawned the creation of the software were fundamentally flawed in ways that a teenager could determine:
"we want to make the Internet more like TV."
"But we have TV and it sucks."
"We want to sell huge items online."
"Shipping the huge items is more expensive than the item itself."
Don't rock the boat...
Anon on February 6, 2010 9:52 PMThe comments to this entry are closed.
|
|
Traffic Stats |