20 ms·
Kernighan's Law: You are not smart enough to debug it
- joker3 7y agoThe output of a machine learning algorithm is code that no one was clever enough to write. In light of Kernighan's law, that should give you pause.
- finolex1 7y agoThe intelligence required to write a piece of code =/= the intelligence required to understand it. Usually the second is a lot easier. Writing a fancy Haskell typeclass to structure a problem might require deep expertise or creativity. Working with such an existing solution isn't as hard. Even in math or science it's harder to create something new than it is to merely imitate it.
- ehnto 7y agoFancy algorithms or one liners are not all that difficult to understand, because all the information is right there. It's when you're writing convoluted code inside a big system that issues of understanding begin to arise, because the incoming developer is unlikely to have all of the context that made the code make sense to the person who wrote it. It's hard to write a concise example because it really takes a big application to make the point, but consider: featureFlag(10, false); processOrder(); What's flag 10? I have to go figure it out, wastes time, oh turns out it was to disable tax, why are we doing that? Okay in the function that called this one we checked if we were processing a subscription order. versus if(order->isSubscription) processOrderWithoutTax()
- jstimpfle 7y agoIt's not about working with an existing solution, but about spotting the error in it.
- rantwasp 7y agoyeah no. this is not imitating something. This is troubleshooting something that does not behave as expected. The issue is that it works on the normal case/flow but it does not in other edge cases. You're in trouble when you no longer understand why you did things is a certain way when you thought you were "clever"
- s_dev 7y agoIt's easier to write code than to read. This isn't a fact but it is generally accepted by many. It doesn't seem obvious at first why but "reading code" isn't like "reading". https://jonathanfries.net/code-is-still-harder-to-read-than-write-part-1/ https://jonathanfries.net/code-is-still-harder-to-read-than-...
- yebyen 7y agoIt's also called the law of "Uphill Analysis, Downhill Invention" which states "It is much more difficult to guess the internal structure of an entity just by observing its behavior than it is to actually create the structure that leads to that behavior." Been reusing and repeating this one quite a lot, since I saw it mentioned in one of this year's RubyConf keynotes: https://blog.jessitron.com/2019/11/05/keynote-collective-problem-solving-in-music-science-art-and-software/ https://blog.jessitron.com/2019/11/05/keynote-collective-pro... (There is a blog-post version behind this link as well, in case anybody wanted to skim the contents rather than watch video of the entire talk to find out how it fits in.)
- gherkinnn 7y agoUphill Analysis, Downhill Synthesis is a major point in the book Vehicles. [0] Fascinating thought experiments. Here’s an introduction on YT [1], though it really only scratches the surface. [0] https://www.goodreads.com/book/show/483485.Vehicles https://www.goodreads.com/book/show/483485.Vehicles [1] https://m.youtube.com/watch?v=A-fxij3zM7g https://m.youtube.com/watch?v=A-fxij3zM7g
- yc_mat 7y agoImho this is a fallacy. I would argue that in order to fully and truly understand some code you have to be able to re-create it from scratch. E.g. to explain weird constants, data structures, design decisions, estimations on complexity. Hence, in my eyes, the intelligence required to perform those tasks are the same. But, there is a backdoor. Solving problems needs immense creativity. Not everyone that easily grasps a piece of code (a domain expert, savant, MIT wizard) could have written it. To my eyes, that doesn't mean that the savant is necessarily of inferior intelligence, but likely less creative in this area.
- duxup 7y agoI worked in a technical support department for a long time. I often was the guy between the customer (the technical customers) and the engineering teams. After a while figured out pretty good ways to manage my interactions with the engineering teams, despite having no coding experience or really any visibility to the code. How I worked with Development and Continuation teams was DRAMATICALLY different. When working with "Development Engineering" (they wrote new code) I always asked them: "What does X, Y, Z do?" Effectively I always asked them what they think the code "should" do and what the results should be. There was no point in presenting them "OMG it doesn't do the thing" because they would just panic, get defensive / shutdown. Rather I understood they knew what their code does (well what they thought it did) and asking them that was the key to get them talking / sharing. After I had their words and phrasing I could better present "Hey we see A, B, C under D conditions. I expected to see X, Y, Z." That would get a lot more buy in from those folks. I also had to avoid some of the more obvious "hey it does G" where G would obviously break the feature entirely... they often didn't understand use cases (one guy I'm pretty sure didn't even know what the product did, but he could program an ASIC for sure..) so you had to be careful about spelling out customer experiences and rope in a program manager if you felt there was a fundamental problem. When working with Continuation Engineering (bugfixes and etc): These guys were much more receptive to the customer's story on on how the customer is using the code / equipment, and you could much more quickly present "Seeing A, B, C, under D conditions. So then I changed L and got M..." and so on. Continuation engineering grocked the meaning of why someone would change L... and so it was helpful. Continuation didn't often know what the code "should do" (or they weren't confidant in their understanding) so just saying "Saw A... that's not right" meant nothing to them. In contrast development engineering needed to talk about the happy path first. Note that much of this occured after I gave them a good writeup / heads up of all the information I had (even if they didn't read it I never kept anyone in the dark). It got to the point that if a panicked support call came in and it was end times and someone gave engineering a heads up, they would ask it be assigned to me if I was in the office. Technically I was far from the best tech, but I could talk to engineering. It was telling how much a difference there was between debugging and initial development.
- datenhorst 7y ago> Effectively I always asked them what they think the code "should" do and what the results should be. https://rubberduckdebugging.com/ https://rubberduckdebugging.com/
- arsome 7y agoI've always found this one a bit peculiar - usually debugging is about looking at something on a simpler, lower level than implementation. Rather than looking at a whole set of logic, let's step through it piece by piece, look at each operation. When done slowly with care and understanding of the lower level components in the system, debugging code is simpler than learning and implementing most architectural patterns in all but the most extreme of circumstances (compiler bugs, hardware faults). Or maybe I just spent too much time in OllyDbg at a young age to notice.
- jonahx 7y ago> Or maybe I just spent too much time in OllyDbg. Yes. Because if you have to use a debugger to understand a piece of code (your own or someone else's), the author has already failed. Good code can be read and understood without any additional tools.
- bluGill 7y agoFor complex code you cannot understand it in the debugger. You can understand how it works, but you can't get the design of why it works (or should work if it had been implemented to the design)
- ehnto 7y agoI will usually plop a breakpoint at where the problem is presenting itself (often in a controller or view), scan up the stack to find where I think the problem is actually being caused, then break at that point and walk through the code as you suggest. If I understand the application really well often I don't need to do the first step, but it can be a handy shortcut.
- leeoniya 7y ago> usually debugging is about looking at something on a simpler, lower level than implementation the lower you go, the less context you have about the author's intent. with too-clever code it's easy to miss the forest for the trees. e.g. it usually works fine to fix spelling errors at word level, but less well to restructure complex sentances without larger context.
- leeoniya 7y agotitle would be less vague as /s/it/your cleverest code
- laumars 7y ago> title would be less vague as True but that's too many characters for HN's title field. Which might be why it was submitted with editorialised version. > /s/it/your cleverest code massive nitpick but you should be suffixing rather than prefixing the regex with a slash: s/it/your cleverest code/ As I said, this is a massive nitpick; literally the only reason I pointed this out was because the submission was about debugging code and I liked the irony of debugging someone's posted about debugging code :) (there is another law somewhere about people who nitpick are prone to making mistakes in their corrections thus getting nitpicked themselves -- I'm hoping I'm not exception hehe)
- leeoniya 7y agohaha, oops! can you tell i'm primarily on windows? something about needing the hn editor to be a REPL...
- jerf 7y ago"there is another law somewhere about people who nitpick are prone to making mistakes in their corrections thus getting nitpicked themselves" https://en.wikipedia.org/wiki/Muphry%27s_law https://en.wikipedia.org/wiki/Muphry%27s_law
- artemonster 7y agoDisappointed that there was no „Greenspun‘s tenth rule“. It‘s HN, after all ;)
- xt00 7y agoKernighans law: Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. (Brian Kernighan) The rest of the laws are interesting, so I’d recommend taking a look as well..
- BossingAround 7y agoI don't know, if I can debug code on my workstation, that does not seem extremely difficult. Time consuming, if anything, but I feel like anyone with sufficient grit could do that, regardless of education. Tracking down a bug and fixing it with a one-liner does not feel like productive programming (though it brings value to the business). If I can't debug code on my workstation, e.g. it's running on Kubernetes with service mesh and a cool feature must be added, that's when all hell breaks loose. For example, debugging why Kubernetes deployed on OpenStack will push an image to its internal repository but won't pull from it, that is hell and I'd much rather debug HTTPD than that.
- ehnto 7y ago> if I can debug code on my workstation, that does not seem extremely difficult. Time consuming, if anything, I find debugging saves time overall. I don't have to guess about anything, I can see it working or not working, quickly run one liners to confirm. Sometimes getting an application into a certain state takes a bit of wrangling too, and a debugger helps save time by not having to constantly set up that state to see how things have occurred. You can just sit on a breakpoint while you deduce what's going on. A bug that happens at checkout success is a good example. Going through checkout over and over again is time consuming.
- BossingAround 7y ago> debugger helps save time by not having to constantly set up that state to see how things have occurred Absolutely. I found out very quickly in my career that I can either stare into the code for hours to see the tiny mistake, or spend 10 minutes stepping through the code to let it tell me what's wrong. But, it is of course more difficult if you have to debug a complex code base that you don't know. It might take you hours to even know where to place debuggers. So, it can be time consuming, but of course it's still orders of magnitude faster than staring into the code, trying to see where the issue is.
- leetrout 7y agoIs that a common issue you’ve hit with K8S? I had this exact issue in an OpenShift system.
- austincheney 7y agoAnother way to think about this: The more steps that exist between the developer and the end product the less likely the developer is to care or identify whether their solution is clever.
- piinbinary 7y agoA possible corollary is that if you are smart enough to make the code simple, you are also smart enough to debug that code. (Making simple code for complex problems is hard!)
- davnicwil 7y agoI agree it's hard to build a simple solution to a complex problem, but not necessarily wrt what we normally talk about as problem solving skills in programming. What I mean is the hard part is stepping back and actually solving the real problem in the best way. That might be utterly trivial code wise, it might be brute force vs optimal. It might be just solving a readily parallelisable problem on a single thread. It might be a unilanguage monolith instead of microservices in the 'right language for every task', etc. The smartness involved in making code simple (and I mean simple, not elegant) is more about pragmatism, lateral thinking, discipline and focus on end goals than any sort of analytical smartness.
- naniwaduni 7y agoNormally doing the former entails the latter anyway...
- lr4444lr 7y agoEh... Not denying the law is correct, but this kind of thinking makes more sense when you're not doing some cloud SaaS solution that can have daily changes due to business needs and continuous deployment. Code can get complicated over time because business moves fast and there isn't time do everything perfectly. It isn't always people trying to be too clever by a half.
- Swizec 7y agoThe business folks can be too clever too. Dealing with that at work right now. We got super clever, changed a couple times, tried to be even more clever, and engineering gets to pick up the mess and try to make it all work.
- commandlinefan 7y agoWriting code that can be debugged is a skill that can’t be taught, only learned from experience. Sometimes painful experience.
- pattisapu 7y agoThere's a saying in my family, which is full of good cooks: The sign of a great cook is not the ability to make great dishes -- it's being able to fix dishes that someone else screwed up!
- contingencies 7y agoNice one. Added a paraphrased version to https://github.com/globalcitizen/taoup https://github.com/globalcitizen/taoup
- pattisapu 7y agoWow! Interesting to see "firsthand" how the various bits of folk wisdom we come across make it into fortunes. Nice work on this project by the way!
- deleted 7y ago[deleted]
- stared 7y agoIt reminds me of a typical code written by scientists. IMHO there is the biggest gap between the raw intelligence and software engineering skills (including good practices). So, it means that most of the code ends up as code-golf-style contraptions, incomprehensible for anyone else (including their future themselves). Full disclaimer: I used to be that guy who liked "clever hacks". Now I try to make code readable in the first place (largely thanks to Python philosophy).
- perl4ever 7y agoThis. I'm not saying I know much about good software engineering practices, but I used to be interested in amateur astronomy and spent time translating Fortran and BASIC code written by astronomers to C, and it was awful bordering on enraging. Several years ago I discouraged someone who called me about a job supporting supercomputing applications for scientists - perhaps subconsciously due to this prejudice.
- edmundhuber 7y agoYou shouldn't feel bad about this, you might have saved someone from a lifetime of fixing wacky science bugs in exchange for not a lot of money.
- perl4ever 7y ago>someone Me?
- jimws 7y agoI am one of those who moved from Perl to Python. As a Perl coder I loved writing clever hacks. After a few months of Python I began appreciating simplicity and elegance in code.
- Balgair 7y agoI'll second this. One grad student friend of mine traded me a case of beer for a Saturday of help on his code. It was some code to record spike timings in the olfactory cortex and also control valves (smelly research). By the 12th nested for-loop, I gave him back the beer.
- deleted 7y ago[deleted]
- shanemlk 7y agoAnd if you write Laws thinking you're Moses, you're not smart enough to code.
- jodrellblank 7y agoYou don’t think Brian Kernighan is smart enough to code?
- deleted 7y ago[deleted]
- Bendingo 7y agoAnd if you don't know who Brian Kernighan is, you're not informed enough to judge him.
- lowbloodsugar 7y agoHit a performance cliff and rewrote a simple divide-and-conquer multithreaded application into a two-thread solution using hand-rolled map and list structures using optimistic concurrency with atomics and paying attention to dining philosophers. Didn't work first time, funnily enough. For about a day I was terrified that it would never work. Then I found my mistakes (two). Except in emergencies like this, my time is much better spent writing "inefficient" yet easy to develop code that everyone can understand.
- tomrod 7y agoI'm tickled pink to see Hyrum's Law included here. Hyrum and I were grad school chums. Not too many brighter folks out there.
- dwmkerr 7y agoThat's awesome! Hyrum's Law is one of my favourites in the repo and one I share the most often :)
- madez 7y ago> Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. The expression "by definition" is misplaced here. The first proposition "Debugging is twice as hard as writing the code in the first place" is not a definition. At best, we can treat it as an axiom. In any case, the conclusion "if you write the code as cleverly as possible, you are not smart enough to debug it" does not follow by definition.
- hinkley 7y agoI promised myself I was going to stop getting sucked into pedantry. I believe that the sense in which he meant 'by definition' is that it's tautological to say that more of something is more than less of something. For n > 0, 2n > n
- madez 7y agoThe meaning of what the quote is saying is clear. It is also clear how the logical reasoning is supposed to be. My - admittedly pedantic - point is that the choice of words is incorrect.
- smoyer 7y agoOver 20 years ago, after I had devised a way to use Gray Code to embed a clock into a signal without increasing the signal's modulated bandwidth, one of my engineers said that someday there'd be a "Moyer's Law". I thought that was funny, so I created one myself: Moyer's Law: "When we can finally print from any computer to any printer consistently, there will be no CS problems left to solve." Since every good law has a corollary, I created one of those too (simply to be funnier): The Corollary to Moyer's Law: "The printed dates will still be wrong." While PDFs have brought us closer to "universal printing", I won't claim we're anywhere close to solving all CS problems. Sadly, date conversion and formatting continue to be problems (hint, consider UTC ISO-8601 or RFC3339 dates/times for the JSON representation). P.S. I don't actually think I'm smart enough to have a law named after me ... nor have I really contributed enough to "our art". - https://en.wikipedia.org/wiki/Gray_code https://en.wikipedia.org/wiki/Gray_code - https://www.electronics-notes.com/articles/radio/modulation/frequency-modulation-fm-sidebands-bandwidth.php https://www.electronics-notes.com/articles/radio/modulation/...
- thrtythreeforty 7y agoDo you mind explaining the gray-code-clock technique?
- vbezhenar 7y agoTemporal literals really deserve dedicated syntax in JSON. I'm bored to parse yet another "18.2.2020".
- smoyer 7y agoI agree but I'd like the generic implementation of that. JSON schema never really took off and I believe that part of the reason is that there's not a way to indicate what type might be contained in a string or number (I'm okay with JSON booleans and null). As ugly as it could get, adding XML Schemas to XML documents did in fact help the parser. The reason I stated I'd like the generic version is that there are other types that we use consistently. There's a very nice RFC available for telephone numbers that we've started following and we can marshal/unmarshal pretty easily from strongly typed languages (where we control the code), but wouldn't it be nice if there was a standard way (within the JSON to let systems know it was a telephone number? - https://tools.ietf.org/html/rfc3966 https://tools.ietf.org/html/rfc3966
- lkbm 7y agoI liked the optimistic twist on this, Kernighan's Lever: http://www.linusakesson.net/programming/kernighans-lever/ http://www.linusakesson.net/programming/kernighans-lever/ Kernighan's Law means that you're continually forcing yourself to level-up in order to debug your own code. It prevents stagnation. Use caution in multi-developer environments. :-)
- strangerw 7y agoOr it could mean, be too stupid for complex tools, be dumb and choose [simplicity]. [simplicity]: https://github.com/dosyago/dumbass https://github.com/dosyago/dumbass Personally I find the original law inspiring.
- Bartweiss 7y agoA related interpretation: your debugging tools need to be at least as good as your programming tools. Ideally, better. Debugging a K8 cluster with print statements is hopeless, but if the cleverest code you can write in a dumb editor is going through a good test suite and profiler, you might be fine. How many as-clever-as-possible optimization tricks have been made viable by Valgrind?
- deleted 7y ago[deleted]
- mkagenius 7y agoWhy do we pay attention to BS like this?
- deleted 7y ago[deleted]
- edejong 7y ago"The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague. " - EWD 340 [1] [1] E.W. Dijkstra - The Humble Programmer, ACM Turing Lecture 1972 (https://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340.html https://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340...)
- ScottBurson 7y agoReally interesting to read this now, almost 50 years later. So much has changed — and so little has changed.
- edejong 7y agoAbsolutely. Many of Dijkstra's EWDs have aged remarkably well. [1] [1] https://www.cs.utexas.edu/users/EWD/ https://www.cs.utexas.edu/users/EWD/
- amai 7y agoWhich brings us to the interesting question: Is God smart enough to debug it’s own code?
- tomohawk 7y agoThis is one of the things I learned to really appreciate about Go. Code readability and comprehensibility is way better than any other language I've ever used.
- nitwit005 7y agoYou're ready for a promotion from software engineer to senior software engineer once you've spent hours debugging some piece of software, only to realize it's actually working as intended.
- aewens 7y agoIs this implying the debugging was due to the code appearing incorrect or that the previously preceived erroneous behavior was actually intended?
- nitwit005 7y agoThe previously perceived erroneous behavior was actually intended. Just code that's extremely difficult to understand and debug.
- carapace 7y agoSee also Mark Miller's adages: https://web.archive.org/web/20090215132813/www.caplet.com/adages.html https://web.archive.org/web/20090215132813/www.caplet.com/ad...
- hinkley 7y agoThe trick, I believe, is in convincing yourself that finding a simpler way to achieve the same result is a more worthwhile form of cleverness. You still get to be clever, but only you will ever know how clever.
- KerryJones 7y agoThis highlights the importance of writing clean, legible, and well-thought-out code but is also an excellent example of hyperbole and false statistics. I've debugged my code consistently for 15+ years (which if you were to take this as law, would imply I doubled my intelligence with a crazy-high compounding rate, and while I enjoy my ego, that's a bit too much for me).
- contravariant 7y agoAlthough curiously it's a lot more difficult to write simple code (if you want it both complete and correct).
- yellowapple 7y agoThis law is actively biting me in the ass right now as we speak ;) Gotta love T-SQL, where hard things are easy, easy things are hard, and one must perpetually choose between extreme cleverness and extreme verbosity because there is absolutely no middle ground.
- gombosg 7y agoSuch a good read, thanks for sharing this page! (And the authors of course)
- _bxg1 7y agoI write every piece of code as if someone else is going to have to be able to use it later, even if it's just for me. And I find remarkable overlap between the clarity that some random person would need and the clarity that future-me ends up needing.
- CodeWriter23 7y agoI say: get clever, spend the inordinate amount of time debugging, then level up.