[HN Gopher] Code Lifespan ___________________________________________________________________ Code Lifespan Author : mitchbob Score : 96 points Date : 2023-01-27 20:14 UTC (2 hours ago) (HTM) web link (xkcd.com) (TXT) w3m dump (xkcd.com) | daemonhunter wrote: | It's accurate. Q&D stuff seems to have long lifespans. | markyc wrote: | and javascript was born | feoren wrote: | I see this kind of opinion a lot, and it's clearly resonating in | the comments. I'm beginning to think most people are just very | bad at writing reusable code. Despite all the negativity, it is | actually possible to write highly-reusable code that is clean, | understandable, and not "over-engineered". Why have you all given | up on that? | Sebb767 wrote: | > it is actually possible to write highly-reusable code that is | clean, understandable, and not "over-engineered" | | You might be able to do that. That code (most likely) still | needs to solve a complex issue and needs documentation to | survive next to it. Also, there is a good chance that the next | guy coming to fix it is not going to investigate the extra time | to fully understand the code if he can fix that one crash by | throwing in a hotfix at the specific line accessing a | nullpointer. Lastly, at some point, if you need to solve a | difficult problem, the code to do so is likely going to be more | difficult to read, too. | | It's not impossible to do this, but having the time to do a | clean solution, having the foresight to be right about the | necessary complexity and also have the environment for it to | stay clean is simply rare. | thfuran wrote: | But the comic isn't suggesting that it can't be done, only that | it's often hard to guess ahead of time when the effort is | warranted. | Gigachad wrote: | The team manager at work likes to bring up the list of "time | investments which we will benefit from later" which we never | benefited from later. It's a good point that usually its | better to wait until the benefits are obvious rather than | predicting at some point there will be some benefit later. | fasterik wrote: | _> it is actually possible to write highly-reusable code that | is clean, understandable, and not "over-engineered"_ | | This is true for systems where you already have working code | and you have multiple concrete examples of code that would | benefit from refactoring or rewriting a reusable module. | | I think the skepticism is more toward the idea that you should | design for reuse _up front_ before you have working code. There | are two failure modes. One is that you spend time making | something reusable that you only end up using in one place. The | other is that you bake assumptions into the code that later | turn out to be false. In both cases, the resources spent on | reusability could have a net negative impact on the project. | Willish42 wrote: | Generally, the more (over-)engineered something is, the more of a | pain it is to reuse/maintain/etc. Simple code is more likely to | be grok'd easily by readers, and therefore reused as many places | as possible. | | Working in an organization where there's a lot of overengineering | going on constantly and it definitely feels like a significant | portion is wasted effort for the time horizon such projects | survive for. | | Randall Monroe observations for this kind of stuff are always | really spot on. I wonder what his creative process is like. I | should probably read XKCD more often... | Pasorrijer wrote: | I mean, the thing about a quick hack job is the person building | the code has a very well defined problem and knows exactly what | will fix it. And so that's almost a perfect requirements to | solution match. | hot_gril wrote: | People where I work tend to act like their code is going to never | be changed later. Like yo, I could rewrite my thing 5 times in | the amount of time it took you to build the "generalized" | solution that'll probably break anyway. My entire job the past 4 | years has been keeping some overengineered thing on life support | until its author leaves the team and I nuke/rewrite it, and one | of my teammates is like me. | mikojan wrote: | Where I work you decide whether to produce over-engineered or | under-engineered crap prior to writing it and people cannot | waste time on a rewrite just because someone left. | hot_gril wrote: | Yeah I've got a lot of luxury here. Used to be in startups | where the whole thing can be FUBAR from a mistake like that. | csours wrote: | Looking at some 20 year old code and continuously telling myself | "They just made it work" whenever I ask why would anyone do this. | Nevermark wrote: | > It took some extra work [... ==> ...] ensure code is never | reused. | | Simplifies to: Code is never reused (99.99% probability) | | > Let's not overthink it [... ==> ...] code lives forever. | | Simplifies to: Reused code is always underwhelming (99.99% | probability) | | Solution? This is the optimum! Tuning 0.01% of situations isn't a | good use of time. Stop worrying and learn to love the spaghetti! | AlbertCory wrote: | Spot on. And why code reviews are at least 70% a waste of time. | | (Note that I left 30% for some of them to do some good, | occasionally.) | Gigachad wrote: | I've generally found pair programming to be more useful than | code reviews. It's too hard to drop in at the end of someones | weeks of work and try to meaningfully review it. And a lot of | suggestions you might have would have been useful at the start | of the work but aren't worth going back to fix. | | If you actually sit along and see the whole process you can | actually understand the whole piece of work as well as give | suggestions when they are useful and much cheaper to action. | hot_gril wrote: | Code reviews are useful when the reviewers don't have OCD, | which is only about half the time. | Gigachad wrote: | All OCD and preferences should be encoded in the | linter/formatter or a wiki page. It's obviously a waste of | time to argue menial preferences in review. | [deleted] | kuczmama wrote: | Seems about right. | seadan83 wrote: | I feel like some of the earliest advice and an early learning | principle was: - design for reasonable extensions in the future. | Is your design modular, will it be easy to add features? Did you | solve problems in a generic way that could be re-used for other | other solutions? For example, instead of doing a graph traversal, | did you solve the problem by first writing a graph traversal | library? | | I don't think it's quite as widespread, I would posit that this | has changed to: - (1) YAGNI, build the simplest solution you can | for the problem at hand. That will make it as easy as possible to | change when future requirements are presented. (2) Design your | code to be replaced, not extended. Design your modules in a way | that someone can rewrite one without having to rewrite the whole | system. | | Points (1) & (2) really contradicts the generalized solution | approach. The generalized solution tends to be very abstract, | hard to understand, and because there are layers - not very | modular (which makes it hard to re-write) | andreareina wrote: | At work I'm looking at exactly the simplest solution I could | have written for the problem then at hand, and now that | requirements have changed I'm going to have to rip it all out. | seadan83 wrote: | I'm curious, had you written a generic version, would you | still be ripping the code out? (I'm guessing so, otherwise | presumably you would now be making that code generic). | | I still find it funny that the place to optimize is generally | for 'rip-out-and-replace', rather than 'extend' (caveat | emport, not always the case, but seems to be a better design | to optimize for replaceable than it is to optimize for | abstract & extensible) | Buffout wrote: | "generalized" means the most simple code you can come up with. | This simple code is then used thousands times from very | different programs, and it never changes. | seadan83 wrote: | See XKCD comic : ) | | I would disagree that "generalized" equates to simple. | Generalized means generic and usually abstract. | | - https://en.wikipedia.org/wiki/Rule_of_three_(computer_progr | a... | | - https://blog.codinghorror.com/rule-of-three/ "It is three | times as difficult to build reusable components as single use | components" | | I think implicit in the point, most code does not go on to be | used thousands of time (let alone dozens or even more than | once). Even if some code is used more than once, making it | the same and shared has significant costs as well. | Buffout wrote: | Never said it is easy to build simple reusable code. Code | itself must be simple but process behind devising it may | not be. If the code is not simple it is more prone to | error. | Gigachad wrote: | We've had a few people who like to do the first option. They | would build a semi library inside the app to solve a problem | and then when they move on to another company, no one really | understands the design principals behind it and make changes | that make it not so reusable and years later it never ends up | getting reused for anything new anyway so we are just left with | a very abstract, pseudo library with no documentation and years | of tacked on changes. | | Now we advise people to build the simplest and most obvious | version for the problem you are looking at right now and if in | the future you need it all over the place, replace it with a | reusable one. | | The exception seems to be React components, those generally | seem to be very easy to identify as reusable UI and can be made | generic from day one. | gopalv wrote: | > Points (1) & (2) really contradicts the generalized solution | approach | | So I was told this as bluntly as possible by someone 15 years | ago - "you don't have to code all parts of your design". | | Every line of code you write makes it harder to replace it. | That the feature is an asset, the code is a liability. That the | goal they had set out for me was to write as little as | possible, but achieve the same result. | | The only reason to rewrite a system out of tech debt, which is | what I was doing then & getting lost in a sort of second system | "this is the last rewrite" effort, is to write the next feature | with less code - even if the next system needs you to rewrite | bits you just wrote. | | This might sound simplistic, but I've seen that work over and | over again. | | Plus, it was much easier to hand over the code to the next | person when I wanted to do something new and interesting, if it | was functionally complete and not full of half designed | extension points all over. | knlb2022 wrote: | > "you don't have to code all parts of your design". | | That's an excellent articulation of what I think as | "invisible seams" when I write code: they're soft points of | extensions that don't need a separate | interface/function/class _yet_. Sometimes I just mark them | for myself with an extra newline within a function. | jayd16 wrote: | The problem with the "generalized" approach is you often only | have one data point to generalize across. If you try to focus | on solving problems you don't yet have then you end up writing | a lot of useless cruft. | | If you write clean code that is easy to groc and easy to | replace, then its also easy to extend once you know where you | want to extend to. | travisjungroth wrote: | There's something in between those two sides that relieves the | tension. You don't have to build a graph traversal library and | you certainly don't have to publish it. My opinion is that | while solving for the immediate problem, you slice off that bit | about traversing graphs and handle that generic problem on its | own. Now, you only have to think about that one narrow thing. | This is also makes it much easier to modify or replace, no need | to extend. If you don't do this, the overwhelming tendency is | that the graph traversal algorithm snakes its way through your | program and is a huge pain to change and reason about. ___________________________________________________________________ (page generated 2023-01-27 23:00 UTC)