This is linked to a pet peeve of mine, especially with restless, young developers. There's a significant difference between the two statements "I don't get this code, it's crap, let's rewrite it." and "I understand this code, it's crap, let's rewrite it". I don't know how many times I've seen someone go down the path of seing battle-tested code, not understanding it, thinking they can rewrite it better only to spend a month falling in to all the same pitfalls that lead to the original code. The middle road is of course refactoring. Cleaning up the code in small, discrete steps to something you can understand and work with is many times better than just tearing stuff out and restarting.
Joel Spolsky's illuminating screed on Netscape rewriting its browser from scratch is apropos here:
The idea that new code is better than old is patently
absurd. Old code has been used. It has been tested. Lots
of bugs have been found, and they've been fixed. There's
nothing wrong with it. It doesn't acquire bugs just by
sitting around on your hard drive.
It tends to acquire bugs because ideas of what it should do change over time, and so what used to be correct behavior is no longer.
Which also gives you useful guidelines for deciding when to rewrite. Identify the design assumptions of the system. Identify which ones of them no longer hold. If you can't identify these, leave it be - there's probably something important in there that you don't understand. If you can identify them but there are ways of making the existing system meet the new requirements, refactor, don't rewrite. Only rewrite if the fundamental assumptions of the system, ones that permeate the whole system design, have changed.
There's a significant difference between the two statements "I don't get this code, it's crap, let's rewrite it." and "I understand this code, it's crap, let's rewrite it".
There are cases when the code is a convoluted, buggy, unintelligible, undocumented, untested and untestable mess. In those cases re-analyzing what it should do and re-implementing it from scratch is often both faster and more reliable way of dealing with required changes. Especially if you consider resources spent on maintenance over a significant period of time.
At this point, I get the nasty feeling that many people who preach "don't ever rewrite" mantra are the people who have produced large volumes of code in the past, but consider themselves too "senior" to maintain it now. The common rhetoric regarding "young/junior programmers" only confirms that notion.
Analyzing what the code should do is insufficient. You must also know what it does do. Somewhere, someone is depending on that and they will be angry when your rewrite, perfectly spec conforming though it may be, doesn't work the way it used to work.
Any change to a badly written application can break some obscure functionality or integration. I repeat, any change. Assuming that you're still working on the codebase in question (and why else someone would care to rewrite it?) there is a constant threat of breaking changes. Heck, with certain types of code regular issues after updates are nearly inevitable.
If you rewrite something, you will at least have understanding of how things work right now, which allows you to quickly and reliably deal with surfacing compatibility issues. On the other hand, updating legacy code to deal with those issue is a) much slower b) likely to introduce other issues.
And no, you cannot always slowly refactor old code. That is, in many cases it will take several orders of magnitude more time that a complete rewrite with new features plus all the rewrite issue mitigation.
Been there, seen that. Many times. So far I haven't regretted a single rewrite I've done in my professional life. If your experience is different, than maybe, just maybe, you should look at how you approach rewrites, rather than dismissing the whole concept as "wrong".
I don't think things should be painted as black or white as being either right or wrong.
A rewrite can be the best thing to happen to a code base, but it is not a panacea for all code quality problems. Sometimes a refactoring is simply a better option.
There are various reasons that factor into this decision, a good one being, as you mentioned, the assumption that you're still working on the codebase in question.
>>At this point, I get the nasty feeling that many people who preach "don't ever rewrite" mantra are the people who have produced large volumes of code in the past, but consider themselves too "senior" to maintain it now. The common rhetoric regarding "young/junior programmers" only confirms that notion.<<
I imagine the real reason is because the senior people have been burned to no end by trying to rewrite code they themselves did not understand.
There's nothing worse than realizing that you spent a whole bunch of time reimplementing something someone had already built when you could have simply taken a fraction of that time to understand why it was the way it was and, if applicable, to extend it to do whatever else you needed.
This also goes for looking for existing libraries to implement a feature before deciding to write your own. You still might need to write your own if you don't find something that fits, but sometimes you can save yourself a ton of work.
The only saving grace for having wasted all that time is learning the lesson that it's a waste of time and being able to apply that lesson usefully going forward. It's possible to go too far down that road and be too afraid to mess with existing code, but that line is actually in a very different place than I thought it was 10-15 years ago.
There's nothing worse than realizing that you spent a whole bunch of time reimplementing something someone had already built when you could have simply taken a fraction of that time to understand why it was the way it was and, if applicable, to extend it to do whatever else you needed.
There is something far worse. Spending years of your life to maintain a software version of Rube Goldberg Machine that performs mostly trivial things, but has insane accidental complexity.
At least when you re-implement something (even if it's been done before), you gain a better understanding of general ideas behind it.
Yes, but if you're going to replace it, then you really, really want to take the time to understand why it was the way it was.
Sometimes, you really do run across things that could never make any sense to anyone who knew better, like the famous Daily WTF example where someone created a website for a restaurant by printing out the page design for the paper menu, laying it on a wooden table, taking a picture of it, and uploading the picture. But other times -- much more often, in my experience -- you run across hidden technical challenges and limitations that led to what look like really stupid decisions until you understand the real motivation. And even when there were some really stupid decisions, it's often better to leave the system largely intact while you incrementally fix the stupid parts.
And, as I said before, sometimes it really does make sense to go in and start over. It's just that the line for when it's warranted may not be where you think it is.
As far as learning things go, providing your own implementation to solve a problem can be a great learning tool. Likewise, writing your own compiler, database, or web server can be an absolutely fantastic means for understanding these tools better. But it will rarely be the best means of solving a problem that requires a database-backed web application.
Reuse production-proven existing code and tools wherever you can when you're on the clock for a job or building a company, and teach yourself how things work on the side. If you build something so good that it's worth swapping in for the original and going through all the steps to bulletproof it for production, then awesome. If not, then you've still learned what you cared about learning.
It is very important to consider why the code turned into such a mess to begin with. Chances are same issues will happen again with the new codebase. If code generally turns worse over time, then the problem is not the actual code.
Developers are quick to think "some idiot must have written that" just because code is convoluted and ugly. But it might as well be smart competent developers working in firefighter mode, developers being shifted around from project to project with not enough time to get acquainted with the codebase, and so on. If these are the reasons a rewrite will not help.
If anybody on the team can spend a month going down a rabbit hole rewriting code then there's something seriously wrong regardless :-)
The "Don't rewrite code without consultation" was the only one of Jeff's points I would niggle with. I love environments where there is collective code ownership - everybody being free to edit any code without asking first.
It encourages everybody to keep the code in a state where that's possible, lowers the barriers to getting code improved, and helps lower the bus number by getting more people familiar with more of the code base.
But for it to work you need an environment where you have rapid feedback, regular integration of changes, etc. If those times are measured in days, weeks or - deity forbid - months then you're heading for trouble.
But for it to work you need an environment where you have rapid feedback, regular integration of changes, etc. If those times are measured in days, weeks or - deity forbid - months then you're heading for trouble.
This is a big caveat for lots of developers. Not everyone works in such an "agile" environment. Another poster has already linked to Joel's essay on rewrites, and that's written with his experience at Microsoft in mind.
There's also a matter of testing. If you have a group of testers slated for a release, suddenly dropping a bunch of regressions on them will seriously skew their time lines.
That's not say that the environment you describe isn't a good thing--it's just not reality for many of us.
I'm just fascinated by the interrelationships between technical practices. The way that a "good" practice can become "bad" (and vice versa) depending on the working context can be very hard to figure out.
Testing would be another one that would come into play here (and I guess that it's interesting that it didn't even occur to me to mention it since having a good automated test suite is so much of the way that I work now).
Without a good test suite having collective code ownership becomes much harder because making some dumb mistake that breaks something unintentionally becomes much harder to spot.
I love environments where there is collective code ownership - everybody being free to edit any code without asking first.
You can only do that in the most trivial environments (e.g. layout on a webpage) without destroying the mental state of everyone who is working on that codebase. Imagine having to waste half your day getting "up to speed" every day because nothing is as you left it. No-one should be irreplaceable, but any piece of code should have no more than two regular owners.
And yet I've worked several places with some decidedly non-trivial code where we quite happily did do this. None of us were wasting half a day getting up to speed because of things like:
* More of us being familiar with more of the code - so less to get confused about
* Lots of small functional commits, so the changes tend to be small
* We were bright enough to go have a conversation with everybody if we see changes that are going to affect lots of people
* We had an excellent test suite that prevented regressions, and was a good tool for getting up to speed with changes that had been made
Quite frankly - the idea of planning a business around only two people really groking bits of the code base is a bit frightening to me.
Sorry, 'months' was ill-chosen. FWIW, it's usually measured in hours where I'm currently at, but I've seen projects where people have spent literally weeks doing inane refactorings and rewrites, or where that has been the dictated norm ("We must rewrite our user management system, it's busted").
I think it depends. If the original author (or most recent modifier) is available then "I don't get this code" means I should be scheduling some time to talk to them.
If the original author is completely unavailable and I am the new maintainer, then "I don't get this code" might be a valid reason to rewrite it. Even if I can't improve it, by the end of it I will know what those pitfalls are and understand that code.
I hate this list. It should really be called the Ten Commandments of Good Little Worker Programmers. The 'commandments' are all about creating nice friendly programmer cogs that work smoothly together, minimising hassle for their employers.
There's nothing there about programming as an art. There is nothing there about pushing the boundaries of what is possible through determination, vision and, yes, ego. There is nothing about solving complex technical problems through sheer force of will.
To hell with 'egolessness'. Why shouldn't programmers have an ego. And, indeed, doesn't it take an ego to do anything great, to think that preposterous thought that you can do something no-one has done before.
For the vast majority of us, technology is one component of the business. The rest of the business is about figuring out how to lower shipping costs so that we make more money per item shipped. Or how to deliver food more efficiently. Or accounts receivable software.
And none of those problems are, well, are particularly hard or complex, at least not enough in my mind to justify ego as you've portrayed it.
There are plenty of professions where people work just as hard (harder, even, including people in the knowledge-working industry) and do not complain nearly as much as developers.
There is a lawyer in our office who works very hard to ensure that we are selling wine in a compliant way across multiple states with different regulations. That person's job is at least as difficult, if not more, than my job writing python. But you'll never hear them complaining because we only have apple juice, rather than orange juice, in the vending machine.
You are kind of making my point for me. This is a list drawn up from the perspective of a business owner who obviously would prefer all his employees to be egoless automatons who work smoothly together in the most cost-effective and efficient manner. Yes, from the business perspective (or the project management perspective or the agile coach perspective or the countless other professions that have infiltrated software development), this list is absolutely great. Couldn't be better. Five-star perfection.
However, from the programmer's point of view - and that is the view I was arguing from - the list is pretty detestable, at least in my view. People get into programming usually because they want to make things, because they want to be creative. But - in the vast majority of cases - they end up working on legacy projects that require absolutely no creativity, where, indeed, creativity is frowned upon - see Commandment 4. You are saying they should shut-up and deal with it. I am saying, fuck that, they can complain as much as they like.
Having said that, even better than complaining would be for the programmer to ditch the job and start creating their own software, under their own terms. But, of course, you would need a bit of an ego to have the guts to do that.
Haha, I am all for people squeezing out from under The Man and creating their own software.
I read Commandment 4 ("Don't rewrite code without consultation") differently. My opinion is that if you are working on a team with developers, you have to be judicious about making big changes.
It is possible (likely!) that some of that code was written because of some weird Python behavior or to handle an edge case from a buggy external API or some odd behavior from another internal system.
I do advocate "if you want a change, write some code and make the change." But a wikipedia-style edit war between programmers' egos is also not productive.
In the context of a business, "creativity" can and should mean "creative ideas that have the potential make more money." It is unfair to ask someone to pay you a salary for unbridled side-project creativity; that is what your disposable income is for!
Even when you are running your own business, well, it isn't a business unless you ask the question "how can I create software that my customers will pay for?" rather than "what shall I make which sates my creativity?"
I'd suggest, then, that this list is relevant for anyone trying to make money, because that always entails working with some other person (fellow programmer, business partner, customer) and that can only happen when you have a harmonious relationship with - and are willing to bend a little - for these people.
It is possible (likely!) that some of that code was written because of some weird Python behavior or to handle an edge case from a buggy external API or some odd behavior from another internal system.
If that code is in there without at least a comment mentioning that, then you have bigger problems than handling people's egos. This kind of thing is precisely what comments are for.
I do advocate "if you want a change, write some code and make the change." But a wikipedia-style edit war between programmers' egos is also not productive.
False dichotomy.
In the context of a business, "creativity" can and should mean "creative ideas that have the potential make more money." It is unfair to ask someone to pay you a salary for unbridled side-project creativity; that is what your disposable income is for!
Tell that to people who came up with 15% "innovation time" at 3M and 20% at Google. Of course, Google's 20% got subverted as far as I've heard, but that's a completely different topic.
The point is that creativity should be exercised at the right time, in the right place and in a right degree.
I'd suggest, then, that this list is relevant for anyone trying to make money, because that always entails working with some other person (fellow programmer, business partner, customer) and that can only happen when you have a harmonious relationship with - and are willing to bend a little - for these people.
This has nothing to do with making money. It has to do with your project being successful or not. It has to do with people on your team being reasonable most of the time and having a good manager (or something equivalent) the rest of the time.
Having said all that, "Don't rewrite code without consultation" should be a no-brainer. Not necessarily for Jeff's reason, but because if it's someone else's code, chances are that there might be something you don't understand about it; on the other hand, if it's your code, there might be someone using it and your rewrite could break it for them. Checking this stuff is usually a good idea.
> If that code is in there without at least a comment mentioning that, then you have bigger problems than handling people's egos. This kind of thing is precisely what comments are for.
Comments are a poor substitute for collaboration.
> Tell that to people who came up with 15% "innovation time" at 3M and 20% at Google.
As far as I'm told, 20% projects always had to be approved by your manager. So I suspect that they are not quite as open as you are thinking.
Of course they are, seeing as how they're only one form of collaboration. I wouldn't think that writing a comment to draw people's attention to some non-obvious aspect of code would count as anything but a form of collaboration.
As far as I'm told, 20% projects always had to be approved by your manager. So I suspect that they are not quite as open as you are thinking.
Which is why I did say, in continuation, that the 20% has been subverted at Google. From what I've heard, it hasn't always been that way.
This is a list drawn up from the perspective of a business owner who obviously would prefer all his employees to be egoless automatons...
People get into programming usually because they want to make things, because they want to be creative.
Welcome to the place otherwise known as 'the real world'. Do you think the guy filming the Jersey Shore dreamed of getting to where he is today? Of course not. Even people in creative fields have to suck it up and do the dry work before they are lucky enough to do whatever they want.
I don't think #4 is about creativity, but about communication and humility. It's about looking at what others did and discussing with them the possibility of changing it because 1) they built it and are probably more intimately familiar with its subtleties 2) it's a good idea to communicate your plans to your team (and especially the stakeholders in the code you're planning to change)
And none of those problems are, well, are particularly hard or complex, at least not enough in my mind to justify ego as you've portrayed it.
I wish I had a dime for every time someone underestimated the difficulty of solving or optimizing a real-world problem. I might have agreed with you if you claimed that executing a solution is not as complicated as coming up with one.
There's a line between having an ego and being a jerk. I don't think that line is so thin that we have to resort to suppressing ego.
If you are so good you can achieve greatness by yourself, as a lone individual isolated from others, and that is what you really want to do, then knock yourself out. That is the American individualistic dream after all. However, if you are not so awesome that you can succeed without help from others, or you value teamwork, community, and friendship, then these are good rules to follow, whether working for a large company, or starting your own business.
These statements are kind of like zen koans - open to different interpretation and depth of understanding. I don't see anything on that list that would preclude someone from doing something great, and a great many things that would probably help.
I like working with other developers. Other developers seem to like working with me. I very definitely have an ego :-)
I've worked with some folk who don't seem to work well with the rest of the team. They certainly make things unpleasant for management - but that's only a secondary side effect of them making the whole teams life unpleasant. Which in turn makes the product worse.
Sometimes (not always - or even often) the person who doesn't work well with others is technically excellent. I mean stupidly good. I used to think that more than made up for the trouble they caused.
These days... not so much.
To pick one from the list - do you seriously think "Treat people who know less than you with respect, deference, and patience" is a bad goal to have? That doing that will make you a worse developer?
Not at all. It's totally possible to dare to do great stuff as a team.
In Silicon Valley, VCs very rarely fund single founders. They fund teams. That's because it takes a team to create the world-changing companies that they seek.
This list isn't saying you can't be passionate about your work. But it is saying you can't be an asshole to your teammates, and that the point of the work is never the code itself, but the effect you are collectively trying to have in the world.
> The only true authority stems from knowledge, not from position.
That's certainly not the full story. In many organizations, having a lot of knowledge about something that someone else is supposed to know more about is a good way to make them feel uncomfortable or in extreme cases dislike you.
From a practical vantage, knowing how to apply what knowledge you do have (and having the will to follow through) is a lot more valuable.
It doesn't help to have a broad and deep understanding of software development and business but be socially awkward and suffer from severe akrasia.
In many organizations, having a lot of knowledge about something that someone else is supposed to know more about is a good way to make them feel uncomfortable or in extreme cases dislike you.
This. I worked for one org (USMC) where I was a young(er) worker, with more knowledge about our job (micro-computers, LANs) than most of my superiors. And this was okay. Encouraged, even. My lieutenant's job was to lead a team, not be a know-it-all.
Then I stepped into the civilian world and found a majority of managers were freaked out when their juniors knew more than they did.
On the other hand, in the armed forces, rank commands respect (or at least all outward forms). In the civilian world, those with rank may be more insecure.
I think it's more about culture, not respect for rank.
A guy is supposed to learn at least the basics of the next higher-up job, sometimes two. Team leaders are supposed to reach down two levels, ensure juniors are properly schooled to step up.
Obviously this is so if one's leader is zapped, juniors can step up and carry out the mission.
But this works out well in nominal peace-time and non-combat jobs, too. And the better trained and schooled one's juniors are, the better the unit can carry out the mission.
Example: one week into a three-week field exercise I was given 20 minutes to pack and report to a new, temporary, job, far away from my parent unit.
We could do this because everyone under me (all of three guys, but still) knew what I did and could do the job. The only problem it caused was that they suddenly had one fewer person to stand watch in the server CONEX.
I think the main point of this commandment is that people in higher positions are being encouraged to open their minds to those in lower positions who have more relevant knowledge. Wise team leads and managers do not point to their job title and inveigh "Respect mah authority!"
Of course, if you are the person with greater knowledge but a lesser position, and you have bosses that are not as wise as you would prefer, then there is an art to deploying that knowledge and ensuring that the right thing gets done while allowing others to save face. This sort of diplomacy isn't the kind of skill that most developers typically have -- or even have the slightest interest in learning -- but it's an awfully useful skill to cultivate, whether you're dealing with corporate bureaucracy or cranky customers.
It is interesting that all of us are getting a different takeaway from this list; something different resonates with different people.
It also surprises me that these lessons originated in 1971 (though I had not heard of this text until just now.)
Back then, IBM was hiring English majors and training them in assembly to work on OS/360 etc. It would not have occurred to me that developers back then would have cultivated a stereotype of a "prima donna."
Because to me, and perhaps this is a reflection of my age, it has only been recently that the popularity of joelonsoftware-esque "pamper your developers!" has led to a culture in small companies where we demand free beer and 36" Macs as a condition for employment.
Or has it always been that way for developers (of young tech companies; none of this really applies if you work at Fidelity Investments) modulo the greatest tech of the day?
Prima donnas exist wherever they can carve out a niche. Anyone working in a specialized field naturally sees the immense benefits to be gained by fully realizing its potential, often out of proportion to the whole enterprise.
As a coder, I constantly see things that could be automated, relieving people of menial tasks so that they could apply themselves to problems that really need a human brain. If only everyone would recognize the importance of this!
As a coder, I can only laugh at the silly testers who want me to reorganize everything I do so that their job becomes easier! Such prima donnas, thinking the world revolves round them, when it's obvious their role can only be in support of development!
The above two paragraphs are somewhat tongue-in-cheek, but there's nothing there that can't be found in the wild written or said in earnest. Such attitudes are equally applicable to marketing, sales, HR, you name it.
I think this is just supply-demand of the current labor market. There are enough lawyers to go around, but not even close to enough good developers. I think it will continue to be that way for a long time
Interestingly, you have compared apples and oranges: "lawyers" and "good developers" (as opposed to "good lawyers".)
What I mean to say is - and, of course, this is all unsubstantiated - there are plenty of coders and lawyers to go around, but fewer good lawyers (with relevant experience in a field of business, for me it is the wine biz) and good developers (can you follow the instructions on our code test?)
Possibly good lawyers simply get paid more than good developers, and so that - combined with a different culture between the two professions - engenders a different sense of professionalism.
What is the essential quality about dev which causes our culture to be different than other professionals (lawyers?)
Well, as someone married to a lawyer I one thing that is completely different is that they have to worry about their professional license - if they screw up badly enough then it can be taken away and then they can't work as a lawyer anymore.
There is no sanction that can be applied to a developer that will mean that they can never get employed as a developer again.
* Be kind to the coder, not to the code. ^
* Treat people who know less than you with respect, deference, and patience. - My friend/cofounder has been inspired by the codeyear thing and have been bringing to me a lot of silly code issues... guess i was being a bit rude with him lately.
I'm frequently in a room with people that know less about mathematics and programming than I do (and let's be clear, I don't regard myself as exceptionally talented in either field). It's not surprising, that's usually the reason I've been asked in to consult.
The great joy is discovering what these people know more about than I do: electronics, cartography, avionics, wet film processing, fire fighting, violin making, linguistics, ... it's always a surprise finding out just how much some people know about their particular interest and how well they can make you appreciate it.
I'm get a little tired of hearing "the IT Crowd" cackle on about how stupid their users are, maybe that is true for them but it is possible to go out and find end users that stretch and challenge you as a programmer to meet their needs.
Meh. I've done the rounds as a statistician, and it would be pretty unusual to meet somebody who knew as much as me about what I do - in fact, even if I meet another statistician, there is almost surely no chance they know everything I know. I am always the expert, at what I do. And then I have to try really hard to get any idea of what everybody else is doing.
This is linked to a pet peeve of mine, especially with restless, young developers. There's a significant difference between the two statements "I don't get this code, it's crap, let's rewrite it." and "I understand this code, it's crap, let's rewrite it". I don't know how many times I've seen someone go down the path of seing battle-tested code, not understanding it, thinking they can rewrite it better only to spend a month falling in to all the same pitfalls that lead to the original code. The middle road is of course refactoring. Cleaning up the code in small, discrete steps to something you can understand and work with is many times better than just tearing stuff out and restarting.