14 ms·
Code Is Never “Perfect”, Code Is Only Ever “Good Enough”
- unimpressive 10y agoI wonder if this attitude will change once things like coq become more accessible.
- patrickmn 10y agoI don't know if we will ever have tools that are that safe and as easy to use as the alternatives.
- oconnore 10y agoNews at 11: winging it is less work than being careful! (Of course, the situation gets fuzzier when you must account for other factors: work/dollars/lives lost due to bugs in dependencies, the integral of maintenance costs over time, etc.)
- unimpressive 10y agoRight. The tools don't need to be easier than competitors, they just need to be easy enough and provide enough benefit that doing it another way isn't worth it.
- SilasX 10y agoIt depends. People were reluctant to give up a lot of bad coding practices (goto, variable scoping, writing in efficient assembly rather than a high-level language, mutable global state) until the better way had better tools or was taught better. Edit: Maybe one day people will look back and say, "you shipped code without formal correctness proofs? Were you all high?"
- ddaygold 10y agoThere is code that pushes the boundaries of the human mind, complex systems that cannot have any additional complexity if they are to succeed. And there's other code that pushes against physical or economic limits: processor speed, memory available, network latency. In those systems, writing in an inefficient, high level language is just as wrong as writing the first type of code in a low level one. Fast, complex, difficult to fully verify code is not bad coding practice any more than a rocket is a worse vehicle than a Volvo because it explodes more. Volvos can't go to space.
- SilasX 10y agoBut one day our skill in "controlling explosions" (bad logic) may be as good as our skill at doing so in a Volvo, where we can get the power, with the efficiency and predictability.
- bordercases 10y agoIt's your job as a worker not to cut corners. It's their job as a manager to fire incompetence. Needless to say I think everyone is failing to do their job.
- johansch 10y ago/remindme in 50 years
- djtriptych 10y agoAgreed. I find that when working in some functional systems like haskell/clojure or even functional-style javascript, I do occasionally produce code of reasonable complexity that I call pretty much perfect.
- ambrop7 10y agoI think the problem is most people are not capable of proving code is correct even informally (and writing correct code, which can only happen if you're writing it while proving correctness in your mind). Using formal verification seems to me like something additional you have to do after convincing yourself of correctness (convincing the computer).
- bottled_poe 10y agoNot sure how this addresses changing requirements..
- dman 10y agoI hope this attitude is used sparingly and in cases where either the problem is supremely hard or where time is exceedingly short.
- dwaltrip 10y agoYou are missing the point. "Good enough" depends entirely on the context. In some contexts, the bar for "good enough" will necessarily be quite high, while in other context it won't matter as much. There is no perfect code -- because no two humans could agree on such a definition. Sure, people may disagree on what is good enough. But hopefully that disagreement will be easier to resolve than one about what the perfect solution might be.
- dman 10y agoMy only concern is that this line of thought can be used as an excuse to stop trying. As long as we agree that one should strive for perfection given the constraints at hand (money / time / problem difficulty / experience level etc) I dont have any objection about the idea. On a related note, I feel another analogous statement that I now see used dangerously is "Premature optimization is the root of all evil". Yes optimizing prematurely can be paralyzing but the other extreme where one refuses to do back of the envelope calculations and wilfully writes code that will be slow is damaging as well.
- pmiller2 10y agoThat's a good attitude to aspire to, but, in real software development, very little code survives contact with users unscathed. If you're writing a C compiler or something with a well-defined spec, then, sure, you can theoretically write perfect software. But, even your basic CRUD web site is unlikely to ever reach "perfect" status. Edit: For example, the HN code was obviously not "perfect," since we just got several new features. :)
- dwaltrip 10y agoI can appreciate that. I have some perfectionist tendencies myself. I think it is a tricky balance that must we must walk. I like your idea of "as perfect as our constraints allow". Another important consideration is the level at which the quality exceeds the needs of current and future users of the software. Past this point (which might be impossible to determine or fully agree upon), one must acknowledge they continue to iterate and polish for purely personal reasons. This can be fine in certain situations, but it may be a detriment in professional endeavors. And of course, like always, one must consider opportunity costs.
- beat 10y agoI have the start of a lightning talk on something similar, called "Why Software Sucks". The idea is that we only make software good enough to get by - we will always choose features over robustness if we possibly can. Every project ends when it either fails, or hits feature-complete. No one sits around polishing the pile of bugs and bad decisions that is a feature-complete app unless they have to - much more fun to start something new!
- jacobtr 10y agoIt seems like most consumer apps incur a crazy amount of technical debt while largely paying people in equity, then if they take off raise a bunch of money to pay other people in cash to sort it all out... Pretty good system actually.
- beat 10y agoEnterprise apps are no different. Lean startup is doing better in the enterprise than it is in the "startup" world. Early on, every app is laden with technical debt. They barely work. When "barely works" becomes "doesn't work", we fix them just enough so they barely work again, and start piling on more features and functionality. We may build some scaffolding and do some refactoring to prevent dropping into doesn't-work-land, but that's not the same as robust! So software - all software - hovers around that barely-works/doesn't-work borderline.
- lotyrin 10y agoManagement doesn't invest in things they don't understand. They rarely understand tech (even if they are technical people, tech is misunderstood). If you care about the outcome of a craft, you'll get craftsmen, and they'll produce things and you'll pick the best ones. Imagine if a chef had to serve the first try at a new dish, if a photographer had to use his first shot, if a director had to use the first take, if a visual designer had to use the first concept. These processes are easier for people to understand because a layman can tell if two flavors didn't combine well, if a model blinked, or if something looks off. People (even technical ones) can't experience technical problems immediately or directly in the same way. Other fields solve for this with engineering, but ours rarely is allowed. We often ship the first architecture that gets brainstormed, and the first implementation that works. It's never "We implemented the MVP using patterns/frameworks A, B, C, D, here's a table of the strengths and weaknesses as we see them, statistical summary of the time to complete each feature, and of defect rates. This next slide is a plot of the relationship between request latency, capacity, and estimated infrastructure cost of each implementation". It's rare to even have refactors scheduled. Just cleaning up your shit is "wasting time", never mind how long it takes to ship new features given how cluttered things are. Sure, engineering is costly, so is not engineering - you just aren't projecting or measuring the latter costs. It's all trade-offs, if you aren't considering expected values of different options, with numbers, then you haven't optimized, you just rolled some dice. Sure, of course it's always worked, everything always have worked for the survivors. There's a big difference between what's unforeseeable and what has merely been left unforeseen.
- karma_vaccum123 10y ago...and, problems change even if the solution doesn't. At this point I only aim to build things that will durable and sensible for about four years. After that, some other change seems to come along that invalidates the original code, no matter how pretty it was.
- centrinoblue 10y agoha the Dick and Bob bit is pretty darn funny
- simonpure 10y agoI think today it's more useful to think of most software as a living organism interacting with it's environment - it's constantly evolving and adapting to external changes (user needs, dependencies, 3rd party services etc.).
- rrradical 10y agoI see things a bit differently. Some domains are well understood and it's relatively easy to write perfect code (e.g. mathematical functions, list manipulating functions, etc.), while in others it may be much harder (the file uploading example he mentions). To me a good aim of writing code is to move bits and pieces from the latter camp to the former, so that more and more of your codebase is well understood (and perfect!). That usually involves finding the mathematical meaning of the abstractions you're using. (Shameless plug- I wrote a little blog post on the subject: http://asivitz.com/posts/programming_in_haskell http://asivitz.com/posts/programming_in_haskell)
- joe_the_user 10y agoActually, I'd say writing perfect code in the mathematical domain is extremely hard - floating point types are a minefield and infinite-precision arithmetic is a minefield also if you consider the possibilities for running-times exploding. For example, code for the mean of a list of numbers is a hard problem when looked at in its full generality [1] - and that's using forgiving definition of "perfect" - alway correct and terminating, running at a reasonable speed. [1] http://hypothesis.works/articles/calculating-the-mean/ http://hypothesis.works/articles/calculating-the-mean/
- skybrian 10y agoGreat link! But also, the mean is itself an imperfect summary of some distributions. Any single-number summary will be misleading in some cases.
- bradleyjg 10y agoAnscombe's quartet is a great illustration of that. https://en.wikipedia.org/wiki/Anscombe%27s_quartet https://en.wikipedia.org/wiki/Anscombe%27s_quartet
- fbonetti 10y agoThat's really cool! Btw, I'd love to drop that line into casual conversation some time. "Anscombe's quartet" has a nice flow to it.
- drwl 10y agoreminds me of http://algeri-wong.com/yishan/only-god-writes-perfect-code.html http://algeri-wong.com/yishan/only-god-writes-perfect-code.h...
- BerislavLopac 10y agoRight on point. Furthermore, it just lead me to realisation that achieving software perfection is like reaching the speed of light: the closer you get to it, the heavier you are, and more effort is needed to go further.
- makecheck 10y agoOne of the depressing things about code is that it is astoundingly easy to build something that does amazing things in controlled circumstances but is otherwise practically garbage. Promotions, venture capital, and all other manner of rewards can result from said garbage. The “real work” is in figuring out how to move forward from something like that, and lots of stress comes from trying to do so without breaking anything. There is little reward in maintenance. “Good enough” is really the type of attitude that leads to this unfair balance of effort. Unfortunately, we live in a world where criticism is levied very heavily on where you are now, and not on how you got there. What, version 2.0 of the product sucks now? Screw it, “1 star”, boycott this; fire the team responsible! Never mind the fact that version 1.0 was a rickety mess, all of those guys left, and anyone would be lucky to get the thing working at all, much less in a way that does not introduce any new bugs. One of the big benefits of open-source is having a chance to understand what’s going on. Would as many people invest in a product, despite promising behavior in version 1.0, if they could see a critical review of how that version was actually implemented? Ideally, we can see not only how a product appears to work, but how well-engineered it is according to experts.
- logicallee 10y ago> The “real work” is in figuring out how to move forward from something like that, and lots of stress comes from trying to do so without breaking anything. I'm a lot more impressed with the evolution of the human species than how doctors have been able to maintain those running systems. You want to design a human from the ground up using proper infrastructure that doesn't have ailments or diseases go ahead. you'll be lucky if you end up with a fruit fly.
- smt88 10y agoThe human body is the result of 1,000,000,000,000,000,000,000+ organisms dying before or after reproducing. That's evolution. It has absolutely nothing to do with the "maintenance" that doctors perform on the human body, especially when doctors are loathed to lose even a single organism. I'm not even sure why I responded to your comment, since it was so random and unrelated to the rest of the thread.
- WalterBright 10y agoHaha, there's some code of mine I've been regularly improving for 30 years now. Even versions I thought had attained perfection I rewrote later when I realized it was a POS. The only software that is ever "done" is code that has been abandoned and is no longer in use.
- asciihacker 10y agoDoes the work of Charles Simonyi and intentional programming change this?
- jfe 10y agoI think the definition of perfect code depends on whether the computer is the end or the means. If it's the end, then there may never be perfection.
- BerislavLopac 10y agoThe obligatory link to "Everything is Broken": https://medium.com/message/everything-is-broken-81e5f33a24e1 https://medium.com/message/everything-is-broken-81e5f33a24e1
- vermooten 10y agoAnd most of the time not even good enough.
- softawre 10y agoTooling is getting better. Ever looked at what Amazon does with formal methods to "prove correctness" for some of their systems? Of course you can argue that "good enough" for them is "damn near perfect". http://cacm.acm.org/magazines/2015/4/184701-how-amazon-web-services-uses-formal-methods/abstract http://cacm.acm.org/magazines/2015/4/184701-how-amazon-web-s...
- kkarakk 10y agogot a link to a non-paywalled source?
- deleted 10y ago[deleted]
- jdironman 10y agoInsanity is doing the same thing over and over again and expecting a different result.
- 010a 10y agoCode quality can only ever be as good as your understanding of the problem domain. A more accurate statement would be "Problem domains are rarely perfectly understood."
- chadgeidel 10y agoIMHO This should be more highly rated. It seems that we write code to understand the problem domain, and only by writing code do we truly understand the problem. This is - again IMHO - why iterative techniques work so much better than waterfall-style techniques.
- ambrop7 10y agoPerfect is subjective, but "correct" not so much. And when you get sufficiently skilled, you realize correctness can, for sufficiently complex software, only come together with the more subjective qualities, since it's hard to make "ugly" code correct. "Piece of [bleep]! I know you [bleeping] work! WHY WON'T YOU [BLEEPING] WORK, MOTHER[BLEEPER]?!" With that kind of attitude (trial-and-error?) you will never be able to consistently produce correct code, let alone perfect whatever that is. Though I think it's not typically the attitude that is the problem, but rather the underlying lack of skill/intelligence which makes people resort to such approaches.
- RealityVoid 10y ago> With that kind of attitude (trial-and-error?) you will never be able to consistently produce correct code, let alone perfect whatever that is. Sometimes software development process can be very frustrating and I fully understand the feeling when you're overwhelmed and confused and feel frustrated because you don't know how to approach the problem. Working with black boxes usually causes the feeling in me, or having an elusive bug that could come from literally anywhere from a huge system and having to debug it with seemingly random reproduction steps, that always gets me.
- phaedryx 10y agoI had a manager that never used "finished" or "done". He always said "where it needs to be right now".
- deleted 10y ago[deleted]
- steego 10y agoIt's important to know what kind of code you're working on before you start setting low standards. Some code is perfect, but it's only perfect because it was define with extreme mathematical precision (Ex: Haskell Prelude code). The value of this type of code is in direct proportioned to how often it's reused. Often the specs are based on timeless and well defined ideas, and the implementation crystallizes. On the other end of the spectrum is loosely defined ad hoc code. The specification behaves more like a living thing and the code often tries to adapt to the moving specification over time. This type of code tends to bring a lot of value to the business and often relies on the foundations laid by perfectionist code.
- aurelianito 10y agoI wouldn't call Haskell's prelude 'perfect'. For a few examples of imperfect things see https://downloads.haskell.org/~ghc/master/users-guide/bugs.html https://downloads.haskell.org/~ghc/master/users-guide/bugs.h... (Find 'prelude' in this page, has several appearances).
- steego 10y agoI didn't mean to imply all the prelude code was perfect. What I meant to imply was some parts are insofar as the specification is complete and specific enough that it yields one solution. An extreme example would be the id function.
- deleted 10y ago[deleted]
- marcosdumay 10y agoI stopped looking for perfect code after I saw the fail man page, and saw that the one on my computer was at version 4.something. Yes, the Haskell's Prelude is perfect when matched with an (artificial) specification that requires exactly it. Yet, on practice I don't think I ever saw any Haskeller that does not want to add or remove something from it. Partial functions are almost unanimously disliked, ditto for String functions; not to say about the universal complaints in how it is badly generalized.
- ZiggyCrane 10y ago... like you could create anything and call it perfect. There is no perfect.
- jfaucett 10y agoI think this is rambling about things that are largely unimportant (spaces or tabs). At least that's what his "Perfect Code" definition seems to be to me. The important part is the flipside, not the presentation: Given a problem domain and a context there is an optimal or "best" solution or there is not, and we can get at the answer for most cases. So code can be perfect if we understand perfect to mean optimal. If we understand it to mean spaces/tabs probably not, though given an input and desired output we can even prove some of these as well (for instance, underscored function names are more quickly processed than CamelCase : http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.158.9499 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.158....).
- Others 10y agoI didn't read the whole paper you linked, but doesn't this sentence in the abstract contradict your last sentence? >Results indicate that camel casing leads to higher accuracy among all subjects regardless of training, and those trained in camel casing are able to recognize identifiers in the camel case style faster than identifiers in the underscore style.
- jfaucett 10y agoyes it appears that way without reading the paper. Basically the main factor to me is speed which has a huge differential for untrained subjects "The model finds that identifiers written in the camel case style took 0.42 seconds more time." Doing the math you see how much wasted time that is. So I should have been more specific in the parameters. Your quote is perfectly valid as well.
- njharman 10y agoCorrection, code is at most "good enough". I've seen (and written) plenty of code that was less than good enough.
- dguido 10y agoUnless it is formally verified, then it is really perfect. Not sure why we shouldn't strive towards that final state of evolution. Conceding the game at "good enough" is a cop out.
- sgift 10y agoFormal verification depends on frozen requirements. These are quite rare in practice.
- cmillard 10y agoIt's scary sometimes that previous consultants (I'm a consulting developer) may have gotten an application "working", but have incurred so much technical debt it is nearly impossible to make changes. They've escaped and taken the biggest chunk of money leaving something built on a foundation of toothpicks. Thus the project becomes a ticking time bomb and requires full-time programmer maintenance. You wonder if the next feature request will become the impetus for the collapse- Then you turn into Robert Gates: "I don't know where. I don't know when. But something bad is going to happen!!!"
- andy_ppp 10y agoI'd love to see what YCs guidance on code quality is. My guess is "ship it if you get users".
- ben_jones 10y ago"If the building isn't on fire you're not iterating fast enough"
- euske 10y agoI'll copy a Bruce Schneier's quote and say "Software is a process, not a product." It's no surprise that there's no such thing as perfect code because code is mere reflection of a real-life requirement, which is always somewhat inconsistent and ever changing. Sticking to one static point is, well, pointless.
- dahart 10y agoI still haven't learned this lesson well enough. Code I think is near perfect always turns imperfect over time. The main corollary for me is that I can spend every waking second of my life making my code better, and I'll never be happy. I want to better figure out how to enjoy 'good enough'.
- mikekchar 10y agoInstead, I might suggest that you enjoy making your code better and to be happy with the process rather than the result. Then every crappy piece of code is an opportunity rather than a curse. Improving code beyond the point where it gives material benefit is not really a problem except for the fact that it deprives you of the opportunity to work on crappier code. Especially when working with new code, I find it useful to concentrate on process rather than end product. If you write tests like X and refactor like Y, how does it affect the result? In some ways this is really freeing because you get over the fear of writing crappy code. If it's crappy, you just get to improve it. It also allows you to explore ideas and ways of doing things without worrying so much about the result. Concentrating on producing good code can often (in my experience) lead to achieving a local maxima but not does not allow you to kick out of it to achieve something better.
- dahart 10y agoI was getting closer to that for many years -- enjoying the process -- until I decided to try and start a software business. All of a sudden, there's a huge downside to improving code without having a clear material benefit. I'm with you on losing the fear of writing crappy code being freeing. At some point I realized that everyone's code including mine is crappy code, and there's no way around writing crappy code or introducing bugs. Realizing that did make me a better coder and a better manager. It let me be a bit more humble as well as empathetic to others, and led me to think more about the importance of testing.
- hypertexthero 10y agoI [attended][1] a great lecture by [Alex Martelli][2] back in EuroPython 2013 titled "'Good Enough' is Good Enough!" From the [summary][3]: > Our culture’s default assumption is that everybody should always be striving for perfection – settling for anything less is seen as a regrettable compromise. This is wrong in most software development situations: focus instead on keeping the software simple, just “good enough”, launch it early, and iteratively improve, enhance, and re-factor it. This is how software success is achieved! [1]: http://simongriffee.com/notebook/europython-2013-notes#goodenough http://simongriffee.com/notebook/europython-2013-notes#goode... "My notes. Biggest takeaway was to use 'perfect' as a verb rather than adjective." [2]: http://www.aleax.it/ http://www.aleax.it/ "Alex's homepage." [3]: https://ep2013.europython.eu/conference/talks/good-enough-is-good-enough https://ep2013.europython.eu/conference/talks/good-enough-is... "The lecture video is also on the page."
- cisstrd 10y agoIt might not be "perfect code", but I find it fascinating what certain institutions do to create bug-free and easily testable code, institutions which are involved in work where small errors can quite literally ruin billions of dollars of investment. For example Coding Standards from NASA's Jet Propulsion Laboratory (JPL) for C[1] and Java[2] This will also give you an idea of just how tedious it is to do so I am not even sure if enforcing those strict standards leaves a Turing-complete language [1] http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf [2] http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_Java.pdf http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_Java.pdf
- meta_AU 10y agoThat's a good point. Safety critical systems commonly require loops to have maximum iteration counters and also forbid recursion. So what's left probably isn't Turing complete.
- mikro2nd 10y agoFrom [2] above: > important general differences from the JPL institutional C coding standard for flight software references (JPL-C-STD) are: (1) the Java standard allows dynamic memory allocation (object creation) after initialization, (2) the Java standard allows recursion, and (3) does not require loop bounds to be statically verifiable. Apart from these differences most other differences are due to the different nature of the two languages. That said, the standard in question is explicitly only intended for ground-based systems.
- RealityVoid 10y agoHow can it not be Turing complete? You have the option of doing those things, even if by accident but you avoid it as much as you can. Turing complete does not mean it runs forever or has a mind of its own. I'm not necessarily trying to be combative and am not the most well versed in computational theory, but this statement seems off.
- kluck 10y agoWe should more than ever strive for perfect code. Perfect as defined by all stakeholders in a software. There is really no point in striving for anything less. Sure you maybe forced to stop at one point (time and money beeing the limiting factors) but if you can, you should always continue making software better! "Good enough" is not good enough as a target. It's uninspiring and unsatisfying.
- okonomiyaki3000 10y agoCode is never "good enough", code is only ever "less in need of fixing than other code."
- coldnebo 10y agoI think that might be paraphrasing implications of Gödel's Incompleteness Theorem. Non-trivial codes can either be consistent or complete, but not both (within a system of abstraction). This explains Joel's "Leaky Abstractions" essay as well as the conjecture that code cannot be perfect. However, "good enough" thinking is often just sloppy thinking. Even if mathematics has boundaries, it doesn't mean you just shrug and say "a nod is as good as a wink". Craftsmanship and quality are perceived in terms of utility over time. "Good enough" often doesn't meet that bar. Engineers overbuild to support capacity and plan for the worst. "Good enough" tends to under-build at or below capacity and hope for the best. "Good enough" is a just reaction to over-engineering (the adding of unnecessary fixtures and 'perfection'), so the warning has value and there are some engineers who use it in this way. But others often mistake over-building for over-engineering and cripple their organizations and products by seeking "good enough".
- geebee 10y agoThis reminds me or a reaction I had to a very old internet war about PHP and Rails https://sivers.org/rails2php https://sivers.org/rails2php "...The entire music distribution world had changed, and we were still working on the same goddamn rewrite. I said fuckit, and we abandoned the Rails rewrite." It made a bunch of people mad, because (I think) they were reading "Rails couldn't X, and Rails couldn't Y, and Rails couldn't Z, but PHP could totally Y Z and Y, so I used PHP and it was a big success". But having been in this situation, I think what he was saying was "I couldn't X, and I couldn't Y, and I couldn't Z, so I said fuckit and did it the way I know how..." It has nothing to do with rails or PHP, or node, django, react. Programmers who have never finally said "fuckit" and abandoned "the true and right way" are programmers who haven't released. Not saying you should stick with ancient technology, but "good enough" is an inevitable ingredient in any software that ends up being useful to someone.
- evoltix 10y agoI try to follow this mantra from Kent Beck: "Make it work. Make it right. Make it fast." I find that most of the development environments that I have worked in, the focus usually ends up being on getting new features completed in order to help facilitate the sales department to make sales. It's a never-ending cycle that will gradually accumulate technical debt such that pushing new features out the door will eventually come to a halt. Yes, I agree that code can never truly be perfect. However, as developers we should always strive to make our code better.