I have worked on many projects where pragmatism is the only way forward, rather than a rewrite. Often the software focused answer is a rewrite of the platform, but in the context of the business the right answer is often deep understanding and maintenance.
Legacy software at first glance can seem unruly and hard to understand which gives devs a kneejerk reaction to rewrite it. But make sure you give your developers enough time to sit down with the code and understand it. Given some time to really grok the platform's idioms often you can empathize with the previous devs work and figure out how to work within their framework.
You have to take the risk of refactoring into account as well. There is no guarantee you'll end up with better software, rather than just different software. You could end up throwing away years of edge case handling and feature development just so the core product runs on some new technology the new team is familiar with.
I've come to accept Conway's law, https://en.wikipedia.org/wiki/Conway%27s_law, that "organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations."
If you are new to a company and are dealing with legacy code who's logic is messy and the solution seems to be a 'rewrite', there's a high probability the new codebase will be as messy as the old one. Even if you aren't new in an org and yet your legacy codebase is a POS. It's highly likely given the same org doing the rewrite that it'll end up as a POS as well.
So if you are making the code 'simpler', getting rid of layers of abstraction to enable a pivot that never happened, you might run into a CEO who still wants that to be an 'option'. A plethora of special cases all piled on each other probably resulted from no single source of truth on requirements in the org. All of these things will still infect a rewrite from scratch.
Its much better to look into specific parts of the code that time can be taken to refactor properly. The time part is critical.
> But make sure you give your developers enough time to sit down with the code and understand it
It means that all future developers will have to spend a lot of time to understand complex code that could be simpler. Also, when the code is very complex, developers don't understand it fully, are hesitant and unhappy to touch it. Every new feature becomes a challenge and can break something. You need to rely on regression testing, but if you have tests, you may as well refactor.
Another reason to refactor is that you want to give new developers the satisfaction of "owning" part of the code. I read an article on software engineering at Google saying that it was ok if some parts were rewritten over and over.
> you can empathize with the previous devs work
Some devs are just bad and/or worked under strict time constraints. Code isn't only a matter of taste. There are objective metrics that tell you if some code can be improved.
>You could end up throwing away years of edge case handling
I work with software that has been continuously worked on since the 60's. It has the dreaded legacy if's like below everywhere.
if(obtuse variable) then
change a few other obtuse variables
There have been at least three attempts at major rewrites done of the software. The main goal was always to get rid of those corner case ifs everywhere. Every single attempt failed because we lost our ability to handle massive amounts of our customer's projects. Each of those ifs does something important.
One of my main projects throughout my stay has been to reduce these with small, disciplined improvements. I have made major headway in this fashion. You have to find the leaves of your software and work your way up while rigorously testing your changes. This is the exact opposite of the human gut reaction of a massive top down rewrite. It's impossible to tell how far you are off-course until it's done. It's the waterfall method of refactoring.
So much this.
I started a new job in a company that is redesigning the product, but instead of a complete rewrite, managers decided it was best to keep as much as possible from the previous iteration (it's an iOS app).
We're getting close to release, so we have less pressing bugs and no new features to implement, so myself and a team mate decided to take a week to perhaps refactor some of the code and update it to Swift. After said week we reach the conclusion that management made the right decision: The written code handled so many edge cases that if we were to rewrite it, even converting from objc to swift could ignore some edge cases.
Honestly, I got so lost in the article that I'm not sure that I understand what the point was.
IMO: It was always hard to justify preserving legacy ASP code once Microsoft made the decision to end-of-life the entire ecosystem. Web development was much newer than, and it was common to completely rewrite web applications in the "language du jour."
IMO: It's also easy to justify "fun" projects like writing your own compiler.
Maybe I'm just being a "Monday Morning Quarterback," but would it have made more sense to build an ASP -> ASP.Net converter as a standalone product?
Was part of an ASP->ASP.net conversion project whose project plan amounted to: “load it up in Visual Studio, switch from ASP VB to VB.net, edit until all red underlines are removed from the codebase. Should take 6-12 weeks.”
"Honestly, I got so lost in the article that I'm not sure that I understand what the point was."
You're 7 years late to a dead controversy. If you were in the middle of it, it would make a lot more sense as rebuttals to specific complaints made at the time.
Since the Internet Does Not Forget, perhaps those complaints will even come back up in this post, in which case the article may make more sense in hindsight. But I'm not going to be the necromancer. If you want to do your own thread necromancy, https://hn.algolia.com/?dateRange=custom&page=0&prefix=true&... should pretty much get you there, if you ignore the articles that are about the condiment. (And the top one is something else, too; FogCreek Wasabi is a compiler, not a storage platform.)
I've heard so much talk about technical debt (and done plenty myself) over the years and it almost always gets used to talk about improving the messy code of the last idiot who worked on the project and didn't know what they're doing. I really appreciated reading Ward's clarification that his original metaphor was about going back and improving the code to show an improved understanding of the problem. Assuming implicitly that the code is clean and well-written in the first place. So now I don't know what to call the effort required to clean up bad code written by inexperienced predecessors. Incompetence debt? Student loans?
I feel like a lot of frustration towards technical debt is rooted in projection. The code confuses you, and you feel dumb, but instead of accepting your feelings you blame the guy who wrote it and assume they're dumb.
However, often people have good reasons for why they write the code they write. For instance, maybe there are so many quirks and edge cases there's no way to write clean code without creating a massive body of abstractions that would just making development speed slower.
I'm all about clean code but as a senior developer I increasingly realize that naturally, everything is a tradeoff. While you should be biased towards neatness, sometimes writing pristine code just isn't worth the time or cost of maintaining all those abstractions.
Came here to write that. In modern sloop-rigged boats, I believe that the general consensus is that tacking is less dangerous and gentler on your equipment than jibing(gybing)/wearing.
In the tall-ship era of square-rigged vessels, wearing ship caused far less wear-and-tear on your rigging and was something you did to be more cautious or if your boat was far from a shipyard. Tacking through the wind was perhaps a bit reckless and not something to be done unless chased by a privateer or you were a warship in action.
If he wanted to say the boat in his analogy is going the wrong way, he failed. Hugging the coastline to Nova Scotia is the shortest route from Savannah to London: http://www.gcmap.com/mapui?P=SAV-LHR
[+] [-] ehnto|6 years ago|reply
Legacy software at first glance can seem unruly and hard to understand which gives devs a kneejerk reaction to rewrite it. But make sure you give your developers enough time to sit down with the code and understand it. Given some time to really grok the platform's idioms often you can empathize with the previous devs work and figure out how to work within their framework.
You have to take the risk of refactoring into account as well. There is no guarantee you'll end up with better software, rather than just different software. You could end up throwing away years of edge case handling and feature development just so the core product runs on some new technology the new team is familiar with.
[+] [-] jboy55|6 years ago|reply
If you are new to a company and are dealing with legacy code who's logic is messy and the solution seems to be a 'rewrite', there's a high probability the new codebase will be as messy as the old one. Even if you aren't new in an org and yet your legacy codebase is a POS. It's highly likely given the same org doing the rewrite that it'll end up as a POS as well.
So if you are making the code 'simpler', getting rid of layers of abstraction to enable a pivot that never happened, you might run into a CEO who still wants that to be an 'option'. A plethora of special cases all piled on each other probably resulted from no single source of truth on requirements in the org. All of these things will still infect a rewrite from scratch.
Its much better to look into specific parts of the code that time can be taken to refactor properly. The time part is critical.
[+] [-] yodsanklai|6 years ago|reply
It means that all future developers will have to spend a lot of time to understand complex code that could be simpler. Also, when the code is very complex, developers don't understand it fully, are hesitant and unhappy to touch it. Every new feature becomes a challenge and can break something. You need to rely on regression testing, but if you have tests, you may as well refactor.
Another reason to refactor is that you want to give new developers the satisfaction of "owning" part of the code. I read an article on software engineering at Google saying that it was ok if some parts were rewritten over and over.
> you can empathize with the previous devs work
Some devs are just bad and/or worked under strict time constraints. Code isn't only a matter of taste. There are objective metrics that tell you if some code can be improved.
[+] [-] safety-third|6 years ago|reply
I work with software that has been continuously worked on since the 60's. It has the dreaded legacy if's like below everywhere.
There have been at least three attempts at major rewrites done of the software. The main goal was always to get rid of those corner case ifs everywhere. Every single attempt failed because we lost our ability to handle massive amounts of our customer's projects. Each of those ifs does something important.One of my main projects throughout my stay has been to reduce these with small, disciplined improvements. I have made major headway in this fashion. You have to find the leaves of your software and work your way up while rigorously testing your changes. This is the exact opposite of the human gut reaction of a massive top down rewrite. It's impossible to tell how far you are off-course until it's done. It's the waterfall method of refactoring.
[+] [-] atticmanatee|6 years ago|reply
We're getting close to release, so we have less pressing bugs and no new features to implement, so myself and a team mate decided to take a week to perhaps refactor some of the code and update it to Swift. After said week we reach the conclusion that management made the right decision: The written code handled so many edge cases that if we were to rewrite it, even converting from objc to swift could ignore some edge cases.
[+] [-] gwbas1c|6 years ago|reply
IMO: It was always hard to justify preserving legacy ASP code once Microsoft made the decision to end-of-life the entire ecosystem. Web development was much newer than, and it was common to completely rewrite web applications in the "language du jour."
IMO: It's also easy to justify "fun" projects like writing your own compiler.
Maybe I'm just being a "Monday Morning Quarterback," but would it have made more sense to build an ASP -> ASP.Net converter as a standalone product?
[+] [-] sokoloff|6 years ago|reply
3 years later, we were almost done.
[+] [-] jerf|6 years ago|reply
You're 7 years late to a dead controversy. If you were in the middle of it, it would make a lot more sense as rebuttals to specific complaints made at the time.
Since the Internet Does Not Forget, perhaps those complaints will even come back up in this post, in which case the article may make more sense in hindsight. But I'm not going to be the necromancer. If you want to do your own thread necromancy, https://hn.algolia.com/?dateRange=custom&page=0&prefix=true&... should pretty much get you there, if you ignore the articles that are about the condiment. (And the top one is something else, too; FogCreek Wasabi is a compiler, not a storage platform.)
[+] [-] mekane8|6 years ago|reply
I've heard so much talk about technical debt (and done plenty myself) over the years and it almost always gets used to talk about improving the messy code of the last idiot who worked on the project and didn't know what they're doing. I really appreciated reading Ward's clarification that his original metaphor was about going back and improving the code to show an improved understanding of the problem. Assuming implicitly that the code is clean and well-written in the first place. So now I don't know what to call the effort required to clean up bad code written by inexperienced predecessors. Incompetence debt? Student loans?
[+] [-] asdfman123|6 years ago|reply
However, often people have good reasons for why they write the code they write. For instance, maybe there are so many quirks and edge cases there's no way to write clean code without creating a massive body of abstractions that would just making development speed slower.
I'm all about clean code but as a senior developer I increasingly realize that naturally, everything is a tradeoff. While you should be biased towards neatness, sometimes writing pristine code just isn't worth the time or cost of maintaining all those abstractions.
[+] [-] ummonk|6 years ago|reply
[+] [-] afarrell|6 years ago|reply
Does this piece of code ~spark joy~ fulfil its responsibilities concisely?
[+] [-] mdtusz|6 years ago|reply
[+] [-] OrangeMango|6 years ago|reply
In the tall-ship era of square-rigged vessels, wearing ship caused far less wear-and-tear on your rigging and was something you did to be more cautious or if your boat was far from a shipyard. Tacking through the wind was perhaps a bit reckless and not something to be done unless chased by a privateer or you were a warship in action.
[+] [-] searedsteak|6 years ago|reply
[+] [-] arkanciscan|6 years ago|reply
[+] [-] draw_down|6 years ago|reply
[deleted]