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