[HN Gopher] What 10k Hours of Coding Taught Me: Don't Ship Fast
       ___________________________________________________________________
        
       What 10k Hours of Coding Taught Me: Don't Ship Fast
        
       Author : thunderbong
       Score  : 95 points
       Date   : 2024-09-21 16:13 UTC (6 hours ago)
        
 (HTM) web link (sotergreco.com)
 (TXT) w3m dump (sotergreco.com)
        
       | ashu1461 wrote:
       | The refactoring piece is a great advice. That is the only way to
       | keep the codebase sane and relatively free from tech debt. And if
       | it is not the part of the process, it would never get
       | prioritised.
        
         | bckr wrote:
         | Tidy first!
         | 
         | Make the necessary change easy to make
         | 
         | Then make the necessary change
         | 
         | I'm paraphrasing Kent Beck
        
         | IshKebab wrote:
         | Yeah I definitely agree. Any time spent prototyping is easily
         | worth it (and I mean _real_ prototyping, not  "prototype that
         | you add features too until it's the product").
         | 
         | I once spent a few weeks protecting a project with different
         | GUI toolkits. I think I spent a week each on Qt, AngularDart
         | and Vue. I wanted to spend one more week trying React but my
         | boss was just itching to "start" and couldn't wait one more
         | week.
         | 
         | We went with Vue, which turned out to be a terrible decision
         | (I'm not sure about Vue 3, but Vue 2 at least is shit compared
         | to React). Guess what we spent 6 months doing later... all to
         | save one week.
        
       | leksak wrote:
       | Do ship fast until it is known what the application will even be
       | and what the feature-set is and what needs the user actually has
       | and not just what it is believed they need.
       | 
       | Don't sink a bunch of time into "cleanly" exploring the fog-of-
       | war. Gather as much insight as possible as soon as possible. Only
       | then will you be equipped to actually architect for the domain as
       | it actually is rather than what you the developer think it might
       | actually be.
        
       | stouset wrote:
       | So much of our "ship fast" culture is based around end-user
       | application development, where it's a reasonable and defensible
       | approach.
       | 
       | But the further away you go from end users toward libraries, then
       | internal services, then even further toward infrastructure, the
       | slower and more thoughtfully you should move. These things often
       | have far less rapidly changing requirements, and getting it right
       | pays dividends. Or more realistically, blasting something half-
       | baked out results in drag on your organization that you end up
       | having to support for forever.
       | 
       | On a slightly different axis, _APIs_ should be built with more
       | thought and care than internal implementations. Backward-
       | incompatible API changes are hard. So start out by building an
       | API that expresses the logic your consumers want to implement.
       | README-driven development works great here: literally write the
       | README that showcases how people would use your API to do a
       | variety of tasks. Then you can iterate as many times as necessary
       | on the code, while having to iterate on the exposed surface area
       | far less than if you just exposed today's internals as the API
       | (which is sadly the norm).
        
         | sonofhans wrote:
         | This, exactly. Rapid iteration on user control surfaces is
         | good; rapid iteration on public APIs is bad.
         | 
         | Edit to say -- rapid iteration of UX is good as long as it's
         | goal-aligned and has an endpoint. Set a goal, iterate and
         | measure until you achieve it, then leave it alone.
        
           | mitthrowaway2 wrote:
           | Yes, please leave it alone. Nothing prompts me to leave a
           | service I've been with for a long time than a UX "refresh"
           | after I had years of experience and setting everything the
           | way I liked it.
        
             | rkuodys wrote:
             | I think this is such an interesting issue. On one hand as a
             | system developer, you want to keep existing customers happy
             | with what they are used to. On the other- you want to grow
             | and acquire new ones which requires upgrades to existing
             | processes till you reach a limit - you need a new ui/ux.
             | And what do you do? Maintain N versions?
        
               | bigstrat2003 wrote:
               | The problem, as usual, stems from businesses prioritizing
               | growth above all things (including the existing
               | customers). There's absolutely nothing wrong with having
               | a stable business that turns a respectable profit, but
               | modern day American business culture is allergic to the
               | idea.
        
           | stackghost wrote:
           | I can't think of a UI/UX iteration in the last 10+ years that
           | felt like an upgrade.
           | 
           | Reddit, Gmail, Twitter, Windows, Android, touch screens
           | replacing actual buttons, etc. they all used to be better but
           | big companies seemingly can't help themselves from making
           | their product worse.
        
           | rqtwteye wrote:
           | "Rapid iteration on user control surfaces is good; rapid
           | iteration on public APIs is bad."
           | 
           | I think rapid UI iteration is bad once a product has reached
           | a certain maturity. I absolutely hate it when a tool I use
           | often, suddenly changes its interface without any discernible
           | benefit. I am fine with yearly changes but the constant churn
           | is really annoying. MS Teams is a big offender here. They
           | constantly change stuff but nothing gets better, just
           | different. And a lot of UX guys seem to feel it's best to
           | take away features that only a few percent of users are
           | using.
           | 
           | Compared to the progress we made in 1990s and 2000s, it feels
           | like most companies are just moving buttons around and making
           | UI elements more difficult to distinguish but otherwise they
           | are out of ideas for actually useful stuff.
        
         | tetha wrote:
         | Mjeah. It is our goal at work to enable our teams to deploy
         | changes to their systems in production within minutes. And this
         | works and the teams utilizing it get commended for it.
         | 
         | But I also need to plan and execute a major database upgrade
         | with ~250 applications depending on it. I will be very happy if
         | I can have a solid, generally accepted plan in a month or two.
         | It will just take 1-2 person-days to eventually execute the
         | updates, but it will take 6 - 12 months to get there. And from
         | what I hear from colleagues and customers, that's fast.
        
           | bluGill wrote:
           | Great, butmy end users don't live in fast internet range.
           | every few months they spend some time in 2g cell range.
           | upgrades mean mailing a usb drive. we have to get quality
           | right as fixes cannot be rolled out fast.
        
         | angarg12 wrote:
         | > even further toward infrastructure, the slower and more
         | thoughtfully you should move. These things often have far less
         | rapidly changing requirements
         | 
         | I used to think that, until I worked on my first large scale
         | system, infra heavy. It turns out it works both ways.
         | 
         | If changing infra is hard, slow, painful and risky, people will
         | be less inclined to do so. If changing infra is fast, easy, and
         | with low risk, people will be much more inclined to change
         | things.
         | 
         | Even if you had very stable requirements (doubtful in this day
         | and age), I see no reason why you wouldn't build your system in
         | a way that is easy and safe to change, for the day when it's
         | needed.
        
           | GauntletWizard wrote:
           | You should still ship early and ship off in with
           | infrastructure projects, but the changes you're going to make
           | are going to be a lot smaller, and the big ones are going to
           | be planned far in advance. You will still need big changes,
           | and even your small changes require subjectively "more"
           | thought.
           | 
           | Both things are true: you should move slower and more
           | thoughtfully on infrastructure projects, and "ship often" is
           | still valuable advice and a worthwhile goal
        
           | auggierose wrote:
           | Because you cannot build a substantial system such that it is
           | easy and safe to change. Especially for changes you didn't
           | foresee.
        
             | angarg12 wrote:
             | Hard disagree. The system I'm talking about is the largest
             | scale system I've worked with (millions of QPS, thousands
             | of servers). We built it in such a way that we were able to
             | rewrite entire parts of our stack easily and relatively
             | safely. The techniques and tools to do it are widely
             | available today.
        
           | stouset wrote:
           | I don't disagree at all, but I want to be clear that my point
           | is more about upfront thoughtfulness and less about continual
           | ability to iterate.
           | 
           | Being careful upfront often _increases_ your ability to
           | iterate rapidly because you aren't constantly dealing with
           | the consequences of poor early decisionmaking that causes
           | calcification.
        
         | hinkley wrote:
         | TDD is trying to accomplish the same thing. Here's the shape of
         | the thing, now make it work. But maybe we should just be
         | writing the manual first. Though I would say we need something
         | akin to "code coverage" in that doc, even if it's just QA
         | changing the font color of every line that is now true from red
         | to black, so you know where the gaps still are.
        
           | stouset wrote:
           | Sort of, but sometimes I feel like TDD approaches the forest
           | by making each tree first one by one.
           | 
           | I _really_ like writing a usage README first, since I don't
           | have to make anything work along any axis yet but I can play
           | freely with the shape of things, figure out how to make the
           | whole thing consistent, and experiment on what boundaries it
           | makes sense to break components apart so they can be mixed
           | and matched.
           | 
           | This does require a decent amount of engineering experience
           | to both figure out what your consumers really need and also
           | to design something that is actually implementable.
        
             | hinkley wrote:
             | We are doing this weird zigzag of a gradient descent
             | because we know that things are bad, but we don't know
             | exactly how they are bad. We don't know exactly which
             | direction is "downhill" and which is "uphill", so we turn
             | around and head somewhere in a 120deg code of where we
             | think is the opposite direction. But it's not the right
             | thing, it just has some of the opposite qualities of the
             | wrong thing.
             | 
             | It's better than post-disaster politics, where "something
             | must be done, this is something, so we shall do it" but it
             | has an aftertaste of that same sentiment, if that makes
             | sense.
        
       | l5870uoo9y wrote:
       | When I program something new and challenging, whether I want to
       | or not, I follow Kent Beck's pattern[0]: "Make it work, make it
       | right, make it fast.". It seems unavoidable.
       | 
       | [0]: https://en.wikipedia.org/wiki/Kent_Beck
        
         | IshKebab wrote:
         | I dunno if you can always do them in order. I've seen so many
         | projects fail because they left "make it fast" until the very
         | end ("but premature optimisation!") and then found they'd
         | written tens of thousands of lines of code using a language or
         | architecture that was fundamentally slow, and making it fast
         | would require a full rewrite.
         | 
         | I think it's fine advice in some circumstances but like so much
         | coding advice the real skill is not knowing the advice, it's
         | knowing when to apply it.
        
           | mewpmewp2 wrote:
           | Out of curiosity which projects were those?
           | 
           | It must be a very specific use-case, because usually I would
           | see languages usually considered worst for performance being
           | able to scale really, really far.
           | 
           | In 95% cases it's usually database being the bottleneck
           | rather than whichever coding language you chose.
        
         | bluGill wrote:
         | If edison had spent some more time thinking he would have
         | perspired a lot less. Too often there is no path from one to
         | the next other than starting over.
         | 
         | If you have the wrong algorithm your existing tests won't help
         | much as the likely have wrong edge cases.
        
       | lordnacho wrote:
       | One of the great things about working from home is that I often
       | don't do anything. As in, I'm not even by my computer.
       | 
       | I'm still thinking about what to do, but I'm not implementing
       | anything. I'm not typing stuff, I'm not waiting for a compile,
       | I'm not outwardly moving the project forward.
       | 
       | But the project is moving forward.
       | 
       | Inside, I am considering the tradeoffs. I'm thinking about what
       | the business needs, and what things will look like when I'm done.
       | 
       | Now and again, things come together and I write the code. It's a
       | lot less frantic than 20 years ago when I started. I throw away
       | fewer things, and there is less time wasted. Any bugs that I
       | write tend to be superficial, easy cleared up. Back when I was
       | younger, "bugs" would be architectural decisions that were made
       | in the frenzy of an office, and would require a lot of work to
       | fix.
        
         | emidln wrote:
         | Rich Hickey calls this "hammock time".
        
         | greenbit wrote:
         | It's kind of maddening, after having the space to Just Think
         | during the WFH days, to be back in the office and any time you
         | stop typing for more than 30 seconds risk being interrupted by
         | co-workers who think you're Not Busy.
        
           | jauntywundrkind wrote:
           | I admire the heck out of the two coworkers I've had who were
           | smart enough to stand up & go for a walk to think. Or to have
           | a 1:1.
           | 
           | I didn't face a ton of unscheduled conflict for my time, and
           | there were many rooms available at that job. But the change
           | in perspective was amazing, just so much power to help me
           | really consider things in new light.
           | 
           | It's funny because I grew up with Steve Roberts as my role
           | model of role models, as the guy who showed me that being an
           | adult could be fun & interesting, with his work-from-bike
           | Winnebiko. And I was a seasoned coffee shop coder, which I
           | found amazing with its change of scene & deliberateness. But
           | seeing Adam have such a practice of getting up, grabbing a
           | notebook (also a seasoned writing-things-down person; another
           | key element of _Hammock Driven Design_ ), and going for a
           | stroll (DC's Rock Creek Park was a bit over half a mile away)
           | was amazing, really opened me up.
           | 
           | As other comments mention, Rich Hickey's Hammock Driven
           | Design is excellent, amazing. Some deliberateness about
           | figuring out what we are doing, letting the waking mind come
           | up with problems and possibilities, and giving time and
           | written down ideas for the passive/sleeping mind to cycle
           | through options & combine them... Kind of like protein
           | synthesis, a soup of amino acids/ideas and your mind as rna,
           | blindly bumping elements together to see if they bond.
           | https://youtu.be/f84n5oFoZBc
        
         | mhuffman wrote:
         | >One of the great things about working from home is that I
         | often don't do anything. As in, I'm not even by my computer.
         | 
         | >I'm still thinking about what to do, but I'm not implementing
         | anything. I'm not typing stuff, I'm not waiting for a compile,
         | I'm not outwardly moving the project forward.
         | 
         | This is literally the nightmare scenario of middle managers and
         | c-suite managers about wfh employees. You walking around
         | visibly doing nothing and them paying you to do it! Somehow
         | when you do the same thing near your cubicle or in your office
         | you "look like" you're working so that is much better!
        
         | mihaaly wrote:
         | This way, I like to work in the shower or during commute of a
         | crowded bus staring outside. But the best ideas come in the
         | can, office or home bathroom, does not matter. : )
        
         | mewpmewp2 wrote:
         | > One of the great things about working from home is that I
         | often don't do anything. As in, I'm not even by my computer.
         | 
         | Couldn't agree more. I think one major advantage of working
         | from home is that you can go for a walk whenever you feel like
         | it without having to feel guilt or feel like you have to
         | justify it to anyone. Not only is it amazing against stress and
         | for health reasons, but it's also amazing to get another
         | perspective with your thoughts left free to run.
         | 
         | Not to mention all the other productivity and efficiency
         | ruining obligations in the office like having to feel you have
         | to stay until certain time even though at that point it would
         | be more efficient to do something else etc.
        
       | renlo wrote:
       | Agree that the repository/service pattern is a good way to adhere
       | to separation of concerns and make refactoring and readability
       | easier.
       | 
       | That said, I really disagree with any precommit checks.
       | Committing code should be thought of as just saving the code,
       | checks should be run before merging code not saving code. It'd be
       | like Clippy preventing you from saving a Word document because
       | you have a spelling error. It's a frustrating experience.
       | 
       | I can make sure my code is good before I submit it for review,
       | not when I'm just trying to make sure my work has been saved so I
       | can continue working on it later (commit).
        
         | BeetleB wrote:
         | Usually you have those checks when pushing, not committing.
        
         | Foreignborn wrote:
         | Most pre-commits I've seen are usually formatting/prettier.
         | 
         | But if need be, I will spam my commits locally with `--no-
         | verify`. Once the code is ready, I reset to head and remake
         | them as nice, conventional commits.
        
       | firefoxd wrote:
       | What 2 decades of coding taught me is, it all depends on the
       | company. We all aspire to write clean code that scale. But most
       | often then not, you inherit the code.
       | 
       | If you work for a company that is built to sell, you will code
       | fast and break things. Each feature is a show case to future
       | buyers.
       | 
       | If you work with "experts", you will write clean, scalable code
       | that no one will buy. The priority is the code, not the product.
       | 
       | If you are lucky, you'll work in a company that is profitable
       | without a hyped up product. Here you have the bandwidth to
       | refactor.
       | 
       | I've worked in several companies that are built to sell. Tech
       | debt is ignored unless there is a major breach.
        
       | jakelazaroff wrote:
       | Strongly disagree with "Do the Refactoring First". It is
       | inevitable that your project will grow in ways you can't
       | anticipate. If you spend too much time up front on architecture,
       | one of two things will happen:
       | 
       | 1. You build abstractions that are not useful in the future, or
       | 
       | 2. Worse, you build abstractions that _constrain_ you from making
       | future changes.
       | 
       | Of course, either of these can happen anyway, but at least then
       | you haven't wasted a bunch of time refactoring before you know
       | how your code base will grow.
       | 
       | I prefer this approach from The Grug Brained Developer:[1]
       | 
       |  _> next strategy very harder: break code base up properly (fancy
       | word:  "factor your code properly") here is hard give general
       | advice because each system so different. however, one thing grug
       | come to believe: not factor your application too early!_
       | 
       |  _> early on in project everything very abstract and like water:
       | very little solid holds for grug 's struggling brain to hang on
       | to. take time to develop "shape" of system and learn what even
       | doing. grug try not to factor in early part of project and then,
       | at some point, good cut-points emerge from code base_
       | 
       |  _> ..._
       | 
       |  _> grug try watch patiently as cut points emerge from code and
       | slowly refactor, with code base taking shape over time along with
       | experience. no hard / fast rule for this: grug know cut point
       | when grug see cut point, just take time to build skill in seeing,
       | patience_
       | 
       |  _> sometimes grug go too early and get abstractions wrong, so
       | grug bias towards waiting_
       | 
       | [1] https://grugbrain.dev/
        
         | pphysch wrote:
         | Yes the author strikes me as a early/mid career SWE rather than
         | a seasoned professional (10K hours is often used as an allusion
         | to "mastery").
         | 
         | 1. Junior: hack a solution from A to B by any means necessary
         | 
         | 2. Mid-level: wait, design matters. Abstract everything up
         | front!
         | 
         | 3. Expert/mastery: wait, complexity also matters. Consider many
         | paths and finds sweet spot that is simple, robust, extensible,
         | maintainable.
        
           | ilrwbwrkhv wrote:
           | I think the intermediate level, do the refactoring first,
           | clean code mentality is a big one to grow out of.
           | 
           | The ultimate mastery is to think about "what does the
           | computer need to do?" If there is a button click and some
           | data has to be aggregated, those are two operations that
           | should result in two blocks of code changing, the event
           | handler and the db select group by (or other data source).
           | 
           | Everything else beyond it is extraneous code and you should
           | think very carefully if you are adding any line beyond that.
           | 
           | The worst in the typescript world is elaborate types which do
           | not work all of the time. Better to have implicit types doing
           | most of the heavy work and remember you are building
           | software, not doing type system research.
        
             | jakelazaroff wrote:
             | For me, the most important thing in this situation is
             | coupling. The code implementing a feature may be an ungodly
             | mess, but by minimizing its coupling to the rest of the
             | system I make it easy to improve (or remove) later. I would
             | much rather have messy and confusing code that is self-
             | contained than an elegant abstraction with a large blast
             | radius.
        
               | hinkley wrote:
               | And you do that decoupling by...
               | 
               | Refactoring.
               | 
               | So I'm a little confused about why it sounds in this
               | whole thread like we are vilifying refactoring without
               | actually saying we are doing so. It's weird.
        
       | dahdum wrote:
       | > They end-up making there managers happy, yet in the long-run
       | everybody is panicking and they are considering refactoring or
       | even building the application from scratch after 4-5 years.
       | 
       | As mostly a startup dev I've never worked in a company with a
       | runway long enough to afford worrying about a potential rewrite 5
       | years in the future. I've had to rewrite some of the most
       | spaghetti founder code ever, but surviving long enough to do so
       | was a sign of success.
       | 
       | Author isn't wrong per se, but code purity isn't _always_ a
       | worthwhile goal, and needs to be balanced by the needs of the
       | business. Virtually all of the code I've written over the years
       | has been tossed by acquiring companies moving everything to
       | "their stack", acquihire, company shutting down, product pivots,
       | or better 3rd party software becoming available /affordable. I've
       | pushed some trash tier code over the years because it worked just
       | well enough to drive growth/revenue and keep the lights on.
        
         | freefaler wrote:
         | Indeed, my own experience in my several companies confirms
         | this.
         | 
         | Yes, code quality is important, but we write code to solve a
         | problem for the paying customer. If we can't solve it on time
         | and on budget it doesn't matter how well it has been written.
         | 
         | If you survive long enough you'll refactor the parts that are
         | important.
         | 
         | Also some parts are more important than other, everything with
         | money calculation and potential data loss should be written
         | more carefully.
        
           | Spivak wrote:
           | I've always called this "good problems to have." If you're at
           | the point where your slapped together solution doesn't cut it
           | anymore then it means you're successful enough to actually
           | need better.
           | 
           | Don't use the solutions to hard problems when you don't have
           | hard problems yet. Because they're making trade-offs to meet
           | constraints that you're not under. Ranch dressing at the
           | grocery store has to be shelf stable and they make a bunch of
           | compromises to get it to that point. The ranch dressing you
           | make it home can be better easily by just ignoring those
           | constraints.
        
           | f819934580bd48f wrote:
           | > potential data loss should be written more carefully.
           | 
           | Doesn't this apply to any code that touches data intended to
           | eventually be persisted? If so, IMO this applies to a huge
           | portion of all software, I would guess more than half,
           | because writes tend to be much more complex than reads IME.
        
         | haswell wrote:
         | > _I've pushed some trash tier code over the years because it
         | worked just well enough to drive growth /revenue_
         | 
         | With all respect, this summarizes everything I've come to hate
         | about our industry over the years.
         | 
         | I understand _why_ this happens, and I've also been the person
         | churning out crappy code at points in my career. But I think it
         | also highlights how backwards the incentives have become, and
         | we're constantly seeing the real world impact playing out as
         | the next zero day, the next botnet, the next Boeing scandal,
         | etc.
         | 
         | I'm not saying there's never a place for bad-but-working code,
         | but I'm increasingly convinced it never belongs in customer
         | facing products, and that we have a major task ahead of us
         | collectively to correct the mindset behind this and fix the
         | incentive structure that enables this.
         | 
         | Software runs the world now, and a frighteningly large number
         | of software companies do not take their position of power
         | seriously.
        
           | bschmidt1 wrote:
           | Is code more like poetry or more like a recipe? If the
           | former, then yes we should be allowed the time and space to
           | craft the highest syntactic art imaginable. But if it's the
           | latter, it should just be quick, correct, readable, and
           | extensible.
           | 
           | If it's art - _how dare you ruin my masterpiece?_
           | 
           | If it's business - _we had a solution deployed for the
           | customer in less than an hour._
           | 
           | If syntax (poetry) is your #1 take your time. If money is
           | your #1 you wouldn't call it "crappy code" at all. Even code
           | that is not as performant as it could be is only "crappy" if
           | it's affecting the bottom line (which it often does). But so-
           | called bad code that is yielding higher profits, hard to call
           | crappy.
        
             | OrigamiPastrami wrote:
             | > If it's business - we had a solution deployed for the
             | customer in less than an hour.
             | 
             | Boeing was good at finding cheaper solutions to business
             | problems as well. In the end it's society that suffers for
             | our tolerance of late stage capitalism.
             | 
             | There is no "right" answer to this. But tolerating crappy
             | engineering because it's cost effective seems like an
             | admission of defeat to people that actually want to make
             | things better. It's not so much letting perfect be the
             | enemy of good enough; it's more about the steady decline in
             | quality because that's what we incentivize.
        
             | ChrisMarshallNY wrote:
             | I have found that "it depends" is an almost universal
             | solvent for all technical quandaries.
             | 
             | I have found in my experience (and I have a lot of that),
             | that the search for "One Solution To Rule Them All" is a
             | snipe hunt. You can't get there from here.
             | 
             | It _always_ (in my experience) comes down to context[s].
             | 
             | That "[s]" is important. There's the current context, and
             | then, there is the future context.
             | 
             | You survived your baptism in fire to live to keep
             | delivering software.
             | 
             | That's great. It's crap software that got you here.
             | 
             | Time to rewrite it, so we now have software with a future
             | 
             | Right?
             | 
             | OK?
             | 
             | That's what we'll do...right?
             | 
             | Oh, for Cthulhu's sake, what do you mean we need to keep
             | building on our foundation of sand?
             | 
             | Congratulations. You now not only have technical debt; you
             | have technical bankruptcy, coming down the road.
             | 
             | Better sell the company fast, before the bomb goes off...
        
             | cjfd wrote:
             | It is you who starts to talk about 'art' en 'poetry' but
             | these words do not come from what you are reacting to. One
             | thing you seem to assume is that the 'crappy code' works
             | and therefore the concerns about its crappiness must be
             | about irrelevant things like 'art' or 'poetry'. However,
             | the working of what I would consider crappy code is
             | generally highly tenuous. There has not been found a bug,
             | YET...., but one difference between crappy code and good
             | code is that in crappy code one is quite sure there are
             | lurking many bugs that are just waiting for the right
             | circumstances to occur in practice. Also when bad code is
             | changed, this is a much riskier affair because it is
             | difficult to be sure that no unwanted side-effects were
             | introduced.
             | 
             | There is a hypothesis that the crappy code was faster to
             | write. At some point, this becomes false because one also
             | has to spend time fixing the bugs. I would wager that this
             | duration is measured in weeks, rather than months. From
             | which it follows that the picking crappy code for speed is
             | actually foolish and lowers profits for all but the most
             | simple projects.
        
               | bschmidt1 wrote:
               | > must be about irrelevant things like 'art' or 'poetry'
               | 
               | If by "bad code" you mean something related to syntax,
               | convention, or code that "might have bugs" (wtf), there
               | is still a case it's actually "good code" if it's more
               | readable, was a quicker solution that yields higher
               | profits, is a less error prone approach to the larger
               | management of the codebase albeit less performant etc.
               | 
               | > one difference between crappy code and good code is
               | that in crappy code one is quite sure there are lurking
               | many bugs
               | 
               | Sounds too superficial/judgmental and not evidence-based.
               | If there is a bug there is a bug. Even perfectly written
               | code to the best possible standard can still be code that
               | does the wrong thing.
        
             | andrepd wrote:
             | > so-called bad code that is yielding higher profits, hard
             | to call crappy
             | 
             | Missing the point of the person you're replying to
             | _entirely_... Yes you can get higher profits with shittier
             | code, just as you can by building shittier airplanes, cars,
             | bridges, etc. The consequences being exploits, hacks,
             | 737MAX, Ford Pinto, etc
        
               | bschmidt1 wrote:
               | I think you missed the point that it wouldn't actually be
               | shittier code in that case.
               | 
               | Some ugly 4 space indented, wrong kind of loops, old Node
               | version, mongo as the main db, no linter, callback hell
               | SaaS platform in 1 file called "server.js" could still be
               | more reliable and yield higher profits and sooner than
               | your masterpiece in Rust.
        
           | mihaaly wrote:
           | Those shipping fast and lot write software not to use but to
           | sell. Not for the user but for sales and marketing
           | departments. And this is why software and programmers are not
           | respected, rightfully so. Judged by their products. And
           | software are crap (and then reasoned with vigour why crap is
           | good by those having incentives in it). Much more time than
           | not, the not is the exception nowadays.
           | 
           | Those having too little resources (money) for their
           | monumental ambition also ship fast.
           | 
           | Also it is so f annoying. All those river of notifications
           | about 'hey, brend new version, now!, stop everything and
           | download right away or else!' is a great nuisance. Like if
           | this was the center of the life of the user, to have the
           | newest and prettiest and greatest new feature (or mostly
           | fixup of f*ups) of the software used. Secret for developers:
           | no one cares. They need a tool to do the thing, and that's
           | it. Do it well, do it smooth, that's all that counts. Not the
           | new versions. Please write it well in the first place instead
           | of this endless tinkering and bugging the customer.
           | 
           | Sipping too fast is some sort of premature ejaculation of the
           | programmers' mind.
        
           | dyauspitr wrote:
           | Well most places putting out code for the first time don't
           | have the luxury of spending the time to put out perfect code.
           | The funding only lasts so long, you're trying to outpace
           | competitors, you end up getting continuous scope creep etc.
           | Star Citizen is a great example of what happens when you want
           | to get everything perfect before you release it, by the time
           | you're done someone else has eaten your lunch.
        
           | fabian2k wrote:
           | One big problem is that you often don't know yet what you
           | actually need, you only find that out when your software is
           | in front of real users. So the later versions might be
           | substantially different than your MVP. Building a very robust
           | first version might be entirely useless if you have to throw
           | away most of it after discovering it doesn't actually solve
           | the user's needs.
        
         | fidotron wrote:
         | A former colleague of mine had a good way to describe it:
         | technical debt is like financial debt, too much will kill you
         | but if you don't have any you will be outgunned by those that
         | do.
         | 
         | The trick is how to manage tech debt properly, and the
         | widespread scrum fake-agile in use provides no means for ever
         | tackling tech debt once taken on. This is one reason for the
         | explosion in SRE teams.
        
           | marginalia_nu wrote:
           | > A former colleague of mine had a good way to describe it:
           | technical debt is like financial debt, too much will kill you
           | but if you don't have any you will be outgunned by those that
           | do.
           | 
           | Yeah, this is a very astute observation.
           | 
           | It's also worth noting that the cost of technical debt is
           | higher for larger organizations. Refactoring is very cheap
           | when you're just one or a few people, but prohibitively
           | expensive to the point of impossible when working in a much
           | larger organization.
           | 
           | I think it's generally a bad idea to write code to large-
           | organization standards when you're working alone. It makes
           | your process much more rigid than it needs to be. The great
           | benefit of flying solo or with a small team is exactly how
           | nimble you can be, the small cost of re-writes and even
           | throwing stuff away.
        
         | bigstrat2003 wrote:
         | > Author isn't wrong per se, but code purity isn't always a
         | worthwhile goal, and needs to be balanced by the needs of the
         | business.
         | 
         | I would phrase this slightly differently: code purity is always
         | a worthy goal, but it's not always an _attainable_ goal. As you
         | said, sometimes the needs of the business have to get in the
         | way even though it is a worthy goal.
        
           | mewpmewp2 wrote:
           | It is a potentially misleading to think of it as a goal in
           | terms of raw calculations.
           | 
           | If we parallelize it to debt should it be your goal to have 0
           | debt and why?
           | 
           | Shouldn't you first consider what is the interest rate of
           | that debt and what do you gain by having this debt as opposed
           | to not having it?
           | 
           | If debt has 0% interest, and you don't have limit on debt,
           | why not just keep taking debt? What if debt has negative
           | interest?
           | 
           | The goal should be to determine what is the optimal approach
           | after considering all those factors and then take those
           | approaches.
           | 
           | Some people have principles that they don't want to owe
           | anything to anyone, but this will make them take suboptimal
           | decisions. They assign this emotional value to something that
           | is actually an arbitrary concept.
        
       | neeleshs wrote:
       | In my 25+ years of experience, any code you write today, however
       | beautiful you think you wrote it, will get stale in a few years
       | and has to be changed/enhanced to adapt to the new reality.
       | 
       | With experience, you learn to find balance between pragmatism and
       | purity more often than not. You will still not always be right.
       | 
       | It is all still a mix of skill, experience, team and external
       | factors.
        
         | hinkley wrote:
         | When I'm working in lower-case c clean code, the amount of
         | friction due to regrettable decisions made before everything
         | became clear is unfortunate but manageable. When we have
         | decisions that aren't just regrettable but daunting (how on
         | earth am I going to unravel this warren of pain and stupidity
         | enough to get this thing to do what it's supposed to do and
         | _only_ what it's supposed to do??) then the full weight of the
         | sins of the past hits, and we start making proclamations and
         | resolutions about Never Again.
         | 
         | You don't have to run away from the falling axe or ban axes.
         | You need to not be there when it falls. And in the context of
         | software what that looks like is very difficult to explain
         | without ascribing unnecessary or even misguided qualities to
         | the differences. We keep describing analogs, symptoms or
         | harbingers of the real problem, and those fall down or
         | distract.
        
       | wslh wrote:
       | As someone who frequently follows HN and Reddit threads, I've
       | noticed that while many interventions are discussed (like
       | supplements or diets), nothing truly beats physical activity for
       | improving well-being--unless you have a legitimate medical
       | condition preventing it. Of course, sample size = 1, and
       | everyone's different, but this has been my experience.
        
       | sobellian wrote:
       | You should usually wait to refactor until _after_ you write the
       | code and preferably ship it to someone.
       | 
       | You may not understand what makes a correct implementation. Don't
       | waste time refactoring incorrect code.
       | 
       | You may not understand what makes a performant implementation.
       | Don't waste time refactoring code that's too slow.
       | 
       | You may not understand what the user wants. Don't waste time
       | making something no one wants.
       | 
       | You may not understand how the software needs to evolve. Don't
       | waste time making something extensible in a way that will never
       | happen.
        
         | muspimerol wrote:
         | It's important to note that this is only really relevant advice
         | for a specific type of startup that is still trying to rapidly
         | iterate to find product market fit.
         | 
         | Personally I find it incredibly annoying to work on and with
         | with products that were developed like this. There are so many
         | half baked features that technically "work" but are slow, buggy
         | or difficult to integrate with.
        
           | sobellian wrote:
           | It's relevant if you need to rapidly iterate, period. The
           | test is not whether you work at a start-up, but how well you
           | understand your problem. I am currently doing a lot of
           | automated design work with optimization over highly non-
           | convex constraints. Good luck writing that without rapid
           | iteration.
        
         | hinkley wrote:
         | One of the very frequent challenges I have with optimizing
         | code, is that unless the problem is very highly contained,
         | first I have to look at this code that's all over the place,
         | both physically and emotionally, and just try to figure out wtf
         | it's actually trying to do. I can't replace it unless I know
         | the requirements. The intent.
         | 
         | Give me a piece of code that's wrong but clear about it, and
         | we're good. I can get in and out and move on to the next most
         | tricky:value ratio's problem.
         | 
         | Refactoring it to that point will always pay dividends. Even if
         | it's just for the next person trying to add more functionality
         | in this area.
        
           | sobellian wrote:
           | I don't think you necessarily need to optimize before you
           | make the code "clean" but you should at least understand what
           | it will take to make it performant. This is a stronger
           | requirement than it might sound like since most programmers
           | are quite bad at predicting what will perform well without
           | profiling first.
           | 
           | So knock together a prototype and profile _that_ to
           | understand what the bottlenecks are in your program, then you
           | have an informed baseline of how the program needs to fit
           | together to function well.
        
       | DangitBobby wrote:
       | Commit hooks are not the place for test checks. You want
       | developers to commit and push work so they don't lose it to
       | catastrophic disk failure, theft, etc. Instead, test on push, or
       | before merging. If you like to enforce "atomic commits", well,
       | there's always interactive rebase.
        
       | iveqy wrote:
       | I strongly disagree. You should always keep the code as simple as
       | possible and only add abstractions once you really need them.
       | 
       | Too many times I've found huge applications that it turns out be
       | most scaffolding and fancy abstractions without any business
       | logic.
       | 
       | My biggest achievement is to delete code.
       | 
       | 1. I've successfully removed 97% of all code while adding new
       | features. 2. I replaced 500 lines with 17 lines (suddently you
       | could fit it on a screen and understand what it did)
       | 
       | Also: https://www.youtube.com/watch?v=o9pEzgHorH0
        
         | halfcat wrote:
         | Yes. Battle future unknowns by remaining simple and flexible,
         | not by trying to predict the future.
        
       | jilles wrote:
       | Lost me at 99% is developer experience. There is so much more
       | philosophy involved in what makes good software.
        
       | makach wrote:
       | Of course we need viewpoints from that perspective as well. It's
       | a balancing act- I've met too many proud developers who never
       | shipped because the idea of perfection. If in doubt, do a risk
       | assessment. Take time to review and evaluate what to do.
        
       | henning wrote:
       | > I've been an engineer for over 7 years now. I have worked on
       | countless projects
       | 
       | If you've worked on countless projects in 7 years, that means no
       | single project was that big or long.
       | 
       | > Refactoring a relatively big software, for example, with over
       | 70,000 lines of code, can take 30-40 hours
       | 
       | I admire the author's ability to casually introduce completely
       | arbitrary definitions of "relatively big" and that "refactoring"
       | 70,000 SLOC only takes "30-40 hours" without giving any
       | information about what the nature of the refactoring is.
       | 
       | > Now imagine if we didn't implement a good architecture from the
       | beginning
       | 
       | This post does nothing to define what "good architecture is" or
       | prove that adding additional indirection helps anything. Code re-
       | use is about more than just not putting query and service call
       | logic in a controller method. The contrived examples about adding
       | logging to a codebase that has no logging (why does the app have
       | no logging? why does it need to be added now when it didn't
       | before?) only makes sense if every part of the application
       | conforms to the same interface you've introduced. Considering
       | that a large application may have many different features and do
       | lots of different tasks, this may not happen in which case you
       | need one interface for each situation or create some stupid
       | abstract thing that can handle everything.
       | 
       | The stupid pre-commit setup makes it impossible to share a branch
       | you're working on if you can't figure out why a test won't pass
       | and want to get help from someone on your team. Or you have a WIP
       | codebase where tests are broken and want to pass it off or show
       | it to someone else.
        
       | diffxx wrote:
       | I agree with the author that slow can be good and that taste and
       | diligence can trump raw smarts.
       | 
       | I think what is often missed though is the opportunity cost of
       | shipping bad products. Our industry lionizes fast delivery to
       | juice short term earnings but this is very often at tremendous
       | long term cost. When your revenue depends on shoddy products, you
       | must devote an excess of resources to patching the holes that are
       | slowly sinking your ship. The best people will tire of this and
       | jump aboard the next vessel that offers better working conditions
       | and/or higher compensation. But of course one never escapes the
       | fundamental problems by job hopping.
       | 
       | To build something great, reliable and high value takes time. If
       | it were easy, the market would be awash with cheap high quality
       | products. It clearly isn't.
       | 
       | For things to improve, I believe that a small group of workers
       | will likely need to join together and sacrifice short term
       | earnings to build viable long term companies on a different set
       | of ethics and values. I have personally made this sacrifice and
       | am working on something I think is great and valuable that I
       | could not possibly do within a typical company.
       | 
       | I have optimism that soon alternative approaches to building
       | companies will emerge outside of the current VC funding model,
       | which I believe has run its course. There are many, many software
       | developers who are wealthy enough to sacrifice short term
       | compensation to build more equitable companies with longer term
       | vision and with a much higher ownership percentage that will pay
       | off in the long run.
        
       | klodolph wrote:
       | I don't know how many k hours of coding I have. 10k is long in
       | the rear-view mirror.
       | 
       | My advice? Ship fast. The way you get good is by being fast.
       | 
       | Think of two junior engineers, we'll call them Uno and Dos. Uno
       | is working hard on a feature and wants to get it working, and
       | working right. Uno spends two full weeks working on it and then
       | sends out a PR. Dos starts by thinking "fast", and figures out
       | how to send a PR within only two days. This PR is, of course,
       | horribly incomplete. Uno's PR is bogged down in review because
       | there are major problems. Dos, on the other hand, gets some
       | really quick feedback from the team lead saying "you can extract
       | this function and write a test for it, please do that."
       | 
       | The same applies not only to junior engineers working on a small
       | scale within a team, but to large scale projects being shipped by
       | the whole team. Ship it fast, get feedback fast, and let it blow
       | up in your face if you think you can survive the consequences.
       | 
       | The same applies to me. The best stuff I have ever shipped has
       | been shipped fast and fixed afterwards.
       | 
       | If you want to raise the quality of your code, the way you do it
       | is by meeting the requirements _fast_. If you beat the clock when
       | it comes to baseline requirements, you get extra time to refactor
       | and redesign components.
       | 
       | There are also a million things you can only learn by shipping
       | code. Learn those things sooner; ship fast.
        
         | npalli wrote:
         | This whole thesis rests on the team not knowing what to build
         | and shipping fast to get more learning cycles. Works if you
         | don't know anything (said juniors) or new fields (like internet
         | or social or mobile etc.). Lot of places (including formerly
         | new fields) that is not true anymore. Not everything is move
         | fast and break things - which was Facebook's motto until 2014.
        
           | klodolph wrote:
           | I say this is wrong, and the true reason to ship slower is
           | when shipping something wrong is catastrophic.
           | 
           | Let's say you are making something well-understood like a
           | PCB. To me, the "ship fast" option is to make a prototype PCB
           | fast, even if it doesn't meet the design constraints (say,
           | size, power consumption, cost),
           | 
           | That's because very few things we build are so well-
           | understood that you can design and then ship. Development is,
           | in its most ideal form, highly iterative and incorporates
           | data from the field as soon as feasible. In the PCB design
           | scenario, we want the prototype sooner because we can learn
           | things like "this design is too sensitive to EMI", which may
           | necessitate a redesign or at the very minimum re-spinning the
           | PCBs.
           | 
           | PCBs are very similar to ICs. ICs get fewer prototypes and a
           | more careful shipping process because it can cost millions to
           | do a new stepping. Not because IC design is poorly understood
           | or mysterious, but because mistakes are costly. That is the
           | real reason you would slow down. Maybe you spend more time
           | and money doing simulations for your ICs, maybe you have them
           | go through more design reviews.
           | 
           | Likewise, shipping a bad medical device or bad space probe is
           | usually catastrophic.
        
       | fsndz wrote:
       | on the contrary, ship fast, survive, then refactor later. there
       | is no need for premature optimisation.
        
       | redbell wrote:
       | > Most people think that great engineers are magicians who build
       | applications _in a unique way that no one can understand._
       | 
       | This reminds me of _Ninja Code_ : https://javascript.info/ninja-
       | code
        
       | jondwillis wrote:
       | From the looks of the "good" code referenced in this article,
       | maybe the author needs another 10k hours. `data: T | any` lmao,
       | just WHY? why try to use generics if you're going to allow any..
        
       ___________________________________________________________________
       (page generated 2024-09-21 23:02 UTC)