[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)