8 ms·
Write dumb code
- jeffdavis 9y agoI agree, but the author doesn't tell us how to do that in practice.
- anonfunction 9y agoIt's not by the author but Rich Hickey (creator of clojure) has a great talk titled "Simple Made Easy"[1] which I always recommend. Furthermore I have been using Golang and would say it is very simple language that anyone could pick up and become productive with quickly. One of Go's proverbs is "Clear is better than clever."[2] At the expense of a little verbosity there is much less ambiguity in the intent of code. 1. https://www.infoq.com/presentations/Simple-Made-Easy https://www.infoq.com/presentations/Simple-Made-Easy 2. https://go-proverbs.github.io/ https://go-proverbs.github.io/
- keithnz 9y agowhile theres an esssense of truth in this blog ( write simple code ) the details given miss the mark. Software shouldn't be considered a cost, that could lead to the wrong choices, it's just part of a bigger system and costs generally should be measured at the system level. Also you have to be careful with using "interns" as a measure of minimum code level. Often the interns opt for what they feel is simple to understand but can be prone to errors. There are many micro patterns that avoid many problems that come from experience. But the sentiment about not using too clever code is generally good.
- wickawic 9y ago> Software shouldn't be considered a cost I fully disagree. Code is a liability taken on as a calculated risk to perform some task.
- dragonwriter 9y ago> Code is a liability Code is an asset, like any other piece of capital. Like physical capital, using it and maintaining it may have costs. Like physical capital, the costs associated with it are not worth paying if you don't have a productive application for the capital asset that justifies those costs (and, also, the amortized cost of acquiring the asset in the first place.)
- majewsky 9y ago> Code is an asset, like any other piece of capital. When you possess 200 units of some currency, that's strictly better than possessing only 100 units. However, 200 LOC are not strictly better than 100 LOC. When I replace a 1000-LOC program by a shell one-liner that does the same thing by composing some coreutils, I have removed 999 LOC without losing any value. The asset is not the code itself, the asset is the value that you derive from it. Given a certain value that you want, the best code is that which brings this value while being the most maintainable. The article argues that the simplest code is usually the most maintainable one, and thus to be preferred.
- dragonwriter 9y ago> When you possess 200 units of some currency, that's strictly better than possessing only 100 units. However, 200 LOC are not strictly better than 100 LOC. Yes, which is why I didn't say lines of code is a currency (or even a commodity), only that code is an asset. Having 200 industrial robots comprising one factory isn't strictly better than 100 different industrial robots comprising a different factory — industrial robots aren't a currency. But factories, and the industrial robots within them, are still textbook capital assets. > The asset is not the code itself, the asset is the value that you derive from it No, the asset is the code. As with any asset, the reason you acquire the asset is the expectation of a deriving a value from it that is greater than the cost of acquisition + maintenance of the asset. The “code is not an asset” argument is phenomenally ignorant about what assets are, because every element of that argument is perfectly normal for non-cash assets.
- 9y ago
- ams6110 9y agoParallels Strunk & White's Elements of Style. Who knew there was so much similarity between writing code and writing prose? Omit needless words. Write in a way that comes easily and naturally to you, using words and phrases that come readily to hand. It is always a good idea to reread your writing later and ruthlessly delete the excess. Avoid the elaborate, the pretentious, the coy, and the cute. Do not be tempted by a twenty-dollar word when there is a ten-center handy, ready and able.
- Royalaid 9y agoWhich has inspired https://leanpub.com/elementsofclojure https://leanpub.com/elementsofclojure
- perl4ever 9y ago"Je n’ai fait celle-ci plus longue que parce que je n’ai pas eu le loisir de la faire plus courte." -Blaise Pascal
- zimpenfish 9y ago> Parallels Strunk & White's Elements of Style. Although do bear in mind that some professional linguists (Geoff Pullum being the ur-example) consider EoS to be an abomination of ignorant claptrap.
- collyw 9y ago"Write in a way that comes easily and naturally to you" That's pretty much what I did at the start of my career. Nowadays I think things through a lot more (and generally come up with a lot more robust solutions).
- dswalter 9y agoThis post is by the author of the dask parallel computing framework, which is written in Python and getting some traction in astronomy circles.
- xstartup 9y agoOur company's full-time job is to shrink our customer's codebase size aggressively. Your team will not do that because it's a job security to them. Let us make your company where it's easy to fire anyone without risking major drawdowns.
- HumanDrivenDev 9y agoSo you're with a consulting company specialising in refactoring!? How do you sell that to people?
- xamuel 9y ago>Your team will not do that because it's a job security to them Every team I've ever been on [albeit that's only two], it's the opposite, if the devs had their way they'd spend all day every day simplifying and refactoring. The only reason we don't, is because actual business needs demand attention.
- sooheon 9y agoAgreed. Putting out fires sadly takes precedence over future fireproofing.
- psyc 9y agoProcess/policy often prohibits refactoring for its own sake. I've always got round this by rewriting everything 5 times before checking it in for the first time.
- dingo_bat 9y agoIf I had a free reign over my time at the office, I'd spend at least a month just cleaning up the mess that has accumulated.
- flukus 9y ago> Our company's full-time job is to shrink our customer's codebase size aggressively. Your team will not do that because it's a job security to them. No, they did do that, that's where the layers of bloat originated from. Everything turns out to be not quite as generic as the authors thought and that helper function end up as it's own class with an inheritance tree, etc. That fancy mapper that uses reflection to eliminate hundreds of lines of boilerplate becomes a liability because information is now lost to future maintainers. I don't want less code, I want simple, greppable code that allows me to trace data across the codebase.
- partycoder 9y agoVery similar to the "the principle of least power": - https://en.wikipedia.org/wiki/Rule_of_least_power https://en.wikipedia.org/wiki/Rule_of_least_power - https://www.w3.org/2001/tag/doc/leastPower.html https://www.w3.org/2001/tag/doc/leastPower.html - https://blog.codinghorror.com/the-principle-of-least-power/ https://blog.codinghorror.com/the-principle-of-least-power/ I also would like to add this blog post by Li Haoyi (from Scala.js fame) - http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html#philosophy-principle-of-least-power http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLe... I think the tradeoff is maintainability and flexibility. I think code cannot be allowed to be complex. Complex code will eventually be broken during maintenance.
- userbinator 9y agoIt is often the case that the simplest solutions require the greatest skill in achieving. Thus, I agree immensely with avoiding unnecessary complexity whenever possible, but not "We should endeavor to write code that a novice programmer can easily understand without explanation or that a maintainer can understand without significant time investment." --- which tends to lead to extremely verbose, inefficient, and dumbed-down code. In other words, if you only ever use the very simplest features of the language, you are effectively reducing micro complexity but increasing macro complexity. One of the best examples of this is the classic arguments over the use of the ternary/conditional (?:) operator --- those against say it's hard to read and should always be replaced with if/else, while those for say it simplifies the code by removing redundancy and should always be used in place of an if/else with a single assignment statement with the same LHS in both clauses. Similarly, if you believe programmers are almost completely incapable of understanding operator precedence, or that it "makes code hard to read" and restrict expressions to only one operator (and mandate that variables be created for all intermediate results), then you will get code with all the verbosity of Asm but none of the benefits. In other words, good code may not be immediately obvious; but your reaction when you do understand it should be one of pleasant enlightenment, and not "I can think of a simpler way to do this." A somewhat related article: http://typicalprogrammer.com/what-does-code-readability-mean http://typicalprogrammer.com/what-does-code-readability-mean
- quickthrower2 9y agoYes definitely. If you code using a VB6 style subset of your language you'll probably end up with spaghetti. That's easy to understand at an individual procedure level but pretty hard to refactor and maintain.
- flukus 9y ago> If you code using a VB6 style subset of your language you'll probably end up with spaghetti Unless I'm remembering incorrectly I'd say the opposite, vb6 had a pretty sane feature set comparable to "modern" languages like go and rust. Coding with that feature set will give you simple and understandable code, if a little verbose at times. The spaghetti code it's famous for was mostly a result of the event driven, drag and drop nature of the IDE and community. If you want real spaghetti code then try vb.net which suffers from the same problem but allows devs to pile on a bunch of OO features that obscure what code is doing.
- nine_k 9y agoApparently the author mistakes dumb for simple. Usually dumb code is layers upon layers of needless complexity, grown because the coder had neither time nor inclination to understand the problem, and kept tweaking. Such dumb code becomes a huge support and troubleshooting cost, letting alone quickly modifying it. Don't write dumb code. Write simple code. The recipe is known: think about the data first, untangle and minimize dependencies (including any global state), write simple, orthogonal functions over these data. Use the language's standard library and built-in data structures. Crave for these negative line count PRs. It takes much shorter time than working with dumb code.
- sooheon 9y agoCurious, what are your top 2 favorite languages (or CS thinkers)?
- hinkley 9y agoSimple also gets us into trouble. Straightforward is the way to go.
- marzipan 9y agoIf it's complex and hard to maintain, then it's not dumb code. It's genius code. Dumb code is actually very hard to write successfully in production and there isn't a recipe for it. The novice flails and makes the code too complicated trying to add one hack on top of another without doing any causal analysis, the journeyman programmer starts throwing in a lot of defensive abstraction they learned about yesterday that doesn't tame the problem at hand, and the expert writes a correct solution that is exactly what is needed and no more. As a bonus, when you enter a new problem domain you're a novice again. All that stuff you knew about working with databases is irrelevant if you're working with real-time audio. But you get to skip through the cycle faster this time. Ergo, dumb code. It's hard to make dumb code that actually stays dumb instead of turning into genius-level complexity or bad abstraction.
- AstralStorm 9y agoThat is some interesting definition of genius you put in here. Usually the criticism of so called genius code is about manual optimization and sometimes domain specific optimization and not about crust achieved over years of lacklustre maintenance. There ate actual real reasons you shouldn't or cannot write dumb code. One piece of such "cruft" is handling numerical corner cases which is unavoidable unless proven mathematically to be impossible (And commented why). Using IEEE floating point? Guess you get to handle ULP precision, NaN and Inf. Using integers? Welcome to wraparound. Memory management? What happens if an allocation fails? Threads? Race freedom is quite interesting to achieve. Using Java? Then figure out what happens when you choke GC with hundreds of objects. Etc. You can only go so far in passing the buck to library authors, they can make mistakes too.
- somethingsimple 9y ago> Software is the currency that we pay to solve problems, which is our actual goal. We should endeavor to build as little software as possible to solve our problems. Amazingly well put. I’m gonna try and not forget this so I quote it when discussing with people who love to come up with bloated, overengineered solutions.
- ScottBurson 9y agoMy point today is that, if we wish to count lines of code, we should not regard them as “lines produced” but as “lines spent”: the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger. — E. W. Dijkstra One of my favorite quotes :-)
- dbcurtis 9y ago> Software is the currency that we pay to solve problems, A great mind shift there.
- pvsukale3 9y agoIMHO this is the philosophy behind ruby and rails. Any kind of software has a people cost. We should be able to spend less time writing software and it should be a time efficient process as we pay for it using human time.
- collyw 9y agoIronically I find Ruby code one of the hardest languages to read when I see a random snippet.
- skun 9y agoKiran addressed a very similar (if not the same) topic at the PyCon India 2013 keynote: https://www.youtube.com/watch?v=_stsJlNgGfA https://www.youtube.com/watch?v=_stsJlNgGfA (40 mins). I was there at the keynote and it really helped set my basics very strongly. Highly recommended.
- seanmcdirmid 9y agoWriting dumb code is a lot more expensive up-front than writing smart code. It is like writing something in simple-to-understand prose; that costs more on write than hard-to-understand prose, but pays off when read. So I feel like the author of this essay is talking about some costs (the reader's) without considering the cost of the writer. If the code is never read because other solutions are considered more viable, then all that cost in making it simple for not. As always: 1. make it work. 2. make it nice (if it works and is going to survive to code review). 3. make it fast (if it has performance problems). Unless you are completely on waterfall, you aren't going to be able to do 1. and 2. concurrently.
- CloudYeller 9y agoI'm not sure if it's more expensive either. The first correct algorithm I can think of, expressed in the programming equivalent of pre-K level English, usually is less buggy and 10X easier to maintain than the advanced-language-feature-filled code that certain engineers love writing. And it takes a fraction of the time to write because it doesn't require much refinement. Is it slower than finely tuned C++? Yes. Does that matter? michael-scott-NO-GOD-NO.gif It boggles my mind when people who are just building an everyday website decide that querying models from the DB means we need a multi-level class hierarchy that requires a 5 page paper to explain. Or that anything remotely related to math means we need to start overloading operators. Congratulations! Your brain recognizes patterns! Wow, someone should make you the President of all Engineers Everywhere. The code you're writing now will likely not survive another 2 years, especially if every time there's a bug or even a question like "how does feature X work under condition ABC?", everyone shrugs their shoulders and has to read 1000 lines of horribly nested abstractions.
- seanmcdirmid 9y ago> The first correct algorithm I can think of, expressed in the programming equivalent of pre-K level English If I can think of it, then I hope it already exists and I can just reuse it. The tricky stuff that needs a lot of thought is the same stuff that you can't just reuse off the shelf. > It boggles my mind when people who are just building an everyday website If it is something so routine that it doesn't need to really be designed, then I guess you can do it right the first time from memory (shame you just can't reuse some functionality if it is so routine though). > The code you're writing now will likely not survive another 2 years I work in research where your code is lucky to survive 2 months. I don't disagree with you, but you can't crank out perfectly simple code on the first go if the design space is clear. Those abstractions usually don't exist because the programmer was trying to be clever, they often exist because the programmer was trying to solve the problem. Its only with hindsight that we can often see a better more simple way (and hopefully have time to go back and do the simpler way).
- IncRnd 9y agoThe author wrote a nice piece, but it should be called, "Write Dumb Code," but, "Write correct & concise code." Dumb code doesn't mean the same thing as short code.
- justboxing 9y agoI've heard and read about this time and again over the years, but am yet to find a blog post -- including this one -- or video that take an existing set of code snippets that is un-necessarily complex, and then refactored / re-written that code to be dumb code that performs similarly but is easier for any rookie to understand and maintain. Can anyone point me to real examples for C# or Java?
- ssivark 9y agoI haven't programmed in C# or Jave, but I was recently looking into expository literature on why functional programming helps write more modular code [1]. I found the following Haskell-based example to be really enlightening: http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/#functional-style http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way... I think it's okay to skim over the Haskell specific parts; what I really liked how the end result (version 10 of the program) is nicely composed out of orthogonal pieces, compared to version 1, which is a monolithic blob, while "simple". So, if you want to solve a related but different problem, you can reuse everything you've written instead of duplicating code. So any bugfixes/improvements to one part can trivially be propagated to all other use cases. [1]: https://blog.acolyer.org/2016/09/14/why-functional-programming-matters/ https://blog.acolyer.org/2016/09/14/why-functional-programmi...
- pdimitar 9y agoMartin Fowler -- Refactoring. Best software practices book I've ever read, even though I don't use Java for a while now. It's FULL of practical examples. Most of the book is examples, and it's not a small one.
- root_axis 9y ago> The best way you can contribute to an open source project is to remove lines of code from it. Deleting code doesn't necessarily mean you're making it simpler. Compressing a 5 line function into a snazzy 1-liner is almost certainly making the code worse, not better. > Every line that you write costs people time. This kind of mantra is how you end up with nested ternary expressions and tightly wound functional compositions in imperative languages.
- Dreami 9y agoI don't think he meant compressing 5 lines of "normal code" into a one-liner. He meant, actually removing it. Maybe the logic it provides is not needed anymore, or you could do it somewhere else in a far more readable way (I'm thinking about abstraction levels)
- root_axis 9y agoSure, and I think we can all agree that this type of refactoring is useful, but I have worked with many developers that really take this anti-LoC idea to heart and end up producing difficult to read code because they are so focused on finding the most terse way to express logic.
- rumcajz 9y ago> Deleting code doesn't necessarily mean you're making it simpler. Compressing a 5 line function into a snazzy 1-liner is almost certainly making the code worse, not better. What about using something like gofmt? That way you can't get rid of lines by just rearranging the code.
- deleted 9y ago[deleted]
- dawhizkid 9y agoIt took me a little longer to understand higher order functions in JavaScript than it took me to understand for loops but once I “got it” then using something like array.filter((x)=> x%2===1) seemed cleaner and arguably “simpler” than the alternative but not “dumber.”
- mvindahl 9y agoAlso, unlike the for loop alternative, it clearly expresses the intent. "I am filtering this array, using this condition". The functional programming style really shines here, and it shines even more whan you start chaining the operations. I guess the rule of thumb is to write code to most clearly express the intent of it. Often harder said than done but a good goal to strive for.
- collyw 9y agoTo be fair the new arrow operator syntax is a bit cryptic. I am sure Ruby offers plenty of things like that, because when I look at Ruby codebases I often don't understand what they intend to achieve.
- shobhitchittora 9y agoGold mine of Empathy!
- perlpimp 9y agoConsistency is the name of the game. Principle of least surprise. Keep flow happening. etc etc.
- lopatin 9y agoI find these kinds of articles ultimately unhelpful. I do agree with the overall message, but with the lack of practical examples, all I came away with is a description of the problem we're all too familiar with already (software design is hard, simplicity is desirable) but no answers to how to achieve that in the real world. "Don't use recursion to solve a problem easily solved by a for-loop, except when recursion is the right tool for the job." You're not wrong. Just not terribly useful advice when fighting against real complexity in systems.
- bootcat 9y agoI have to completely agree with the article, and that has been my learning working for biggies in the US. But not all people agree on that. They consider themselves smarter, after writing complex code with no documentation. Also, certain people make value with complex stuff instead of making it easy as a breeze for others to understand and contribute.
- carussell 9y agoHere are links to two of my favorite essays that make a similar point: Java for Everything[1] Too DRY[2] And then there's a third, which is not quite the same topic, but still in the same vein. It's arguably even more relevant today than three years ago when it was written, especially given how much attention is being captured by ecosystems that attract folks who end up generating a morass of terrible tooling: Helping my students overcome command-line bullshittery[3] 1. https://www.teamten.com/lawrence/writings/java-for-everything.html https://www.teamten.com/lawrence/writings/java-for-everythin... 2. http://jamie-wong.com/2013/07/12/grep-test/ http://jamie-wong.com/2013/07/12/grep-test/ 3. http://pgbovine.net/command-line-bullshittery.htm http://pgbovine.net/command-line-bullshittery.htm