10 ms·
When I was in school in the 70's. (That's NINTEEN seventies.) There was this book called The Psychology of Computer Programming. This predates the microcompu
by DannyB2 8y ago
When I was in school in the 70's. (That's NINTEEN seventies.) There was this book called The Psychology of Computer Programming. This predates the microcomputer era as we know it. Punched cards were still common when the book was written.
A computer was to control a new assembly line for a car company. They couldn't get the software to work. They called in an outside insultant. The outsider developed a program that worked. (It was more complex.) The book was about the psychology part: The original programmer says: "How fast does YOUR program process a punched card?". Answer: "About one card per second." "Ah!" said the original programmner, "but MY program processes ten cards per second!"
The outsider said, "Yes, but MY program ACTUALLY WORKS". If the program doesn't have to work, I could make it read 100 cards per second.
Correctness comes first. Simplicity is highly desirable, adds additional cost, but always comes after correctness.
- karma_fountain 8y agoSeen this several times when someone refactors. The code is much simpler and easier to read, but does not actually work for several important test cases anymore. I've never thought of simplicity adding upfront cost. That's probably true, but also true that it pays dividends later on in the project.
- DannyB2 8y agoIf it no longer works then I don't consider that to be "refactoring" but "rewriting". I think of refactoring as a series of SIMPLE transformations that clearly do not have any effect on the correctness (or incorrectness) of the code. That is, there is no possible change in behavior. And think of the word "factoring" as in high school algebra. or rather "factoring out" something. I have a dozen examples of this calculation. How about let's refactor it into a function, and replace all the instances with a function call?
- msla 8y ago> I think of refactoring as a series of SIMPLE transformations that clearly do not have any effect on the correctness (or incorrectness) of the code. That is, there is no possible change in behavior. This kind of transformation is precisely what the person who coined the term meant: Taking code which works and turning it into easier-to-read code which works precisely as well, because refactoring never introduces a change in behavior. To quote Martin Fowler and Kent Beck: > A change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior… It is a disciplined way to clean up code that minimizes the chances of introducing bugs. [snip] Not a direct quote this time: > Fixing any bugs that you find along the way is not refactoring. Optimization is not refactoring. Tightening up error handling and adding defensive code is not refactoring. Making the code more testable is not refactoring – although this may happen as the result of refactoring. All of these are good things to do. But they aren’t refactoring. https://dzone.com/articles/what-refactoring-and-what-it-0 https://dzone.com/articles/what-refactoring-and-what-it-0
- jstimpfle 8y agoMaybe the test cases / requirements are "wrong"? I think simplicity is the ultimate test that you found a good problem!
- DannyB2 8y agoSimplicity is ALWAYS something desirable to achieve. Correctness comes first. As code is originally written, people are (or should be) using the most "obviously" simple approach. A Breakthrough in simplicity is often the result of additional thinking and hard work. (And cost)
- d__k 8y ago> Correctness comes first. Simplicity is highly desirable, adds additional cost, but always comes after correctness. It is true mainly for one-time contracts where you actually might not care about simplicity at all. Enough is enough. However, in the case of iterative projects keeping complexity under control has much higher priority including top priority for very big projects. Complexity and high entropy can easily kill everything.
- quadcore 8y agoHow do you know it was more complex because from what I read it was slower which is different.
- DannyB2 8y agoIt has been too long. The book described both approaches that both programmers used. I simply no longer remember those details. As I recall, the working program, when explained gave you the "Ah Ha!" experience, and thus was simple enough. The focus of the entire book was more about psychology aspects. One chapter was about how programmers come to feel "ownership" of code. Another thing: what was an entire program back then, is sometimes a mere function, or maybe a class or code library today.
- Dylan16807 8y ago> If the program doesn't have to work, I could make it read 100 cards per second. > Correctness comes first. Simplicity is highly desirable, adds additional cost, but always comes after correctness. Correctness isn't binary. Roughly no software today is 100% correct, but for most purposes you'd still pick the current version over a highly complex, slower, more-correct version. Simplicity can save you a lot of cost as you edit the software, which helps you make it correct sooner. Simplicity and correctness go very well together.
- DannyB2 8y agoIf correctness is some kind of continuum rather than a binary choice, then pick whatever trade offs, cost, and other factors you want. Plenty of times correctness is binary. In some cases it would be: passes all tests. Or: meets all requirements. Even if it could be "more" correct (or "more" simple), but those aren't part of the tests / requirements.
- close04 8y agoI always thought correctness begins when the result of your work does what it's supposed to do. Maybe it's supposed to move from A to B, maybe it should do it in under x seconds, maybe it should go via Y, maybe it has to be easily understood by a 6 years old, etc. But I can't really imagine something that has simplicity as the only requirement ("nothing" is the simplest thing so that requirement would always be met with no action). So as long as the other requirements are met simplicity is usually the nice to have "add-on". And you can have correct and simple, or correct and complex. But correct (does the job) trumps simple. And the world is surrounded by examples that prove this point. I think the author meant "simple should be part of good design" but couldn't properly convey the message. He focused on making the message simple and ignored the fact that it's not correct.
- traviscj 8y agoI’ve noticed a pattern where the simplest solution DOES accomplish the goal, but isn’t what a user might consider the “shortest path”. How do you count a workaround where it technically can accomplish the end result, but requires a minor annoyance? What about a major annoyance? What about a process so painful nobody has even thought of it?
- dwc 8y agoYes, correctness absolutely comes first. One way to achieve greater simplicity is to negotiate for fewer/simpler requirements for the first revision. There's often a core set of functionality that can be implemented correctly in a simpler way, and that gets the work done. Once that's in place it's interesting to see how often people lose interest in what were "hard" requirements before. It's also common that new asks have little to no resemblance to those unimplemented features, and are instead things that they found out they needed after using the new system.
- BlackFly 8y agoHow sure are you that a given program is bug free? I feel that only very rarely would I ever assert 100%. In fact, I would generally assert with 100% confidence that there is some overlooked edge case. How many users that bug may affect... well I would generally give that a small percentage, but it still doesn't hit the boolean state of correct. So correctness is generally never satisfied in my mind. At any given moment, the programs I am working on are in some way broken in my mind. Even if the other programmers thought that correctness was priority number 1, I will never consider the program correct. I will always suspect there is some snake in the grasses. I suppose you could feel the same way about simplicity. I think the most charitable stance would be to give them the same level of importance. Overtly complex code cannot easily be proven to be correct amid changing business requirements. Easily testable, complex code with a full functional test suite is at less simple in one sense. Patently incorrect code is hardly valuable regardless of how easily one can understand its function.
- DannyB2 8y agoI can not be sure the code was bug free. It was an anecdote in a book, the focus of which was more about the psychology of those who wrote the code. But it worked, and the first program did not work. The non working code's author took pride in the speed of his code.
- BlackFly 8y agoDon't get me wrong, I think its an excellent anecdote. I just shy away from a focus on correctness since in my experience people who prioritize correctness above all else usually make a shambles. I feel that people who prioritize simplicity still understand that it still needs to work more or less correctly.
- annabellish 8y agoNone of them are absolutes. Just as we do not expect that "simple" before "fast" means "the code must be 100% as simple as it could possibly be before we begin even thinking about speed", we do not mean "the code must be 100% correct in every possible way before we even start thinking about simpleness" It is relative preferences, more about what takes precedence over what than an absolute measure. Nothing is ever perfectly correct, nor perfectly simple nor perfectly fast.
- ythn 8y ago> Correctness comes first. Not always. Have you ever used a SNES emulator? There is one emulator that is more correct than all others combined - it's called BSNES and it's the most true to the original SNES hardware of all the available emulators. Yet it is horrifically memory/cpu hungry - that correctness comes at a huge cost. So no, correctness does not always come first, especially if you value other things like user experience.
- DannyB2 8y agoCorrectness then is a trade off against other factors. Also it seems correctness in this case is a continuum rather than a binary choice. And you would prefer to trade other important factors for "true" correctness. But I'll assume that you want the software that calculates your paycheck to be correct.
- DougBTX 8y agoThe follow on from that is “performance is a feature”. If the emulator is supposed to emulate a fun, playable, game, then perf would be a required feature :-)
- KirinDave 8y ago> So no, correctness does not always come first, especially if you value other things like user experience. I think you're using a different definition of "correctness" than most other people in this thread. Which is understandable, a lot of folks are using different senses of it. What matters is not, "Does this perfectly and unobservably play hardware" in the definition of correctness for an emulator. What matters is, "Can this emulate the cart I want to play right now with a good experience?" and perhaps, "Will this allow a malware maker to own my entire computer if they run a cleverly crafted fake cart file?"
- kibwen 8y agoBSNES trades off performance for emulation accuracy. Other emulators trade off emulation accuracy for performance. No widely-used emulator that I know of has any care for simplicity at all (all of them are chock full of one-off special cases to benefit specific games). This has little to do with the screed in the OP, especially given how little the OP appears to value performance.
- sgt101 8y agoWorks today, but tomorrow the complex solution does not do what is needed and presents a barrier to delivering what is needed now. In a static environment you are right, but static environments are vanishingly rare for software, by definition (because with stops after one iteration!)
- kibwen 8y agoWhat is this comment trying to say? That a simple program that doesn't work today is better than a complex program that works today, but that might not work in some nebulous future? Not all complexity is reducible. The point of software is to work correctly, not to satisfy the author's aesthetic notions, which is what most of the modern hype over simplicity boils down to.
- mlthoughts2018 8y agoI think you missed the parent comment’s point, which is that a highly complex implementation might have problems very similar to overfitting in statistics. Simplicity in some sense means “room to expand to handle future unseen cases.” If an implementation is very complex, chances are it has some assumptions baked in somewhere and when it hits the wrong corner case or a new requirement is added, it manifests not as some mere refactoring annoyance, but as a complete meltdown where the system is revealed to be incapable entirely, and has to undergo major delays due to huge refactoring that can lead to ripple effect problems in other parts of the system. In that sense, simplicity is like insurance against the future, and so at any given moment you don’t solely care about the system’s total correctness or performance right now but also you care about some diversification benefit of investing in simplicity too. Very much like how you don’t choose stocks based solely on what will have the highest expected return right now, but instead you also incorporate some notion of risk management when optimizing.
- sgt101 8y agoWhat I am saying is that a ball of mud that passes all tests is worse than something clear that fails corner cases (genuine corner cases) because sorting that out can be done. Whereas the ball of mud will definitely fail in the future and when it does nothing will help you apart from a complete rebuild. "It passes the tests" simply doesn't cut it.
- Daycrawler2 8y agoThat was my first thought as well but then I realized that by correctness the author means "no bug", which is quite more ambitious than just making it "work". I think the author implicitly assumes the software basically works right from the beginning of the article.
- kibwen 8y agoIf that's the case then the author is attacking a straw man, because nobody (besides Dijkstra) is suggesting that we rewrite all the software in the world in Coq in order to 100% eliminate bugs at the cost of simplicity.
- KirinDave 8y agoThat's not what Coq would do, and a misrepresentation of Dijkstra's position. We certainly could use tools like TLA+ to assist us with existing code. Folks are using "simple" and "easy" interchangeably here. That's probably inappropriate.
- kibwen 8y agoI apologize for using Coq speicifically, I just needed a scapegoat for formal verification that people might have actually ever heard of. :P I'm happy to debate definitions, which the author of the OP has regretfully omitted (and the contentious definition here is probably the OP's notion of correctness, rather than their notion of simplicity).
- KirinDave 8y agoTo be honest, I'm fine skipping it. I don't understand why this article is so upvoted anyways.
- AstralStorm 8y agoYou'd be surprised how simple a well written proof can be compared to a program implementing an algorithm to do the same. That said, Coq itself is not the best vehicle for this. There are nicer high order logic languages.
- dredmorbius 8y agoGerald Weinberg. A classic, inpired much of Demarco and Lister's Peopleware. https://leanpub.com/thepsychologyofcomputerprogramming https://leanpub.com/thepsychologyofcomputerprogramming
- kibwen 8y ago> Correctness comes first. Simplicity is highly desirable, adds additional cost, but always comes after correctness. Seconded. I'm highly confused at how many upvotes the OP has gotten in such a short time despite appearing to say that implementation details matter more than program output. A beautiful machine that doesn't work is, at best, a statue. I'm all for the existence of pretty things that do not need to demonstrate inherent practicality, but most people are not printing out source code for use as wallpaper.
- lubujackson 8y agoTo defend the idea, I think it starts with the assumption that software is often a moving target so "correctness" is at best a temporary state. If you had to use a codebase at any point of time you would obviously want the correct one, but if you look at the lifespan of software it would be better to have the simpler code. Simpler is (usually) easier to fix, easier to extend and easier to learn. I think the author made this a little inflammatory to get people to think about it in these terms.
- AstralStorm 8y agoEasier to fix, yes. Tends to get more complex in nasty and ugly ways. Easier to extend, almost never. Proper design for extensibility has an extra bit of complexity over the most obvious. Simplistic implementations tend to be tossed away and are good for unscalable prototypes. Easier to learn, definitely not. The simplest code comes from deep understanding of problem domain and algorithms. It is almost exactly like with writing brevity while not losing the point. It is easy to end up with simplistic instead of simple. There is that famous quote by Dijkstra which I'd rather not butcher from memory.
- kungtotte 8y agoI think the core consideration is that software isn't static, and a machine that is held together with chewing-gum and silly string can produce the correct output and be a terrible machine at the same time. What happens when it breaks? What happens when you need to produce doodads as well as gizmos, or a different size gizmo is desired? Who wants to reach inside the silly string and hope for the best? I'm reminded of that old saying that even a broken clock is right twice a day; an overly complicated piece of software that produces the correct output is only coincidentally correct. Which I think is the point of the article.
- jpfr 8y agoYour example is a case of premature optimization. That is not what the author is concerned with. The problem are not the programs that obviously do not work or who break in a very visible fashion. Programs whose deficiencies are known can be fixed or worked around. The real problem are programs that appear to work correctly but aren't. To say it with the words of Tony Hoare: There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. It demands the same skill, devotion, insight, and even inspiration as the discovery of the simple physical laws which underlie the complex phenomena of nature. Source: 1980 Turing Award Lecture; Communications of the ACM 24 (2), (February 1981): pp. 75-83.
- kibwen 8y agoThat quote actually refutes the OP by reinforcing that correctness is more important than simplicity. Achieving correctness is the whole point of making things simple, after all. To put simplicity before correctness would be missing the forest for the trees.
- jpfr 8y agoCorrectness is achieved by simplicity.
- kibwen 8y ago> Correctness is achieved by simplicity. That's... literally what I just said? "Achieving correctness is the whole point of making things simple, after all."
- jpfr 8y agoThat's... literally what the author said. If your solution is not simple, it will not be correct or fast. Correctness may be the end-goal. But correctness is absolute. So it is a bad performance indicator to set as the goal. Yes, we can track bugs. But the absence of open bugs is no guarantee for correctness. I can never say "We are 5% more correct than last week. Keep up the good work!" Simplicity is a much better goal for the day-to-day work. Because it can be tracked, measured and evaluated for every individual change.
- SuddsMcDuff 8y agoThe thing is, correctess is often a transient property. Requirements are frequently changing or evolving. What's correct on a Tuesday may no longer be correct by Friday. Under these conditions it's important that the software be amenable to change. It's for that reason I believe simplicity is more important than correctness.
- kibwen 8y agoSimplicity is also a transient property. > Under these conditions it's important that the software be amenable to change. At the same time, under all conditions, it is important that the software actually works (i.e. correctness), which is why it's more important than simplicity. Irate users who come to us telling us that our program doesn't work will find little comfort as we regale them with how simple it is. First, make it correct. Then, make it simple. If requirements change what correctness means, then make it correct again, then make it simple again.
- chillacy 8y agoI encountered a similar argument in Clean Architecture by Robert Martin of correctness vs maintainability, where he argues for maintainability over correctness. The argument goes that if you had to choose between code that did the wrong thing but was easy to make do the right thing, and code that does the right thing but is hard to change, you should always pick the former. He also talks more abstractly about the value of software (as opposed to hardware for instance) being primarily in its "soft"-ness, or ease of changing. Ultimately this comes from his point of view as an architect, who fights more for system design than say, a PM might for user features. I've encountered the opposite school of thought that says: MVP to deliver features, refactor/rewrite later. I think the strategy to use will depend on the project and team (budget, certainty, tolerance for failure, etc)
- p0nce 8y ago> Simplicity always comes after correctness. Strong disagreement here. A program that isn't kept simple will stop being correct, fast, or any desirable quality over time.
- kibwen 8y agoNobody's saying that simplicity is unimportant, but if the failure mode of a loss of simplicity is that the program is no longer correct, then it inherently suggests that correctness is the primary metric to strive for. :P
- p0nce 8y agoAbility to change ("simplicity") is the key metric that allows to maintain, or further desirable invariant. eg: in b2c "correctness" may be less valued than another trait. Do you prefer to know something or to be able to learn fast?
- ptero 8y ago> Correctness comes first. Simplicity is highly desirable, adds additional cost, but always comes after correctness This may be a matter of definitions. It may be worthwhile distinguish between general correctness and full, as close to 100% provable correctness as you can get. That way allows us to dismiss clearly degenerate cases (you can always do a one-statement no-op program that will be simple but do nothing). General correctness is what I want in most cases. Example: voice dictation. It requires a final read & polish, but errors are infrequent enough to save me a lot of time. Full correctness is usually requested for jet avionics, nuke power plant control, etc. With that addition one should optimize for general correctness and simplicity as a first goal, full correctness and performance as a very distant second. When I write software (or build systems) what I end up with is usually significantly different from what I started with; not externally, but under the hood. Keeping designs simple (on large teams being almost militant about it) helps large systems morph as it goes from a proof of concept into an actual thing. My 2c.
- kibwen 8y ago> It may be worthwhile distinguish between general correctness and full, as close to 100% provable correctness as you can get. Which is the root of the endless back-and-forth in this thread: a program has to do what it says on the tin ("general correctness") before anything else, and then probably be as simple and as "fully correct" as possible. But it's easier said than done for us to posit a distinction between general and full correctness than to actually find exactly where the dividing line lies between the two. A blog post to discuss such a dividing line might have been valuable, but the one we've got here unfortunately just handwaves away all the hard questions.
- zzzcpan 8y agoThere is no line between the two. It's something that depends on how much effort and time is put into this, what methods were used, etc. But, the world doesn't actually care about this specific property, as it has no inherent value. Instead we have various levels of assurance of more practical properties, like safety, but not correctness.
- extralego 8y agoDoes the time it takes to write come into play here at all? I’m a novice of sorts. Thanks.
- mooktakim 8y ago> Correctness comes first. Simplicity is highly desirable, adds additional cost, but always comes after correctness. Yes, but what is "Correctness". Its not usually so binary. Get to "good enough" and move onto the next thing.
- danesparza 8y agoThis makes me think of the Donald Knuth quote, "Beware of bugs in the above code; I have only proved it correct, not tried it." More info here: https://en.wikiquote.org/wiki/Donald_Knuth https://en.wikiquote.org/wiki/Donald_Knuth
- AstralStorm 8y agoWhich is why we now have automated theorem provers that can refine proofs into programs.
- ginko 8y ago"A program that produces incorrect results twice as fast is infinitely slower." - John Ousterhout
- fwdpropaganda 8y ago> Correctness comes first. I agree with this. Interestingly, the post is very simple, and not correct. I prefer posts which are slightly more complex but correct, but those don't get as many upvotes.
- dcre 8y agoIf it's not simple, it might be incorrect and you'd never know until it bites you.
- j45 8y ago+1. Simplicity won't work if it isn't correct. Simple correctness is the best way to create beginners that use software to get faster results. Fast isn't all about computation - it's taking the least amount of the user's time as reasonably neccesary.
- jackhack 8y ago>> They called in an outside insultant. This is either a great typo, or a hilarious moniker I have somehow missed (almost 40 years in the business). Either way, it's worth recognizing. Equal parts hilarious and accurate as "/in/con/sultants" are often brought in to play the part of the court jester -- they can speak the hard truths no-one else could, and survive. >>"Yes, but MY program ACTUALLY WORKS". If the program doesn't have to work, I could make it read 100 cards per second. I think I wrote a device driver like that, more than once. :( Fast as hell, to the point of outstripping the bitrate of the device it talked to, and about as useful as a sailboat on the moon.
- falcolas 8y agoThere's a great Dilbert where Dogbert wants to both con and insult someone. So he goes to consult for Dilbert's PHB.
- tshannon 8y agoI was going to say the same. The conclusion I came to personally was always Accuracy > Maintainability > Performance in that order
- smaddox 8y agoAnd since "fast enough" is a part of "correct", the order should really be "correct, fast enough, simple".
- eikenberry 8y agoI don't think this is the form of correctness discussed here. I believe this is more the Correct as discussed in the famous "Worse is better" article.
- torstenvl 8y agoYou cannot have correctness without simplicity. "A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over, beginning with a working simple system." - John Gail
- nerpderp83 8y agoThis book, "The Psychology of Computer Programming" is by Gerald Weinberg, an author that really explores the design and complexity of systems. I recommend his other books, esp, "On the Design of Stable Systems : A Companion Volume to an Introduction to General Systems Thinking" http://www.ppig.org/library/book/psychology-computer-programming http://www.ppig.org/library/book/psychology-computer-program...