1. 15
    1. 5

      Interesting observation, though I’m not so sure it’s really how Kernighan intended it. I also know that there’s plenty of code my (much) younger self wrote that was so convoluted I wouldn’t be able to debug it now - instead I’d probably end up having to rewrite it.

      Also, having to load up the required state in an old code base that I haven’t touched in a while, I might find hard enough to do even if I wasn’t as absolutely clever as I could be when writing it. In that particular context even “dumber” code might confound me, simply because I had forgotten all about the context. That has nothing to do with growth per se. I could be a lot wiser and know a lot more about programming, yet still find certain types of terse code unapproachable.

      All in all, I prefer to interpret Kernighan’s comment the other way - try to avoid making code that’s hard to follow. On the other hand, if you have to use a fancy technique that’s dependent on a lot of theory, it probably is worthwhile (just be sure to include references for the reader - either your future self or someone else).

      1. 3

        I think the logical fallacy here is equating clever with smarter or better. It’s like Mark Twain once said “Sorry I’ve written so much code, for I didn’t have the time to write a shorter program”

        I see where they are coming from though. I defend my right to FAFO and to take gambles and bets in my code. I push boundaries and only after crossing them do I see the true limits. However my goal is never to be clever, if anything I want more simplicity. But sometimes you only see the simple path after going the long way around.

          1. 1

            Interesting. I originally wrote Ben Franklin and then searched and changed it to Twain.

        1. 3

          Reading this made me realize part of the reason I dislike working in Go.

          Unlike languages like Rust, which allow you to be as clever as you want, Go tries to force you to write all your code in a way that is simple enough anyone could understand it.

          While this may arguably result in more maintainable software, it also makes it harder to push yourself to improve beyond your current skill level.

          I suppose this encourages a divide between hobby programming, which is done to make you a better programmer, and collaborative programming, which is done with others to make a useful program.

          1. 2

            This whole article is a bit nebulous with liberal use of non-defined terms such as “cleverness” and how it imagines both code and a scenario where you need to debug it, and don’t know why.

            In my experience with real-world debugging, the primary motivator is state management and the primary motivation for debugging was to figure out exactly where some state was being modified into an undesirable state. Nothing about “clever” code or even how well I understood the code, just so long as I can keep following the breakpoints until I see where the bad mutation was, and going up the stack to fix it. That’s it, it’s that easy, and I didn’t even need to craft up a spiel about imagining clever code and how there’s an artificial metric to comparing said code with how easy it is to debug it. Yeah, I get non-deterministic bugs exist, but that’s leaning more into the realm of problem domains than general debugging (as in, who’s executing your code non-deterministically? The OS scheduler? The async runtime? The network? The day of the week?).

            Honestly, I’m having a hard time figuring out what this article is even trying to tell me. Don’t write hacks, I guess?

            1. 1

              I don’t fully agree with this sentiment. If your problem is so difficult, you just need better debug tools. Rather, I’d say: The complexity of a useful computer system is bounded by the power of its debugging suite.

              1. 6

                Debugging tools are a luxury, not a necessity.

                As someone who has worked in FORTH systems that lacked memory protection, a sufficiently well architectured program can overcome a lack of debugging tools, but the less help you have, the more time you will need to think about the architecture and design of the program, and the less time you will have for actually writing code.

                1. 4

                  Debugging tools are a luxury, not a necessity.

                  I love this statement because it also hints at how expensive debugging tools are and you pay for them in lost expressiveness and abstraction power. It’s hard for me to demonstrate this from first principles, especially within the amount of effort I’m willing to put in this comment, but there are many examples, such as Python not supporting tail call elimination in order to preserve stack traces, or how higher order functions make life harder for debuggers, telemetry middleware etc.

                  I think at the root of it all is the fact that this kind of tooling wants to treat your source code as a part of the program, but this is at odds with abstraction, which wants to establish equivalences between different ways of expressing the same thing.

                  All of that said, I honestly don’t have rigid opinions on which side of this trade-off is better and under what circumstances.

                  1. 2

                    Modern debugging tools are a luxury that nonetheless improve the economics (time efficiency, mostly) of our work.

                    But in the end, you probably did use some (necessary) debugging tools when writing FORTH. Though they may have been so simple that the only affordances you had were control of initial input and the ability to observe the final output. Nevertheless they are a feedback mechanism, as are our modern tools.

                    We should be glad we have our fancy methods of observing state, program flow, etc. It’s good that our debugging tools have improved to the point where they’re clearly distinguishable from input/output manipulation/observation.

                    1. 1

                      but the less help you have, the more time you will need to think about the architecture and design of the program, and the less time you will have for actually writing code.

                      This is exactly what I mean with “bounded by the power of its debugging suite”.

                      Note that with debugging tools I don’t just mean the fancy tools we are accustomed to these days, but also the bare fundamentals like an actual machine to run your code on. You can write software with pen and paper, but it’s going to be error-prone and take an eternity.