1. 9
  1.  

  2. 27

    Very much no to all of this.

    “Reasoning about code” is as far as I understand it a proxy for building a correct mental model of the code, and then using that model to facilitate changes, and predictions about changes, effectively.

    This is a very real process, the most important thing to optimize for when writing software. It’s true that there are different approaches to it, which are each more or less effective in different contexts. But the task is to figure out what works and treat it as a priority — dismissing the entire idea as sophistry is naïve and self-defeating.

    1. 7

      Agreed. The author is kinda missing the point about when he dismissed “reasoning about code” due to the how to reason changing with time and being different between people.

      The only thing that matters is that you can reason about code. It doesn’t matter and I don’t care how you get there.

      1. 4

        There are also objectively easier-to-reason-about practices. Either they haven’t been exposed to it, or they’re just whining. The absolute first thing I thought of as an example: referential transparency, followed by pure functions.

    2. 8

      I think the author protests too much. First of all- what world are we in such that we never care about yesterday’s code, only today’s problems? Do we never have to change (or indeed, as the author says themselves, delete) code that was written yesterday?

      But more concretely, the author repeats the phrase ‘reason about code’ as though it were a total semantic nullity rather than shorthand for a bunch of related processes. Here’s a really simple example:

      x = open(“foo.txt”)

      What does this do? What is the value of x when this line is executed? Is it possible for it to mutate other elements of the global state? Is it possible for it to raise an exception? Can the return value have different types, or only one type?

      That is a handful of questions that you will need to answer in order to write that line, or edit that line, in confidence, because each of them will influence the behavior of your program. And the answers will be very different based on the language the code is in, the paradigm we’re working in, and the rest of the program. There we go: going from the the textual representation of program source to an expectation of the behavior of the executable program generated by the source. We’ve just reasoned about code. We do that constantly, whether we’re reading, writing, editing or deleting.

      1. 8

        We know, for example, that you can basically use any programming language for basically any purpose, because back in the days when there were intellectual giants in computering they demonstrated that all of these languages are interchangeable. They did so before we’d designed the languages. So choice of programming language is arbitrary, unless motivated by external circumstances like which vendor your CTO plays squash with or whether you are by nature populist or contrarian.

        This claims far too much.

        First off, “All languages are interchangeable” does not follow from “you can use any programming language for basically any purpose”. Sure, I can write a web server (or whatever) in python or c or haskell or brainfuck. That does not mean that each of these languages are equally effective for my purpose across all dimensions.

        In light of that, the claim that “choice of programming language is arbitrary” looks more like the author’s own failure to discern key differences between programming languages than some fact about the world.

        1. 3

          There was a twitter thread I saw yesterday about a bunch of “Rails Hot Takes”, where one of the core ideas was thinking about properties of the codebase in economic terms. Speaking about things like carrying costs, opportunity costs and so on.

          Programming languages and communities differ wildly in terms of what they make easy/hard to do and reason about. Yes, all of the Turing complete ones can technically all compute the same things, but a programming language is so much more than it’s computation class. It’s a community (or a bunch of them). It’s what’s considered acceptable. It’s what libraries exist, and which ones can easily be pulled in due to FFI, or the underlying platform. Or which libraries are difficult to make sense.

          1. 2

            I know a guy who wrote a web server in Brainfuck! It wasn’t good or readable, but it served a web page.

            1. 1

              Did it work with CGI?

              1. 1

                No, I think it was called from inetd.

          2. 5

            If you can guarantee simple properties about a module’s behavior, that makes the module’s user-facing interface simpler. Otherwise, a user of the module has to know its implementation details, so that they can anticipate how it’s going to behave. Sometimes, you can provide a proof for those properties, and that’s a very nice place to be.

            It’s true that the real world is messy and uncertain, but that only increases the value of making your system’s internal interactions as simple and predictable as possible.

            1. 4

              But… making code “deletable” requires being able to reason about the code to know that said code is safe to delete? I get that this sort of thing could be argued poorly, or used as a buzzword, but that doesn’t mean the underlying principle is bad.

              1. 3

                Suggested rant tag.

                1. 1

                  /rant on

                  I found the article totally unreadable because there were not one line of code to reason about! Only comments.

                  Comments are bad practice when they do not describe what the code really do, and do not help reasoning about code, the why, the how…

                  /rant off

                  1. 1

                    With different examples one can make plausible points on either side of this debate. In that sense it kind of doesn’t feel worth “reasoning about” from just a theoretical angle.

                    Ruby script vs python script? OO vs FP? Program written with 6 level deep multiple inheritance + mutability vs functions passing around a few well documented immutable data types?

                    There’s obviously no universally correct mental model of anything but that doesn’t mean that everything is equivalently easy or hard to understand. Certain ways of “reasoning about” things become popular or not due to how they resonate with people.

                    1. 1

                      Wait, but isn’t it useful if I can reason about my own code now?

                      1. 1

                        Following this argument using math to reason about the world is also a scam.