[HN Gopher] Throw away your first draft of your code
___________________________________________________________________
Throw away your first draft of your code
Author : herbertl
Score : 153 points
Date : 2023-08-04 18:31 UTC (4 hours ago)
(HTM) web link (ntietz.com)
(TXT) w3m dump (ntietz.com)
| lxe wrote:
| Throw away 1st, second, third, etc... Write your code in small
| replaceable/disposable POCs until at some point the architecture
| and coherence starts to take shape.
|
| That's the advantage of software over other work. You have 0
| material sunk costs. Unlike building a bridge, which you can't
| just tear down and iterate, with software you can develop a
| workflow where you break things and iterate quickly.
| tracker1 wrote:
| There are of course software systems with a very large bit of
| complexity and entrenchment... least of which the complexity
| added in order to avoid said entrenchment in the first place.
| 3cats-in-a-coat wrote:
| Or maybe keep it and tell GPT to refactor it. Soon.
| coolliquidcode wrote:
| I think sometimes it's a good idea to use a language the company
| doesn't use internally to prototype. Like we don't use python or
| node in production, but a lot of stuff can be POCed in those
| languages/frameworks without a learning curve.
|
| It forces you to throw out the old code and forces you to think
| the problem out in different ways.
|
| Also, in my experience the POC does enough that it turns into
| just use POC because of the illusion that it would be faster to
| use than to rewrite. Then it's a span of time fighting edge cases
| and added features thought of afterwords till it passes all
| testing. Then you have a battle tested piece of code you can't
| get rid of, difficult to understand, and ridged for changes.
| thescaleofit wrote:
| Exactly what I thought after GPT3.5 was released. "Delete it all.
| Start from scratch. You'll learn so much. You'll do so much
| better. You'll actually live up to the scale of your creations'
| potential."
|
| But a decision like that would be superhuman by itself, a
| transcendent experience, giving the creators a perspective that
| seems impossible. Unlike what is happening instead, both publicly
| and behind closed doors... A great pity!
| orthecreedence wrote:
| I've never had luck with this approach. For me, iteratively
| building and changing the codebase as new requirements come up
| lends itself to having to think of good ways to modularize and
| future proof. The idea of throwing out the code and starting over
| is definitely appealing, but often the iterative approach gives
| me something I'm super happy with.
|
| I think I do use the throwaway approach with simple prototyping
| of smaller portions of code that I will then port into an
| existing system, but the overall system remains stable.
| moonchrome wrote:
| If you're discovering requirements along with developing code
| you often end up with Frankenstein's monster because things
| that were intended to do one thing got retrofitted to do 4 more
| things. It works but if you had all 4 things in mind when
| designing the first approach it would have been much cleaner.
| And going forward it keeps getting worse.
| danielovichdk wrote:
| Funny how Fred Brooks keeps repeating history.
|
| I am just watching as the young and optimistic learn the hard
| truth.
|
| Build one to throw away - mythical man month.
| jpswade wrote:
| I like the idea of "Spike and Stabilise".
|
| Which means, prototyping in this way, but at the point it is
| actually delivering value, stabilise.
|
| Of course, it's never as simple as that, but there's certainly a
| place for this technique.
| stormdennis wrote:
| Not on this scale but it has happened to me on a few occasions
| that I've lost several hours work for some reason (including no
| autosaves).
|
| After the initial despair I know from experience I need to
| quickly try and recreate what I've lost while it's fresh in my
| mind.
|
| It takes much much less time and I always feel that I've done a
| cleaner job second time around.
|
| At times like that has occurred that this is the way to do it but
| I've never been able to bring myself to adopt this as policy.
| davidkunz wrote:
| I like to build my first version in one file with as few
| abstractions as possible. No helper functions, unless absolutely
| necessary, just straight-forward code. Building good abstractions
| later on is a lot easier than starting with wrong ones in the
| first place.
| krembanan wrote:
| I've always done it like this as well. Initially I did it for
| the most obvious reason: it gave me the working software that I
| needed the fastest. Then later on, I always found it to be the
| best way to find natural abstractions as you go.
| hot_gril wrote:
| This is an underrated way of doing things that I've come to
| appreciate over time. Heck, I'll even go live with the all-in-
| one-file thing until there's a reason to split it up. It's all
| peanuts anyway compared to bigger decisions like what API,
| DBMS, DB schema, other deps, libs, etc you use.
| avgDev wrote:
| Very interesting approach. As someone who has overengineered
| last major project I worked on......maybe this is the way. I
| got so fixated on getting it "right" using current standards
| and abstractions that it became a bit of a mess. I despise
| working with that code base now.
| superb_dev wrote:
| I'm gonna second this. Just build it first and add the
| abstractions as they become obvious
| nraf wrote:
| We do this occasionally as a tech spike - if there's a lot of
| uncertainty or if we need to evaluate between a couple different
| approaches, we'll dedicate 2-3 days to hacking away with the aim
| of lifting the "fog of war".
| varispeed wrote:
| I try to structure my code so that it can be easily tested and it
| is modular enough so that you can swap implementations with fair
| ease.
|
| This means I can iterate much quicker - I can have code that
| works and is good enough for now and I can later on improve it
| and also I can suitable test coverage that can confirm the new
| improved implementation works as expected.
|
| Code that is organised this way is also rather easy to understand
| and test perform a function of documentation - which means
| someone else can get familiar with it and work in a short period
| of time.
| jchanimal wrote:
| I'm in the middle of this with my new database startup. The alpha
| was written to gather requirements, so I intentionally skimped on
| code quality as it could be a waste of time. Now that I know the
| domain inside and out, the beta rewrite is worth turning up the
| quality. And it's so fast and easy to write, as the old code
| serves as api documentation for all the low level stuff it
| depends on.
|
| I recommend you do this too.
| neverthe_less wrote:
| I've never respected this advice, even though I hear it often
| enough. The reasoning appears to come down to this:
|
| > If you know that you're possibly keeping the code, you do
| things in a "proper" way, which means moving slower
|
| combined with the idea that it's faster to redo work than it is
| to refactor.
|
| I don't buy either of these propositions as a universal rule. For
| the first, it seems that a mindset of avoiding premature
| optimization, which you should be cultivating anyway, is enough
| to ward it off.
|
| For the second, I see it as very context dependent, with my bias
| going towards refactoring instead of rewriting. I most often get
| things right enough the first time that it really only needs to
| be refactored going forward. Only when I end up with serious
| flaws do I decide to start over, often before I finish my
| implementation because the flaws are already apparent enough. Add
| to this that even very large changes can be refactored
| effectively and timely in my experience, and I feel like the bar
| for rewriting is really high to be cost-effective.
|
| Unfortunately this essay and many others seem to take objections
| like mine for granted, and I should just believe the author that
| rewriting is faster with zero supporting evidence.
| tracker1 wrote:
| I'm largely with you on this... do the simplest thing that gets
| a job done, that you assume will be replaced, and don't be
| surprised when it's still un use a decade or more later.
| iraqmtpizza wrote:
| looking for gaping security holes is premature optimization. if
| you run into security problems down the line, use a security
| profiler and find the hot spots i.e. radioactive code
| wizofaus wrote:
| > looking for gaping security holes is premature
| optimization.
|
| I won't approve a PR if I notice such a thing (and if it
| really is "gaping" I'd expect an automated tool to flag it
| and fail the build anyway). I don't really see ensuring your
| code follows basic secure SDLC best practices as
| "optimisation" at all - in fact it often comes at a
| (hopefully small) cost of less than optimal performance. Of
| course there may be areas of software development (hobby
| projects etc.) where security is not a priority at all, but
| if it's code you're being paid to write that runs on the
| cloud or your customer's machines then security is absolutely
| worth getting right from the get-go.
| programzeta wrote:
| I think this depends greatly on the product area and ease of
| updating. Removing problems _categorically_ from designs
| early has been valuable to me in the past to reduce surface
| area, avoid impossible refactoring, and eliminate systemic
| bug classes.
| bee_rider wrote:
| Usually I think it is unnecessary, but you might want to
| include the "/s" marker in this case. It is just close enough
| to believable that someone would think this, given the amount
| of insecure trash products that have been released...
| wpietri wrote:
| I definitely disagree with you on the first point.
|
| Setting aside the part that's just fussbudgetry, I think
| "proper" coding is about doing things that pay off in the long
| term even if they feel burdensome now. As an example, I'm a
| huge fan of good automated tests for long-lived code bases. But
| if I'm just writing a quick, throwaway script, then building a
| bunch of automated tests are going to slow me down.
|
| Throwaway prototypes are another area where you can save a lot
| of effort if you have really committed to throwing the code
| away once you've learned what you set out to learn. As a
| physical analogy, before the Long Now built out their bar/cafe
| space in San Francisco [1], we spent a day in the raw space
| building furniture and walls out of cardboard and tape [2]. It
| let us get a real sense of how the designs would work in
| practice for actual use of the space.
|
| In the past for a number of projects I've done throwaway
| prototypes and then started fresh with "proper" engineering,
| which for me usually includes pairing, test-driven development,
| and continuous deployment. I've also done ones where we think
| we understand it enough and just start building. And either
| way, we usually end up evolving ways to prototype on top of the
| existing platform via feature flags, etc, so we can learn
| something from the real world and then decide whether or not we
| want to refactor to accommodate a major change.
|
| [1] https://theinterval.org/
|
| [2] https://vimeo.com/73959127
| neverthe_less wrote:
| Using boxes is great! The beauty of coding is that those
| boxes don't need to be discarded, we have the virtual power
| to transmute them into real chairs and tables via the power
| of refactoring. It's like Photoshop vs. watercolor. I'm going
| to sketch either way, it's just a matter of what the bar is
| for throwing it all out, and I think it's very often
| sufficient to decide in the moment in a virtual environment.
| That's all to say, going back to my first point, I don't need
| to decide ahead of time whether the code will be kept, I'm
| going to keep it loose either way.
|
| And there are situations I'd go in assuming I'll probably
| rewrite the work, but I wouldn't set the criteria so broadly
| as to cover literally whatever the next large project I
| embark on will be, as the article suggests.
| josephg wrote:
| > I most often get things right enough the first time that it
| really only needs to be refactored going forward.
|
| I think it really depends on your values and what you're
| working on.
|
| If you have the mindset of a product engineer, the thing you
| care the most about is how well the software works for your
| users. The code is an unfortunate necessity. When I build react
| apps, I tend to think like this. The code I write first go is
| often good enough to last until the next redesign of the UI.
|
| By contrast, if you're thinking of the code as a home you build
| for your work that you will live in, then having a tidy home
| becomes its own reward. Good decisions today (in terms of
| cleaning up or refactoring code) should lead to more velocity
| later. When I think about building a database, an OS kernel or
| a compiler, I think like this. When I start, I don't know where
| my code should be rigid and where it should be flexible. My
| first guesses are usually very wrong.
|
| Personally I prefer the latter kind of problem. I like it when
| there's no obvious way to structure my code and I have to
| explore while I work. The code I'm most proud of writing has
| probably been rewritten 5 or more times before I landed on the
| "final" design. The "right" abstractions are rarely obvious at
| first glance and the search can be incredibly rewarding.
|
| The rich history of application programming abstractions
| suggests it isn't exempt from this either. It's just, when
| you're building a UI there have been an awful lot of explorers
| who came before you and can show you the way.
| neverthe_less wrote:
| I agree that it depends on factors like what you describe
| which is why I am asking those giving the advice like this to
| consider the context at all. I also happen believe that the
| contextual bar should be placed high. I have to say, what
| comes to mind when I read your comment was "What about this
| does refactoring not accomplish?" In the metaphor of building
| a house, refactoring is what keeps it tidy and organized, and
| rewriting would only appear necessary in the case of your
| trash chute leading into a bathtub or some other critical
| design flaw that could only be addressed timely by
| redesigning the entire house.
|
| If you are in a context where you are in danger of making
| critical design flaws often, or where circumstances make it
| hard to make changes after committing, then I absolutely
| agree that rewriting is effective. That's just what I mean by
| a high bar, one that I personally don't encounter very often
| in my work.
| [deleted]
| AtNightWeCode wrote:
| I think the author mixed up prototyping with proof of concept. A
| POC should be tossed out. I think most companies expect at least
| the senior devs to be able to write a feature on first try.
| myth2018 wrote:
| Currently I'm writing mostly C and C++ and I find it very useful
| to write prototypes, either in the target language or in Python,
| to experiment with ways to modularize the code and how the
| modules will communicate.
|
| I only disagree with throwing the code away. On the contrary,
| sometimes I even use the last prototype as a sort of "executable
| documentation".
|
| That strategy indeed saves me a bunch of time. However, at least
| in my experience, I didn't have success applying that to modern
| front-end dev: the complexity is frequently so high and the dead-
| ends are so numerous that I prefer to buckle-in for the rough
| ride and proceed to the code right away.
| darkmarmot wrote:
| I don't throw it away, I keep it as a reference. But for anything
| interesting, I might rewrite from "scratch" three times easily.
| fritzo wrote:
| I've been following this flow where I write a few successive
| versions and perform refactoring steps to move one version
| "towards" another version, as if there is a conceptual force of
| attraction. It's often unclear which version will prevail, as
| if I'm acting out a genetic algorithm with a small population.
| toss1 wrote:
| Go further.
|
| One test is worth ten thousand opinions. What are a thousand
| tests worth?
|
| _Plan_ to build and deliver an expedient first version, then
| have a technical debt jubilee before building the second.
|
| Build v1 in the most reasonable expedient (including not-scaled-
| up) way to deliver a reasonably full first feature set. See how
| it runs, what the users like/dislike/need/want, where are the
| rough edges both externally & internally, what the load cases
| look like, on various components, etc.
|
| You'll find 80%-90% of your surprises with this.
|
| Now, use your quickly-won knowledge of your actual system to plan
| and build the durable and scalable version.
|
| Despite my intrinsic approach having always been about planning,
| generalizing, etc. (premature optimization?), I was fortunate
| enough to be in a situation in one startup where I decided to do
| this, and it worked out amazingly well. V1 got out fast, without
| worries about tech debt. Building the 2nd version based on actual
| knowledge and and the v1 tech debt jettisoned, allowed a 'real'
| version to get out faster and better.
|
| There may be some problems with mgt politics, and it interfered
| in the above product also, but it does have much to recommend it.
| waffletower wrote:
| Another untenable programming ethic used as a clickbait title.
| jimnotgym wrote:
| I see. A new generation discovers Extreme Programming!
| snailtrail wrote:
| [dead]
| m463 wrote:
| I can't load the page.
|
| https://web.archive.org/web/20230804183217/https://ntietz.co...
| sambull wrote:
| Someone said that to me once.. I just accidentally always end up
| with it in production.
| mattbis wrote:
| I have the observation:- first version is never the best it will
| work with bugs, then you iterate and improve structure and arch.
| The third is the best. No time to waste doing that.
| treprinum wrote:
| You throw your first draft away, you go straight to the second-
| system effect:
|
| https://en.wikipedia.org/wiki/Second-system_effect
| sideproject wrote:
| Well, maybe not throw away everything, but I understand the
| principle. There are also other areas where this could help - and
| one of them is "naming". Sometimes when you start a project, you
| don't really know what the best names are for things. Project
| name, repo name, service name etc. So you choose something that
| you think it's ok and you go ahead. As the project progresses,
| you realise you've named things wrong, but renaming is so
| annoying and tedious. Often we ignore the bad names because it
| doesn't seem significant. But names are how people burden their
| cognitive load (an example, we named our repo after planets
| rather than describing what the repo does - "acme-customer-
| module-frontend" but we named it "pluto" - now everyone has to
| remember what pluto is and make sure pluto is not neptune).
| waffletower wrote:
| The article describes a potentially useful exercise that might be
| explored by an organization that has allotted development time
| for a hack-a-thon or some such. Depending on the size and scale
| of the projects that a software team typically develops, a more
| realistic approach might be to spend smaller and more manageable
| chunks of time as a team evaluating recently developed
| features/services/apps and directly applying improvements gleaned
| into the planning of subsequent projects.
| GMoromisato wrote:
| I'd rather do the Ship of Theseus thing and just harden the
| prototype as required, and only when faced with real-world
| evidence.
|
| The problem with rewriting is that sometimes you face second-
| system syndrome[1] where you overengineer everything.
|
| Believe me--it happened to me at Groove Networks after Lotus
| Notes (ask your grandparents about that).
|
| [1] https://en.wikipedia.org/wiki/Second-system_effect
| fritzo wrote:
| Yet I find when rewriting from scratch there's a countering
| force of simplification where I find myself thinking "We spent
| way too much complexity on that part, and we can entirely do
| away with that other part, and we turned out never to use
| features X and Y."
| bell-cot wrote:
| > "...and we turned out never to use features X and Y."
|
| THIS. Often, the best way to start the rewrite is to go
| straight to the database, and start asking "what allowed
| values for all these fields have never actually been used?".
|
| EDIT: Whether it's rewriting, or refactoring, or adding some
| "if( Deprecated_Feature_Allow !== true ) ... ErrorDie(
| Feature_Deprecated )" logic here and there, or updating
| training material, or whatever - knowing that
| Software_Feature got ~zero real-world use is d*mned useful.
| GMoromisato wrote:
| Agreed--every software engineer I know loves deleting
| useless code.
|
| But this is not incompatible with refactoring instead of
| rewriting.
| GMoromisato wrote:
| Yeah, that makes sense too.
|
| I think it just boils down to "keep writing systems and
| you'll get better at it." But there's no bait on that kind of
| link.
| EdSharkey wrote:
| The psychology of knowing ahead of time you'll delete all the
| code is interesting. Devs would be in hack-hack-hack mode and not
| worry about design - the goal is just explore all the territory
| to find the hilly parts and landmines. Move as quickly as
| possible and report back.
|
| In general I think developers value their code too much and
| should be willing to scrap and rewrite, especially whenever
| requirements are changing. I chalk it up to everyone's desire to
| conserve mental energies due to not understanding what their
| energy peak/limits are.
| Tade0 wrote:
| I have a similar process, but I do it after hours because I treat
| it as _exercise_.
|
| The task isn't about what the resulting system does, but _how_ -
| the aim is to figure out where certain patterns are applicable
| and where they break down.
|
| Ideas include: using a design pattern like Entity Component
| System, exploring whether a certain way of formatting code is
| actually more readable, producing a drop-in replacement for a
| small utility.
|
| I firmly believe this makes you an overall better programmer.
| That being said I think it would be wise to refrain from doing
| that at work.
| progmetaldev wrote:
| This is the exact technique I used that made me a better
| developer. I would take on the task of rewriting code in my own
| time (small team where my rewrite didn't affect others). There
| were times where I misjudged how difficult the rewrite was, but
| I stuck with it and took it as a learning experience to make
| sure next time I thought things through further before moving
| ahead with a complete rewrite. Now that I'm more experienced, I
| tend to get more important (and difficult) projects, and no
| longer attempt the large scale rewrite. I do definitely throw
| away portions of code and rewrite, though. I think there's a
| balance to achieve.
| jes5199 wrote:
| yeah but I often end up getting Second-system effect
| https://en.wikipedia.org/wiki/Second-system_effect
| CollinEMac wrote:
| I've seen the theory that this is why changing to a new
| framework/language seems like magic so much of the time. That
| it's not so much the differences in the technologies as it is
| your knowledge of the problem.
|
| It's probably a little of both in reality but it's an interesting
| idea.
| ChrisMarshallNY wrote:
| I have found that this kind of advice does not play well with
| managers (but it's actually not a bad thing to do).
|
| I'm fairly grateful that I've retired from the rodent rally, and
| am working at pretty much my own pace and structure.
|
| About six months ago, I tossed out the code for the frontend of a
| project that I'd been developing for over a year and a half (at
| that point). I distilled the business logic into an SDK, brought
| in a designer, and started over from scratch.
|
| The result is ten thousand times better than what we had (and
| were considering shipping), a few months ago.
| mav88 wrote:
| Plan to throw one away. You will anyway. - Fred Brooks, The
| Mythical Man Month.
| einpoklum wrote:
| Yeah, well, good luck convincing most manager I know to plan for
| a phase whose outputs get tossed away. They would really much
| rather the prototype code gets merged, and then just work. Not to
| mention the fact they never let you "do things more properly", if
| they can help it, because you are again wasting precious time
| which could be used to do other work from the ever-growing
| backlog.
|
| As for my own projects - if I both "write things more properly"
| and divide them into small parts, it's easier to just keep the
| code I wrote for doing whatever it is I had it do; and maybe at
| some point collect enough of that to make a library, or at least
| a reusable header.
| Havoc wrote:
| Not sure that level of absolute is the way to go.
|
| If you build a prototype and happen to nail it then why not
| iterate?
|
| Or perhaps you wrote a prototype and specific components/module
| feel sound?
|
| Authors suggestion feels sound as a question you should ask
| yourself & seriously consider, more than a strict principle.
| Jeff_Brown wrote:
| Justify wasteful things you've done and suggest them to others.
|
| Less cheekily -- it's true that sometimes the best way to
| research a topic is by writing code that you might appropriately
| throw away later. And it is extremely important to be able to
| recognize when something is not worth keeping. But also, often,
| the most efficient strategy is to think about the problem off-
| screen enough that you don't subsequently waste time on-screen
| writing things you won't keep.
|
| It seems strange to usually expect to throw away your first
| draft. Not every problem is that hard, and even for hard
| problems, not every first attempt is wrong.
| mtkd wrote:
| Often happens that you can't see the next hill until you get to
| the top of the current hill
| hackan wrote:
| I really like this idea, I'm often prototyping, but since I do it
| on my own, it is not throwable, so I tend to keep longer as they
| explain.
| microflash wrote:
| After seeing multiple "first drafts" going into production over
| years, I've internalised that they shouldn't be even presented as
| ready to be shipped until and unless a draft passes multiple
| refractors. If something is unknown, it is better to explore
| possibilities and prototype in a prior sprint before picking the
| actual implementation. Take your time to figure out unknowns
| before writing the code you intend to ship.
| pishpash wrote:
| Management doesn't care about your perfect code. You won't get
| rewarded either.
| Squarex wrote:
| I've found this great on my personal projects where I've had all
| the time I've wanted. The next iteration was always orders of
| magnitude better than the first. In the professional setting I
| find that the prototype is often enough and rewriting costs
| unjustified amounts of money.
| kleiba wrote:
| The temptation to throw away all of your code - be it a prototype
| or a "grown" code base - arises often.
|
| Often it is a bad idea. I get it, though, there is an inherent
| attractiveness in the idea of starting fresh from a clean slate.
| Except, more likely than not, you'll soon find yourself in a
| similar situation to the one you started from. The fundamental
| problem is that it is easy to underestimate the edge cases. Sure,
| the main functionality is easily understood and straight-forward
| to conceptualize. But did you remember to think through all the
| smaller aspects of your software, too?
|
| Perhaps it's easier with a prototype implementation that in fact
| doesn't have a lot of features yet, but to completely replicate
| the functionality of a complex piece of software isn't an easy
| undertaking. Sure, getting 80% there is probably easy, but the
| last 20% is the part that's easy to overlook when considering a
| complete rewrite.
|
| Admittedly, there's nothing sexy about refactoring. And often it
| may seem like it's less work to just simply scrap everything and
| start over. However, that's fallacy a lot of times.
| barbariangrunge wrote:
| Game companies implicitly do this, throwing out old versions of
| their code (sort of). You make a game. Ship it. Start on a new
| game. Your previous game is now sort of a practice run for
| making a new game from scratch. Continue, ad infinitum.
|
| It's weird: you rarely have to maintain something for 20+
| years, and you get to always improve and iterate on how you did
| things last time. But, are you training yourself to write hard
| to maintain code, since you don't really have to maintain it
| past a certain period? Or does the learning-from-iteration
| actually make writing-maintainable-code easier?
|
| I know some people do keep developing their games for decades,
| look at Dwarf Fortress, I'm just talking in general.
| throwaway14356 wrote:
| what you do you get good at. if you don't have to maintain
| there is no point in getting good at it or any reason to
| think you will gradually get better at it.
| glouwbug wrote:
| Minecraft is reaching that 15+ year mark
| withinboredom wrote:
| > Admittedly, there's nothing sexy about refactoring.
|
| There's the "strangler fig" (my favorite) method of
| refactoring. It's where you rewrite just a small portion of the
| software, little bits at a time. Instead of doing a full
| rewrite.
|
| IMHO, it's the best way to refactor. You can switch out both
| "old" and "new" versions at-will until you're 100% sure you've
| covered all the edge cases.
| eternityforest wrote:
| I don't really feel that attraction to complete rewriting. I
| wonder if the people who do are very smart, and thus able to
| hold more state in their head, so ugly code bothers them more
| even if it's not actively a problem, because they are able to
| have background tasks in their mind to worry about it?
|
| And at the same time, perhaps their code is less encapsulated,
| because they didn't optimize for abstraction, they optimized
| for beauty. A leaky abstraction doesn't bother them, because
| ALL abstractions are leaky to them, they probably have a sense
| of internal workings even whem using household appliances, but
| ugly code tucked away somewhere bothers them a lot, and they
| might dislike using popular large libraries even if they work
| great, just because they're not comfortable using what they
| don't understand deeply.
|
| My evidence of this is the fact that suckless exists and people
| actually use it, I assume their experience of thought is very
| different from anything I have experienced.
| lamontcg wrote:
| I'd rewrite code to make it simpler and easier to hold in
| one's head, not just to make it pleasing from some aesthetic
| viewpoint.
| jwells89 wrote:
| Speaking personally my urge to rewrite at least partially
| comes from not _truly_ understanding the problem and the
| solutions to it until I 've written something reasonably
| functional. It doesn't matter how much time I put into
| sitting and theorizing, there's always things I didn't
| anticipate and assumptions that turned out to be incorrect.
|
| This usually means that rewrites are significant improvements
| across the board, especially if they're done a relatively
| short time after the original is finished since it's all
| still fresh in my head.
|
| This may be a weakness of sorts on my part though, I lack
| formal engineering training which might be why purely mental
| modeling (no code) doesn't work all that well for me.
| extr wrote:
| Yeah, I find that the desire to rewrite often comes from
| the final (working) solution having poor code ergonomics.
| It's not necessarily that it's wrong, it's that it's
| awkward or clumsy to understand/use, because my mental
| model of how it worked didn't take into account the actual
| practical day to day usage of the code.
| ipaddr wrote:
| Smart people can ignore ugly code. It's the people who get
| easily confused that need to see clean and easy to understand
| code.
| bigfudge wrote:
| Sadly, I think this is true of me -- at least of me. I
| don't think smart people (by this definition) are that
| common though, so clean code is a sensible default.
| josephg wrote:
| > Admittedly, there's nothing sexy about refactoring. And often
| it may seem like it's less work to just simply scrap everything
| and start over. However, that's fallacy a lot of times.
|
| Agreed. Though sometimes you need to refactor the core of an
| application, in a way which will touch the entire app. To do
| that I often make a new, empty project. Then I rewrite the core
| of my project into the new folder (in whatever new structure
| I'm trying out). When that works, I slowly copy the content
| from the old project into the new project - refactoring and
| testing along the way.
|
| But it's not perfect. About half the time I do this, I discover
| halfway through that I didn't understand some aspect of the
| system. My new design is wrong or useless and I throw away all
| the new code. Or I figure out that I can just make the changes
| in place in the old project folder after all, and I bail on the
| new code and go back to a traditional refactor.
|
| But no matter what happens, I don't think I've ever regretted a
| refactoring attempt like this. I always come away feeling like
| I've learned something. How much you've learned from a project
| is measured by the number of lines of code you threw away in
| the process.
| duxup wrote:
| Required link to Joel on Software:
|
| https://www.joelonsoftware.com/2000/04/06/things-you-should-...
|
| Granted Joel is taking about a wholesale rewrite of proven /
| established code. Code and has had had the advantage of time.
|
| Personally, I end up rewriting parts of my code often. It
| usually takes a mile for me to find exactly the right way it
| should be based on how are people use it.
|
| You absolutely should rewrite prototypes, and re-factor
| important chunks of code. I rewrote something 3 times today, it
| was better each time.
|
| At the same time you should be wary...
| wpietri wrote:
| Nah. I think a prototype is something you definitionally should
| throw away. There's a huge freedom to knowing that instead of
| taking on tech debt, you're committed to declaring tech
| bankruptcy and throwing away the code. It lets you try things,
| cut corners, and generally experiment. It's great for thinking
| through what everybody really wants.
|
| I do agree that it's generally a bad idea to just throw out a
| long-lived code base. But for me that's not an estimation
| issue. It's because the urge to throw it out is usually a
| response to upstream problems that haven't gotten fixed. For
| example, a lot of code bases are a mess due to time pressure.
| But if you don't fix the process problems that turn time
| pressure into mess, then you're just doing to end up with
| another mess. Possibly a bigger one, in that stopping all
| productive output in favor of a rewrite usually makes business
| stakeholders crazy, causing increased time pressure.
| robaato wrote:
| Rather than "throw away" I would "start from scratch" meaning I
| can refer to prototype but reimplement with respect to
| appropriate norms. As a version control fanatic, very little
| gets really thrown away in my book. Just hidden.
| tnecniv wrote:
| Yeah normally when I do this, it's because I picked bad
| abstractions. The main business logic I can bring over almost
| line by line, but I want to reshape the abstractions / data
| structures / interface to that logic
| m463 wrote:
| It says to throw it away after a couple of _DAYS_ , which seems
| to differ from other advice (like from joel-on-software)
|
| Maybe this is ok, given that time period?
|
| or will the rewrite have all these extra bells and whistles?
|
| or will the rewrite throw away the unneeded bells and whistles?
| HenryBemis wrote:
| Ok, perhaps don't throw it away. When I come up with an idea
| (for an app usually), I use "a few" A4-sheets (anything
| between 5 and 20), scribble and draw on them with a pencil,
| draw screens, buttons, data flows, activities, write notes
| (in various font sizes). Then I use my CamScanner and call
| this a v1.
|
| Then email me the PDF and store the papers in a box, and a
| couple of days later I start the v2 (same process), then v3.
|
| By v4 it's 'good'.
|
| I also use the same method on my 9-5.
|
| I take VERY seriously the Abraham Lincoln quote "Give me six
| hours to chop down a tree and I will spend the first four
| sharpening the axe" on almost everything.
|
| I consider the v1, v2, v3 as the "sharpening the axe" and the
| v4 on the actual cutting.
|
| In that spirit, the article has a similar approach, as the
| v1, v2, and v3 may take you down an (more than) imperfect
| path.
| Buttons840 wrote:
| > The temptation to throw away all of your code - be it a
| prototype or a "grown" code base - arises often.
|
| I want an editor plugin which allows me to mark sections of
| code as reviewed or "perfect" (depending on how honest I'm
| being). Then, when I'm tempted to rewrite everything, I can go
| through and mark what I think is good, and then focus on
| refactoring the rest until I think it is good as well.
|
| I'm tempted to rewrite code because I lose track of what it's
| doing, or I've learned a lot since I wrote that old code and so
| I'm not sure if the old code is good anymore. It's not so much
| about rewriting the code as an exercise in getting familiar
| with the code I've already written. I want a tool to help me
| with this.
| gregmac wrote:
| I would think a combination of git, unit tests, and comments
| would solve this problem?
|
| Unit tests prove the code works as intended, and are
| basically examples of what the code is doing. Whether the
| code is actually "good" is a bit more subjective -- but tests
| give you the freedom to modify it without breaking it.
|
| Checking into git frequently is also a way to give yourself
| some freedom. Commit at every milestone, like every time the
| next thing is "working". If you feel like refactoring, go for
| it -- you can reset back to working state in a few seconds.
|
| And lastly, leave comments in. You can always clean it up
| before you push. You can even squash or interactively rebase
| your history so no one else sees the gory details how the hot
| dog was actually made.
| trentnix wrote:
| Ah yes, starting from a clean slate.
|
| https://devrant.com/rants/816880/i-ve-done-it-again
| nemetroid wrote:
| Throwing away an established code base is a completely
| different thing from throwing away a few-days-old prototype,
| and not what the article is suggesting. The points you mention
| don't apply to the prototype case.
| tuwtuwtuwtuw wrote:
| Yeah, this thread is a somewhat strange read. People don't
| seem to understand what "draft" or "prototype" means. Odd.
| redblacktree wrote:
| Just like management. I can't tell you how many times I've
| written a "Proof of Concept" that became production code.
| doublerabbit wrote:
| I did that today. Rewrote a bash script in to a perl
| script as Proof of Concept. it's now in UAT... but I like
| perl, hey ho.
| ninepoints wrote:
| This is such a HN phenomenon it infuriates me. Read article.
| Then read comment that misconstrues article to be something
| completely different, accompanied with loud critique. Read
| replies all in violent agreement to obviously self-evident
| strawman.
| duxup wrote:
| Sadly, it's an everywhere phenomenon :(
| hot_gril wrote:
| I've thrown away and redone a lot of code, both mine and
| others', and I've never regretted the time spent vs continuing
| to use the old thing.
| [deleted]
| extr wrote:
| As an ML-focused python dev I have never been able to break the
| habit of REPL-driven development, but I find it works really well
| for "building code that works" rather than coming up with a tower
| of abstractions immediately. A typical python development
| workflow for me is:
|
| * Start with a blank `main` file and proceed linearly down the
| page, executing as I go.
|
| * Gradually pull out visually awkward chunks of code and put them
| into functions with no arguments at the top of the file.
|
| * If I need to parameterize them, add those parameters as needed
| - don't guess at what I might want to change later.
|
| * Embrace duplication - don't unnecessary add loops or
| abstractions.
|
| * Once the file is ~500 LOC or becomes too dense, start to
| refactor a bit. Perhaps introduce some loops or some global
| variables.
|
| * At all times, ensure the script is idempotent - just
| highlighting the entire page and spamming run should "do what I
| want" without causing trouble.
|
| * Once the script is started to take shape, it can be time to
| bring some OO into it - perhaps there is an object or set of
| objects I want to pass around, I can make a class for that.
| Perhaps I can start to think about how to make the functionality
| more "generalized" and accessible to others via a package.
|
| This is literally the only way I've ever found to be productive
| with green field development. If my first LOC has the word
| "class" or "def" in it - I am absolutely going to ripping my hair
| out 12 hours later, guaranteed.
| slim wrote:
| by REPL here you mean jupyter notebook?
| bogeholm wrote:
| REPL = Read-Eval-Print Loop. So could be iPython or just
| plain `python` in general, can't say what OP is using of
| course
| paxcoder wrote:
| [dead]
| hughesjj wrote:
| Not OP but I often code in the REPL for python as well.
| Sometimes I'll stub out my code and just drop into an
| interactive debugger where I'm writing the next section.
|
| In the python debugger, if you type `interact`, it'll give
| you the normal python repl. This combined with the `help` and
| `dirs` are super useful for learning new frameworks/libraries
| and coding with your actual data.
| sergioisidoro wrote:
| I've felt this, and I agree. It really pays of to do some work on
| technical discovery, make all the mistakes, see where all the
| design issues will be, validate as much as possible, and then
| start again. And the best way to really scope out requirements
| and get to know the "unknowns" is really to get your hands dirty.
|
| Especially when in comes to business logic and domain modelling,
| some bad decisions at the begining can cost a LOT, to undo in an
| iterative matter.
|
| (To clarify I'm talking about the timeline the author proposes of
| "a couple of days" build the throw away prototype)
| linsomniac wrote:
| Decades ago I spent a whole day adding a serious new feature to
| my software. Had the first version all polished up and ready, and
| through a misunderstanding with my version control software
| (probably RCS, maybe CVS, probably not SCCS), I lost that work.
| Like maybe I did a checkout instead of checkin, something like
| that. I went to bed quite annoyed.
|
| The next day I got up and started from scratch. The new
| implementation took me half a day, and was decidedly a better
| implementation.
|
| Fred Brooks turned out to be right.
| paulddraper wrote:
| Aka "Build one to throw away"
| trevortheblack wrote:
| Oh FFS.
|
| Writing code is like writing natural language.
|
| It's editing that counts. Not the first draft.
|
| Whether or not you should throw out your first draft is in
| proportion to its value at getting you to the final draft.
|
| Not some axiom you thought of for a specific use-case and
| specific code base
| say_it_as_it_is wrote:
| Ship your first draft. Never rewrite. Go work on the next task.
| Scoundreller wrote:
| First draft? Final draft.
|
| http://m.quickmeme.com/meme/3629ez
| zer8k wrote:
| The agile mafia does not appreciate your sarcasm.
| karmakaze wrote:
| I've always called this the "green-path prototype", which is
| building what you thought you knew, without implementing edge
| cases. The edge cases will get discovered and noted along the way
| and they should be documented (with a comment or other method
| that doesn't get lost). Pretty much any time you only handle a
| subset and don't handle the 'else's.
|
| The real implementation should consider the green-path and edge
| case notes, decide the desired structure/decomposition and pick
| and choose from the green-path rather than try to start with it
| as v1 of a final form.
| dools wrote:
| See also "Plan to Throw One Away" from the Mythical Man Month:
|
| https://wiki.c2.com/?PlanToThrowOneAway#
| avgDev wrote:
| I rewrote a mission critical application. The original app was
| something else. One function had 1500+ lines of code. It was the
| ugliest thing I have seen in my life. We wrote cleaner code in
| early college years. However, that code ran the business for 12
| years with almost 0 modifications. People created work around for
| some stuff. Error handling was poor. But the goal was achieved
| and business continued to grow.
|
| I think devs in general sweat too much about code quality.
| refactor_master wrote:
| > However, that code ran the business for 12 years with almost
| 0 modifications
|
| We have code like that, and it requires everything around it to
| twist and contort to comply with the beast of unmaintainable at
| the center of it all, simply because at this point it has so
| poor test coverage and is so incredibly mission critical now.
| avgDev wrote:
| Test coverage!? I don't think that word was in the vocabulary
| of the dev who wrote it :).
| vsareto wrote:
| Some disputes about quality are simply differences of opinion
| or style.
|
| There's not really a book or standard on opinionated code
| quality that satisfies a majority of the people in the field.
| There's way too many ways to build things for that to exist.
|
| This leaves it up to individual teams to approach a shared
| consensus (with some wiggle room) within their domain and tool
| set.
|
| One thing that is universal is how strict the enforcement of a
| team's quality standards. So as a developer, you have to decide
| whether you like strict or lax enforcement of quality
| standards. Everyone can decide that but I think most don't.
| patrulek wrote:
| Code quality isnt that important if you check this code "once a
| year" and dont have time pressure to change somewhere in there.
| Or if you are seeing this code daily and know all the quirks.
| wizofaus wrote:
| > I think devs in general sweat too much about code quality
|
| I think if they sweated a little more then poor quality code
| wouldn't find itself into the codebase.
| mplewis wrote:
| Bad code doesn't usually come from lack of effort. It usually
| comes from business requirements that grow over time with
| deadlines attached.
| wizofaus wrote:
| It can still be a lack of effort put in trying to convince
| product managers etc that more time is needed!
|
| But almost all PRs I review have something in them that
| suggests the developer not putting as much thought/care
| into what they were doing as I'd like to see (and I'm just
| as capable of doing the same).
| halfinvested wrote:
| Anecdote: I know a guy who works solo and throws every project
| away (usually games) at least five times, often more like ten.
|
| According to him, each iteration tends to go smoother and faster
| than the last.
|
| Edit:
|
| There's probably some nuance to whether this approach is a good
| idea based on type of software, size of team, experience level,
| personal and/or team skill set, etc...
| foxbyte wrote:
| The idea of prototyping to uncover 'unknown unknowns' resonates
| with me, it's like a reconnaissance mission before the actual
| project. This could indeed save a lot of time and effort in the
| long run...
| Mountain_Skies wrote:
| Just never let management see the prototype or they'll consider
| it done and tell you to move on to something else.
| shortcake27 wrote:
| In my experience, this is what actually happens. A developer
| makes a low-quality, low-effort prototype under the
| assumption it won't ship. Someone sees it. It gets shipped.
| Everyone loses.
| jstarfish wrote:
| Sabotage your prototypes then. Have it reset its state
| every 5 minutes or deliberately leak memory.
| sodapopcan wrote:
| Ya, this basically.
|
| It helps if you have tests because when prototyping, you
| can write things in a way which break tests and ideally
| break other features. It works enough that you can
| validate the one idea. That way it will never pass CI.
| gjvc wrote:
| Sneaky move.... but then, in the eyes of some people, you
| might well appear not competent to put together a working
| system, so make sure you know your audience.
| vishnugupta wrote:
| Reconnaissance mission is a great analogy. I think of it as
| scouting from the Age of Empires.
|
| Besides discovering unknown-unknowns it also helps in conveying
| design/idea to rest of the team.
| hot_gril wrote:
| Another war analogy was the Byzantine defense. Their policy
| was to avoid decisive, large-scale battles where a lot can go
| wrong at once. If an enemy army is incurring, first try to
| weaken or deter it with lighter forces that also gather
| intel. If they can't stop the threat, form and advance a
| larger army with a better-planned supply chain to stop it
| deeper in the territory.
|
| Which actually doesn't work so well in AoE. The game doesn't
| have a concept of army supplies, so you usually just want a
| huge unstoppable army you can send anywhere.
| okamiueru wrote:
| This advice depends a lot on how your "first draft" was coded to
| begin with. The concept of "first draft" shouldn't exist as code.
| You design it properly, then you implement it properly.
|
| Now, if for some reason, and there are plenty of good ones, you
| cannot do the former, then sure, you pay that price by redoing
| some work. But, at that point, you do the same thing you should
| have done: you design it properly, then you implement your
| design.
|
| One could argue that implementing a first draft _is_ a way of
| designing it. Which, I cannot imagine making sense unless you don
| 't know what it is you want to end up with. Maybe if you're
| making computer games or other creative endeavors?
| hot_gril wrote:
| > One could argue that implementing a first draft is a way of
| designing it. Which, I cannot imagine making sense unless you
| don't know what it is you want to end up with. Maybe if you're
| making computer games or other creative endeavors?
|
| It's when the problem itself has some ambiguity. Like, I design
| systems that other people and systems use within a large
| company. I try to figure out how they'll use them, but even
| they can't tell me exactly. New business requirements come in
| mid-design, etc. They might even cancel the whole project if
| something more important comes along. In that situation, it's
| best to get some MVP as quickly as possible then iterate on it.
| Later iterations might totally scrap and rewrite the internals,
| which is fine if the API sticks.
| okamiueru wrote:
| That makes sense. Like a prototype you hand out so that you
| can figure out what it is you/client _actually_ want. I don
| 't think of those as first drafts though. Maybe it's a
| language barrier thing for me.
| almostnormal wrote:
| "Design" has a spectrum of level of detail, anything from a
| whiteboard full of information to a description of code in
| a fancy tool that is more detailed than the code itself.
|
| Text (source code) as a representation of ideas can be
| worked on extremely efficiently at arbitrary detail. At low
| level of detail only beaten by a whiteboard.
|
| If any piece of information has been missed when creating
| anything (any form of design or code), updating mutiple
| implementations of the same thing takes more effort than
| updating only one (the code).
|
| Too many details in design will require frequent changes,
| with low level of detail it won't help much to detect
| missing pieces of the puzzle. Either way it adds effort.
|
| Design has its advantages, lower total cost/effort in the
| short term isn't one though.
| hot_gril wrote:
| First draft could mean a lot of things. If you mean
| something you write then rewrite before it's ever released,
| the same still kinda applies. You might be mid
| implementation when something changes and ruins whatever
| structure you had. Or maybe the abstractions aren't very
| obvious at first even if nothing is changing.
| klabb3 wrote:
| > You design it properly, then you implement it properly.
|
| I'm extremely defensive and try to think through everything.
| Aside from analysis paralysis which is a real obstacle, it's
| still not enough. Or rather, it's not the best way to use a
| human brain. At some point for a complex project, no matter how
| smart and experienced you are, assumptions break down. The
| mental model changes based on "friction" with the gritty world.
| Prototyping is one way to confront wrong assumptions earlier
| rather than later.
|
| All creative and intellectual endeavors have analogous process.
| Writers don't structure a book and write it perfectly in a
| methodical fashion. Basically, turning chaos into order can -
| almost per definition - not be proceduralized.
| cratermoon wrote:
| > You design it properly
|
| And how, if I may ask, does one design it properly?
| almostnormal wrote:
| That's easy. Create one, try to implement a bit of it, throw
| the design away, and then create the real one.
| HankB99 wrote:
| I didn't read the article, but can guess at the rationale. I
| often wish I had the luxury of taking everything I learned
| writing something and then applying it when starting over.
|
| But IAC... I would much rather throw away someone else' code. :D
| bandyaboot wrote:
| I don't really see the need to commit to throwing my first
| iteration out. I do refactor pretty aggressively at the outset of
| a major project or code change though. It often takes me quite a
| bit of time before things really get off the ground because of
| this. The result is probably the same--that I'm paying a lot of
| attention to making sure I'm going down a good path.
| sodapopcan wrote:
| The funny thing is is that this is part of TDD (and extreme
| programming) that most detractors of TDD don't understand. I'm
| talking about the old "but if I don't know what I'm writing, how
| do I write a test first?" crowd. Well, the answer is this
| article. Write a quick prototype to answer unknowns, figure out a
| general plan, then throw it away and start with a _single_ test.
| I emphasize "single" because there was that other article that
| made the front page a couple of months ago where the author
| described their "new found way" of doing TDD that made them
| actually enjoy it and then went on to describe regular plain ol'
| TDD.
| [deleted]
| nine_k wrote:
| <<In most projects, the first system built is barely
| usable....Hence plan to throw one away; _you will, anyhow_.>>
|
| Fred Brooks, The Mythical Man-Month
|
| 1975, fourty eight years ago, but worth repeating sometimes.
___________________________________________________________________
(page generated 2023-08-04 23:00 UTC)