Is code formatting a blessing or is it killing the art of writing beautiful code? Today we weigh in on the arguments for and against formatting and how this might affect your coding process. An early point against formatters, we talk about how they limit nuance and some of your ability to communicate through your code. Following this, we chat about how projects can be held up because of someone’s “opinion on how code should look.” A problem that’s solved by formatters. We discuss how formatters decrease friction in a group setting before touching on the cases where they reduce clarity. After diving into why formatters are useful if you value consistency, we explore cases where you might prefer either customizability or to be bound within strict parameters. We then compare linters to formatters and share why new developers should learn code hygiene. In wrapping up the conversation, the hosts highlight the fact that, despite their issues, they all use formatters in their projects. Tune in to find out why.
Key Points From This Episode:
- How co-host Dave Anderson has developed a balanced view of code formatters.
- The view that formatters can take nuanced communication from coders.
- Taking the friction out of coding by using formatters.
- Contexts where formatters can reduce clarity — or create bizarre spacings.
- How formatters like Prettier deal with customizability options.
- Comparing linters and formatters, along with their use cases.
- Why Ruby’s philosophy means that no strict formatter exists for the language.
- Teaching code hygiene to new developers by not using formatters.
- The hosts share their final arguments before reaching their conclusion.
Transcript for Episode 178. Code Formatting - Friend or Foe
[0:00:01.9] MN: Hello and welcome to The Rabbit Hole, the definitive developer’s podcast. Live from the boogie down Bronx. I’m your host, Michael Nunez. Our co-host today —
[0:00:09.3] DA: — Dave Anderson.
[0:00:10.1] MN: And our producer.
[0:00:11.3] WJ: — William Jeffries.
[0:00:12.2] MN: Today, we’ll be talking about formatters, is it a blessing or killing the art of writing beautiful code. I’d love to hear what you guys have to think about formatters. Are you anti-formatting, are you for it? When you hear ‘formatter,’ Dave. What are some thoughts that come into your head? Is it easy?
[0:00:28.7] DA: Yeah. I, for one, welcome our robot overlord. They’ve taken my job of deciding between the tab and the space. And how many of those tabs in the spaces. And also the carriage return and I don’t really miss it. I wasn’t comfortable with it at first but I’m okay with it, you know? I think we talked about this, like, throwing away tabs, episode 98. I mean, we were talking about linting. But we were starting to get introduced to these things. And now, been a couple of projects where I’ve used them and I think it’s alright, you know?
[0:01:04.0] WJ: I’ll play devil’s advocate here. I think there’s, like, a real loss when you hand over all of the nuance and subtlety of formatting to a machine that just standardizes everything. I think, very often, the beautiful formatting work that some other engineer has done gets replaced by garbage when you introduce Prettier.
Formatting is a tool that we have as engineers in order to communicate meeting more effectively to other engineers that have to read and maintain our code. And Black and Prettier and other kids of formatters take away that tool from you.
[0:01:48.2] MN: You know what I dislike though? I agree with you that you typing the code, that has been typed, rather, in the way that you did it.
Everyone has their own way of knowing how code should look like. What I dislike though is when those call outs happen in a PR that hold up features, which is why I often would just say, “Hey, I think we need a formatter for something,” right? You know, some people, they put a space after the curly raise. Or, like, they don’t end the file with a new line. And all sorts of these other things that can hold up your feature from being merch because someone has an opinion on how code should look.
I think that oftentimes, when that blocker becomes a thing that we have to deal with, then it’s like, “All right, well then let the machine do that for us.” It becomes really difficult. It’s like correcting someone for their handwriting. I find that to be like, “Dude, if I write this way, leave me alone, as long as you can understand what’s on the piece of paper, what’s wrong with that?”
[0:03:41.8] MN: Yeah.
[0:03:43.1] WJ: How the values vary. That’s the kind of thing where there are some circumstances where doing that is really good for clarity. And some circumstances where it’s really bad and like, that is a judgment call that I don’t think you’re ever going to be able to teach a robot to do for you.
[0:04:01.6] DA: Right. I guess if you want to be able to have that control then you can have a looser restriction. Like in a linting role, like a line limit. And leave it at that. And then the risk is that you may have some disagreement on the team about when that’s appropriate or maybe even if that’s appropriate to have that kind of spacing. I remember seeing that in, like, in imports, also. And other places like some people love it and there’s sprinkle it all over the place like lining things up with wide space — and it can be helpful.
But I do generally value consistency above all things. That’s kind of why I like code formatting. Even though sometimes it does run on my file and I’m aghast by what it has done. Where it’s just like — “You know what you need? You need more line breaks. Everything needs a line break.” And there’s going to be, like, one word on each line and your 10 line function is now 50 lines. It’s likem “What did you do?”
[0:05:11.6] WJ: Yeah, I think we’ve all had that moment where you run your formatter and are horrified by the choices it’s made.
[0:05:17.0] DA: It’s kind of amazing because it’s the same code right? Like the formatter will never change the code itself, it just changes the spacing around it. But I guess your point, the space does change the aesthetic impact of rooting the code.
[0:05:34.7] MN: I think there is a thing about, I know Prettier, super opinionated about the formatting that it does. Dave, as a person who appreciates formatting, are you okay with a formatting standard that you may or may not agree with but because it’s just a stand-in that someone else decided that call it a standard that you would just continue to move on with your life. And just use Prettier in that sense? Or are you of the class where it should be plain as day and then as code comes in, we discuss what things or what patterns we want to follow in our formatter.
[0:06:14.2] DA: I love the same set of defaults that just gets you going. I had never really used a Mac for development till I started at Stride. I had used Linux before and I thought, like, “This is what I love.” I really enjoy using Linux. But then I realized that Linux was like the ultimate in customizability. And I had to set up my drivers, I had to apply the patch, I had to configure this and that. And generally, I would say, lowest axis, more leaning on the side of Prettier in the tooling option. Where it’s like, “Okay, things just kind of work,” and the philosophy that people make tools for that platform too is — “It’s just going to work.” And that’s kind of nice. You do have that customizability and you can break out and mess around —
[0:07:04.7] WJ: That’s the thing with formatters like prettier is that you can’t customize. That’s part of their philosophy. If you go and open a GitHub issue on Prettier and you say, “Hey, I think that this one particular formatting choice that Prettier makes is bad and I want to be able to customize this — what it does differently.” They will close your ticket, that’s just standard, they’re like, “Nope, we’re not going to do that, see the Prettier philosophy, we don’t do customization.”
[0:07:51.7] DA: I mean, it’s definitely in the top five I guess, yeah. That’s a lot.
[0:07:58.2] MN: You know, for some reason, there are people on the planet, and I’ve grown accustomed to this, you know what? They don’t want to use semi-colons anymore than I think semi-colons are dumb. Why would you use semicolons? My other top four languages don’t use semicolons. So why do I need them?
Your Prettier file, you can change it, it’s like, “Hey, make sure you ensure that there are no semicolons.” And you can now add that to, I think, it’s the Prettier RC file. That — what you can then change it. And then you can have certain things. Or, another fancy one that often gets argued at teams that I’ve seen is the trailing comma. Where, if you have a key value pair, that ties a new line. On the last item, do you add a coma to it? Some people really like it because if you leave the coma there at the trailing comma, then it allows you to add a new line without disrupting the git.diff with two lines. And just adds to the one. Some people like that and you can definitely change that in Prettier now.
I think it was really strict before William but I think they might have softened up I guess, allowing you to make the little changes you want to do.
[0:09:03.1] WJ: it’s actually the opposite. They used to be soft and then they got hard.
[0:09:09.0] MN: Wow.
[0:09:09.4] WJ: Those customizations are grandfathered in for backwards compatibility and they no longer add new ones.
[0:09:17.4] MN: Oh, okay.
[0:09:18.3] WJ: So if you go to the prettier.io website, they’d say the option for us fee there is like a section of the wiki on this Prettier has a few options because of options history in bold — “But we don’t want more of them.” And then they have a whole page where they talk about why they will got any worse.
[0:09:36.6] MN: I was wrong the whole time ladies and gentleman, don’t listen to me ever.
[0:09:42.0] DA: There are a lot of emojis on this page.
[0:09:42.7] MN: There is a lot of emojis on this page, yeah. It is like the rocket and the thinking emoji, that’s a good one. That is always a good one. Yes, so I think the idea of having it super strict, I think what Dave mentioned before, like, if you have a super strict and then you can talk about the changes that you can make/ I think that is probably one way to do it and then the other way is like, hey, if you get a lot of call outs in your PR because you don’t have a formatter, raise that as a team. And figure out which formatter options are beneficial to the team to continue moving forward.
But I think there are some things, William, as you mentioned. Like, the idea that people are going to write code the way that they write code, it is like expressive in that regard. Regardless of whether they use a trailing comma or semicolons. That is how code gets written and I think a machine coming over and swiping all of your changes to make it look uniform destroys the uniqueness of the code that you added.
[0:10:40.3] WJ: Yeah, I mean I think that this is one of the differences between formatters and linters. Is that linters provide a high degree of customization for teams that have preferences about their style. And formatters, in their philosophy, like the whole reason that they Python formatters called black is from Henry Ford’s model-T car. You can have it in any color you like so long as it’s black. There is no customization — that’s part of the philosophy.
[0:11:38.7] DA: Hindsight, I guess. But I mean that’s the interesting thing there. Is there any reason why you would want to use a formatter and a linter?
[0:11:50.0] WJ: I think so. I think that formatters are really good for style choices that can be automated. But linters are much more powerful than that though. I mean, because they don’t actually autocorrect your code, they can detect problems that just require judgment in order to fix. Cyclomatic complexity, you can add a linter rule that the cyclomatic complexity score has to be below a certain number. That is a thing where there is no way to teach a formatter how to fix it. It’s just like — you need to figure out how to extract a method or simplified code in some way.
[0:12:27.3] DA: Yeah and I guess they are also correctness or comment bugs that you might have — unused variables. And things like that that the code formatter is going to apply all of the spaces, tabs, and line breaks that it wants to it but it is not going to actually change the code or even just the back code could be a problem for you.
[0:12:49.7] MN: I have a question, is there no formatter for Ruby? Is that in the Ruby philosophy that Ruby should not be formatted? I am having a hard time trying to find a formatter that is heavily supported.
[0:13:03.6] WJ: I don’t think there is one. I think that there are a couple of quirks about the Ruby community that have sort of insulated it from the blessing/curse that is formatting. I think the Ruby community really prides itself on there being more than one right way to do a thing. There are some methods in Ruby, like map versus collect, they just do the exact same thing. Any ideas, “There is more than one way to do it.” And that is pretty into cycle to the formatter philosophy.
And then also the Ruby community tends to adapt an open-source project. You get like a huge amount of community support for existing open-source projects. So people just added an auto-format option to RuboCop, which was already the main linter. And then just started using it for formatting. It is not a proper formatter the way that Black and Prettier are, where it’s like super having opinionated, not customizable. “We just parsed the STN print back out for you and you’re stuck with what you’re stuck with.”
[0:14:10.3] DA: Yeah, I am looking at the stars on GitHub and RuboCop has 11,000 stars. And then there is a project called Rufo, a formatter for Ruby that has 600 stars and a plugin for Prettier for Ruby that has 900 stars. But RuboCop is great, like, it is so good. I remember the first time I was learning Ruby on our first product together William and we were like messing around with RuboCop and I was just blown away with how good is that fixing a lot of the problems automatically. Which, working more with Python, the linters don’t really have that helpful feature so much.
[0:14:52.2] WJ: And RuboCop is the most customizable. There are thousands of different cops you could choose from.
[0:14:59.4] MN: Yeah, I think RuboCop is pretty in depth with the amount of things you can change on it. I think maybe, as you mentioned William, before, like, the Ruby community has taught that the expression of writing code to be more important than the format of that code. I could respect that. I’m sorry William, I think I am still going to use formatters in the end.
[0:15:19.0] WJ: I was just advocating it on my current project that we add one and made a story for it and implemented it yesterday.
[0:15:27.0] MN: Yeah, I mean I think the idea that Ruby doesn’t have one is pretty cool because of it being able to express the way you write. The way you write code is the way you write it. And you can answer a solution in many different ways, as William said. I wish formatters were more introduced. I have been mentoring some students on how to program and they always get caught up with the tabs. And it makes me cringe that I say like, “Oh they add three spaces and then maybe two.” Like, I don’t really know.
[0:15:52.3] DA: Oh my god, no. I have seen that and I don’t want to be that guy but you are making me be that guy.
[0:15:58.4] MN: Yeah, exactly. That’s like the hard part yeah. I understand why your code editor doesn’t automatically do it, like, right from the start. But it is such a small think to learn when you’re thinking about programming for the first time. But it is really important because you want to make sure that their coding hygiene is okay enough to understand the tabs, the spaces within their code make sense. But I definitely understand why formatters exists. But I also understand why it is not automatically turned on when you open up VS Code, for example.
[0:16:29.4] DA: I didn’t even think about that whole possibility. When William was giving his pitch about the elegance and the choice that you have to express yourself without a formatter through the white space that you put on the page. But that darkest timeline is so dark.
[0:16:48.3] MN: Yeah, imagine three spaces rather two or four bro. And getting away with that.
[0:16:52.9] WJ: Like one hund-o P, when I am working with a junior developer, I absolutely make them set up the formatter in their editor. I don’t want to be responsible for what I do to you if you continue.
[0:17:05.7] MN: Exactly.
[0:17:06.6] DA: It’s got to be like going to be like, going to therapy.
[0:17:08.9] MN: I think formatters can be good. But I have to look at that at a different lens now. I think I am not going to be super finicky in how people write code. But I’ll ask them why they think that’s good. And that will be an inspiring conversation. It may as well be interesting.
[0:17:22.0] DA: There you go and then you run a formatter and then it just erases all of their uniqueness from the world you know? I wish we had set this up as an awkward-style debate because I feel like it would have won. Everyone is convinced. Although, maybe not entirely, I don’t know.
[0:17:37.6] MN: As much as I love the elegance of you writing the code the way you have it — nah. Run it through the formatter, bro. It has to be unified. David, you mentioned before, uniformity is important as well. I think people are going to bring their different styles of programming and then we all agree on a format for us to do that.
[0:17:57.2] DA: I will nitpick here, variable names has to —.
[0:18:00.0] MN: Yeah, the format is not going to help you with that so that’s good.
[END OF INTERVIEW]
[0:18:02.6] MN: Follow us now on Twitter @radiofreerabbit so we can keep the conversation going. Like what you hear? Give us a five star review and help developers like you find their way into The Rabbit Hole. And never miss an episode, subscribe now however you listen to your favorite podcast. On behalf of our producer extraordinaire, William Jeffries and my amazing co-host, Dave Anderson and me, your host, Michael Nunez, thanks for listening to The Rabbit Hole.
Links and Resources:
Our seasoned cross-functional agilists work with you to develop technology, ship product and deliver value. We leverage our diverse expertise across industries and throughout the organizational growth cycle to your benefit. We bring best practices, emergent practices and creative solutions to your problems.