1. 14
  1.  

  2. 3

    Automated code formatting

    • As an individual, you get back all of that mental energy you used to spend thinking about the best way to format your code and can spend it on something more interesting.
    • As a team, your code reviews can entirely skip the pedantic arguments about code formatting. Huge productivity win!

    I will happily die on this hill: No. Autoformat is for noobs.

    Even when they use tools like prettier, I constantly have to point out to juniors ways in which their code is hard to read, repetitive, poorly factored, and so on, on the line level. They pick names that are too long. They don’t extract common subexpressions. They nest way too much. The act of tidying up the code by hand gives you time to think about all of this, it forces you to slow down, and to develop good habits so that there is no mess to clean up in the first place.

    Auto-formatters give you only the illusion that you don’t need to care about any of this. In practice, you still do, only now you’ve taught people that it’s a “waste of time” or “nitpicky” to do so. It is a local maximum that keeps you from getting better.

    The worst symptom is when you have two or three pieces of code that are structurally near-identical, but which auto-format forces to be formatted differently because e.g. one line happens to cross some internal auto-wrapping threshold while another doesn’t. Or because autoformat forbids you from lining it up vertically. Now, code that should look the same looks wildly different because a bot was too dumb to do it right, and somebody convinced you that this is the Rule that must be followed.

    Given a piece of code that was nicely formatted and lined up by hand, nobody can seriously argue that the auto-formatted version is better. It is obviously less clear, worse at communicating intent, and mangling it through auto-format is just like trampling all over a carefully manicured garden. If you do use it, auto-format should only apply to changed lines, as a tool to get you to cleaner starting point. Forcing everything to match a linter’s preferences only seems like a good trade-off if you’ve never seen code crafted with precision.

    1. 7

      I didn’t realize it until I adopted Black, but I used to spend a material amount of my time typing code - I’d estimate as much as 5-10% - agonizing over my indentation. And I was using Python!

      I used to have very strong opinions about when to break up a long set of function parameters into new lines, or how to indent a complex sequence of chained function calls.

      I resisted Black for a couple of years because of tiny, trivial differences it had from my very opinionated way of formatting code.

      Then one day I decided to drop that… and suddenly I was liberated. All of that mental energy I had spent agonizing over where to put my new lines… it turns out I could put that to good work somewhere else instead.

      As for code review: my goodness, the HOURS if not DAYS of time I’ve seen wasted on back and forth between the office pedants and junior engineers over how best to format code. I don’t regret eliminating those conversations in the slightest.

      1. 6

        I couldn’t disagree with you more.

        Even when they use tools like prettier, I constantly have to point out to juniors ways in which their code is hard to read, repetitive, poorly factored, and so on, on the line level. They pick names that are too long. They don’t extract common subexpressions. They nest way too much. The act of tidying up the code by hand gives you time to think about all of this, it forces you to slow down, and to develop good habits so that there is no mess to clean up in the first place.

        Perhaps I have a different opinion here but all of this does not sound like the job for an auto-formatter. Poor factorization, repetitive, too long variable names, not extracting common subexpressions, nesting, etc is the sole responsibility of the author (linters can provide hints at some of these things but its not their job to fix them) and you should be pointing those out to so they can write better and more clear software.

        For me the benefit of an auto-formatter is in consistency of formatting. gofmt for example helps make code written by different authors look consistent. If someone has their editor set to 2 spaces vs 4 spaces I don’t want mixed indentation littered about the code base nor do I want to comment in PRs telling people to change their editor settings. The auto-formatter is there to make it so I don’t have to think about it.

        It sounds to me like maybe you have some poor auto-formatter rules or you don’t like the defaults of whatever auto-formatter you’re using perhaps? In most (all?) tools I’ve used if you think your formatting is better you can turn on/off rules globally or on specific lines if you think your formatting is more clear. Not having to think about it or nit pick about it in PRs is a huge win in my opinion.

        1. 3

          I agree with almost all of your points, yet completely disagree with your conclusion. All of the things that you list (repetition, naming, and so on) are things that require understanding of the code (some CSE is possible, though it requires an understanding of the source language). Auto formatting allows you to focus on this on code review because all of the trivial things are handled with a tool. If you have three almost identical bits of code that are formatted differently because of line lengths, the problem is not the auto formatted, the problem is that you didn’t pull this out into a generic function.

          The slavish application of the rules is a huge benefit because it avoids subjective arguments. Either you can unambiguously express a rule about how code is formatted, in which case you can teach the tool to do it, or it is subjective and so you will get disagreements. Any time spent on these disagreements is time not spent on the more important things.

          In my experience, the code review quality is significantly higher on every project that I’ve worked on that uses automated tooling for formatting than ones that don’t.

          I’m still sad that we store text in revision control systems. Some years ago, I had a student implement a project called Code Editing in Local Style, which used a C or Python AST to typeset the code in the user’s preferred style (including capitalisation conventions, variable declaration locations), with the idea that you’d commit code in one representation and edit it in another. I’d love to see modern languages adopt something like this.

          1. 1

            I’m sympathetic to the “friction is good” argument, but obviously these things are tradeoffs with limits. In the olden days, people would write out programs on pads of paper and get everything figured out so that by the time you typed up the punchcards, it was just a matter of text entry. Lots of friction! And they managed to create, e.g., C and Unix this way. But I wouldn’t want to work that way…

            In practice, sometimes prettier will format something in a way that I find ugly, but there’s typically a way to “fix” it by introducing a comment or something that it has to format around. The benefits for 99% of lines are worth it for the 1% that it does wrong.

            FWIW, gofmt doesn’t change line breaks, only indentation, so lines that are long stay long. I can’t say I can remember disagreeing with gofmt, although Go itself has strong feelings about comma and brace placement that you have to adhere to, which I do sometimes dislike.

          2. 1

            Automated preview environments

            Has anyone working at a big tech, any thoughts to share on this? I always feel like what I could achieve in a nice way on my personal project (or some startup) is simply utterly impossible at $JOB because we’re stuck with a normal Jenkins CI/CD solution and bitbucket PR system.

            1. 2

              I’m not a big fan of SPA architecture at all, but the one thing I will say for it is that it makes preview environments SO much easier: if your application’s UI is pure HTML and JavaScript pulling from production web APIs you can turn on Netlify previews and they just work.

              … for client-side code at least. Server-side code remains much harder to do previews for, though Heroku has had this sussed for about a decade now.

              The hardest bit is when there’s a database involved, since you need a mechanism that can provision a fresh database for each PR - not cheap or easy.

              I think this is one of those things though that it massively less expensive if you build it early on. Having preview environments on a young project is hopefully only a day or so of tinkering - and then you can incrementally improve them as the system grows more complicated.

              Adding them to a large existing application with a lot of moving parts is a whole lot harder.

              1. 1

                I always feel like what I could achieve in a nice way on my personal project (or some startup) is simply utterly impossible at $JOB

                Not at $BIGTECH, but I feel the same way. I can see it not being too difficult if you’ve got a monolith, but once you have multiple teams deploying their own services on different it becomes difficult / tedious / expensive to get a complete environment up for every PR. Probably less useful too.

                For a web frontend it might still be practical to deploy a preview pointing to the production backend, but for stuff further down the stack I’d recommend deploying behind a feature flag and toggling that on for yourself / your organisation only. And once you have that you might just want to use feature flags for the frontend too, for the consistency it provides and ability to slowly roll out the feature to new cohorts of customers—not to mention the ability to instantly roll back.

                1. 1

                  We were thinking about using Jenkins parametrized builds to allow devs to create preview environments from PRs on-demand. But on a first closer look it didn’t seem to be as easy as expected with the parametrized builds and I didn’t spend enough time to dig into Jenkins.

                  1. 1

                    I just finished migrating a few internal tools in order for them to be used from the Jenkins agent, which previously we could’ve ran from the terminal ourselves (compliance reasons…) and played a lot with parametrized builds myself.

                    The major pain-point, to me, is that you’re writing groovy without knowing wether or not it is going to work out, feedback look is tedious.

                    Let me know if you find yourself knee-deep in parametrized builds somewhere down the line!