The Bike Shed
375: Deleting Code
thoughtbot had an in-person Summit in the UK! Joël recalls highlights. Stephanie is loving daily sync meetings on a new project.
The idea of deleting code has been swimming around in Stephanie's brain recently because she's been feeling nervous about it. Together, Joël and Stephanie explore ways of gaining confidence to delete code while feeling good about it.
This episode is brought to you by Airbrake. Visit Frictionless error monitoring and performance insight for your app stack.
- Thoughtbot summit video
- Gather Town
- Sustainable Rails episode
- Chelsea Troy on deleting features
- Unused
- elm-review-unused
Transcript:
STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn.
JOËL: And I'm Joël Quenneville. And today, we're here to share a bit of what we've learned along the way.
STEPHANIE: So, Joël, what's new in your world?
JOËL: I just got back from a few days in the UK, where thoughtbot has been having an in-person Summit, where we've brought people from all over the company together to spend a few days just spending time with each other, getting to know each other, getting to connect in person.
STEPHANIE: That sounds like it was a lot of fun. I've been hearing really great things about it from folks who've come back. Unfortunately, I couldn't make it this year. I got sick a little bit beforehand and then ended up not being able to go. But it sounds like it was a lot of fun just to get together, especially since we're now a remote company.
JOËL: Yeah, I'm really sorry you weren't able to make it there. It would have been amazing to do a Bike Shed co-hosts get-together.
STEPHANIE: I know. In the same room, maybe even record. What a concept. [laughs]
JOËL: So thoughtbot is a fully remote company, and so that means that getting a chance to have people to come together and build those in-person connections that you don't get, I think, is incredibly valuable. I was really excited to meet both the people that I work with and that I see on my screen every day and people who I don't talk to as often because they're working on different teams or different departments even.
STEPHANIE: What was one highlight of the time you spent together?
JOËL: I'll give a couple of highlights, one I think is more on the activity side. We went bouldering as a group. This was a really popular activity. We were trying to sign up people for it, and it was so popular we had to make two groups because there were too many people who were interested. And it was really fun. There are people with a whole variety of skill levels. Some people, it was their first time, some people had been doing it for a while. And just getting together and solving problems was a lot of fun.
STEPHANIE: Yes, I saw that. That was one of the things I was really looking forward to doing when I was still thinking that I was going to go. And it's cool that it had opportunities for both beginners and people who have been doing it before, which I think, if I recall correctly, Joël, you are a boulderer yourself back home. So that's pretty neat that you were able to, yeah, I don't know, maybe share some of that experience IRL too.
JOËL: Yeah, yeah, I think it's great because people were able to help each other. Sometimes you have a different perspective down on the ground than you do up on the wall. And then, in my case, because I've done it a lot, I know a little bit of actual climbing technique. And so I can give some tips on, like, oh, if you're stuck and you don't know how to get past a particular point, or you don't know how to start a particular climb, or your arms are getting tired halfway up, here's maybe a small change you can make that would make things easier for you.
STEPHANIE: Honestly, that also sounds like a really good metaphor for pair programming, [laughs] like, looking at things from different perspectives, you know, someone who's on the wall? I don't know what the lingo is. But it's the equivalent of someone driving in coding, the navigator having a little more perspective and being able to point out things that they might not see that's right in front of them.
JOËL: I love that metaphor. Now I'm going to think of that both when I pair and the next time I climb.
STEPHANIE: I love it.
JOËL: I think climbing, when I do it, it's always more fun with a friend, specifically for what you were saying. I climb alone sometimes, but as much as possible, I'll reach out to another friend who climbs and say, "Hey, let's climb together." And then we can alternate on the same route even.
STEPHANIE: That's cool. I didn't realize that it could be such a social activity.
JOËL: It is very much a social activity, and I think that's part of the fun of it. It's challenging physically but also mentally because it's a puzzle that you solve. But then also, it's a thing that you do with friends.
I think another aspect that was a highlight for me was getting a chance to connect with people from other teams, other departments within thoughtbot. I think one thing that was really nice when we were located in an office is that over lunch, or just at the water cooler, or whatever, you would connect with people who were in other teams and who were in different departments.
So I might talk to people in People Ops, or in marketing, in operations just sort of in the natural course of the day in a way that I think I don't do quite as much of now that we're more remote. And I tend to talk more with other developers and designers on my team. So I think that was really great to connect with people from other teams and other departments within the company.
STEPHANIE: Yeah, I know what you mean. I think I really miss the spontaneous, organic social interaction that you get from working in an office. And I think we've maybe talked about remote work on the podcast before, or previous co-hosts Steph and Chris have also talked about remote work. But it definitely requires a lot more intention to manifest those connections that otherwise would have been a little more organic in person.
And so, while you all were at an in-person summit in the UK, there was also a virtual summit hosted for folks who weren't able to travel this time around, and I really appreciated that. I got to spend a day just connecting with other people in Gather Town, which is a web app that's like a virtual space where you have little avatars, and you can run around and meet up with people into virtual meeting rooms on this map. [laughs] I'm not really sure I'm describing it well, but it's very cute. It is almost like a little video game.
It's like a cross between a video game and video conferencing [chuckles] software. But yeah, I think I just really appreciated how inclusive thoughtbot has been doing remote work where, like, yes, we really value these in-person gatherings, and we understand that there is a bit of magic that comes from that, but also making sure that no one's left out. And at the end of the day, not everyone can make it, but we were still able to hang out and socialize amongst ourselves in a different way.
JOËL: Agreed. I think that inclusivity is part of what makes thoughtbot such a great place to work at.
STEPHANIE: Speaking of inclusivity, I mentioned a few weeks ago that I joined a new project recently and had been going through the onboarding and hopping into all these new meetings. One thing that I've really enjoyed about this new client team that I'm on is that in their daily sync meetings, we all share what we're working on. But we also all share something that's new to us, which is a little bit meta because we do that on this podcast. [laughs]
But each person just shares maybe something they learned at work but also usually something just totally not work related like a new show that they're watching. There's another person on my team who learns a lot of things from YouTube videos. And so he's always telling us about the new thing he learned about, I don't know, like mushrooms or whatever, or AI [laughs] through YouTube. And yeah, someone else might show a sweater that they just knit themselves. And it's been a very easy way to get to know people, especially when you're meeting a whole new team. And yeah, I've been enjoying it a lot. It's made me feel very welcome and like I know them as people outside of work.
JOËL: I love that. Yeah, they're more than just people you're shipping code with. You're able to build that connection. And it sounds like that helps smooth the...maybe we can say the social aspect of onboarding. Because when you onboard onto a project, you're not just onboarding onto a series of codebases and tools; you're also onboarding onto a team, and you need to get to know people and build relationships.
STEPHANIE: Yeah, absolutely.
MID-ROLL AD:
Debugging errors can be a developer’s worst nightmare...but it doesn’t have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half.
So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking!
Airbrake’s debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted.
In addition to stellar error monitoring, Airbrake’s lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction.
Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality.
Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back.
Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today!
JOËL: So you've been...is it two weeks in a new codebase? Have you gone and deleted any code yet?
STEPHANIE: I wish. I am glad you asked this question because this has been a topic that has been swimming around in my head a little bit lately because this new client codebase it's very big and it's quite old. Like, I've been seeing code from 10 years ago. And it's been a really challenging codebase to get onboarded into, actually, because there's so much stuff.
In fact, I recently learned that some of their model specs are so big that they have been split out into up to seven different files to cover specs for one model. [laughs] So that has been a lot to grapple with. And I think in my journeys working on a starter ticket, I've just stumbled upon stuff that is very confusing. And then I might follow that thread only to realize that, like, oh, this method that I spent 20 minutes trying to grok turns out it's not actually used anywhere.
JOËL: That's a lot of dead code.
STEPHANIE: It is a lot of dead code, but I am also not quite feeling confident enough to delete it because I'm new, because I have no idea what consequences that might have. So, yeah, the idea of deleting code has just kind of been swimming around in here because ideally, we would be able to, but, for some reason, I don't know, at least for me, I feel very nervous about it. So it hasn't been something that I've reached for.
JOËL: That's a great question because I think in maybe Ruby, in particular, it's not always obvious if code is being used or not. When you do find yourself deleting code, how do you gain the confidence that it was safe to delete that?
STEPHANIE: Yeah, that's a good question. In the past, when I've done it successfully, I'll probably post a Slack message or something and being like, hey, I noticed this code is not being used anywhere, or I'd like to delete it because why, like, I don't know, because it's been misleading me because it's just not providing any value. And then kind of give it like a day or two, and if no one speaks up about it, then I will usually go ahead.
And obviously, get some code review, hopefully, get some other eyes on it just to make sure that whatever assumptions I made were valid, and then go for it. And then just watch [laughs] the deployment afterwards and make sure that there are no new errors, you know, no new complaints or anything like that. And, yeah, I think that has been my process, and I've definitely found success doing that.
But I have also experienced a bad result [laughs] from doing that where one time, on my last client project, we were refactoring the signup flow. And we realized that after you signed up, you were redirected to this blank page for like 10 seconds or something. It was completely empty. There was nothing on it except a spinner, I think. [laughs] And then it would then redirect you to the dashboard of the app. And we were like, oh, we can definitely delete this. We have no idea what this is doing. We don't want to try to refactor this as part of the effort that we were doing.
And so we deleted it, only to find out later from the marketing team that they had been using that page for something Google Analytics related, and we had to revert that change. And it was a real bummer because I think when we removed it, we felt good about that. We were like, oh yes, deleting code, awesome. And then having to bring it back without a clear plan of how to actually fix the problem that we were trying to solve was a bit of a bummer.
JOËL: So, as programmers, we're hired to write code. Why does it feel so good to do the opposite of that, to delete code?
STEPHANIE: That's a great question. I actually want to know what you think about this, but before that, I wanted to plug this Slack channel that we have at thoughtbot called Dead Code Society, where people can post their PR diffs showing more red than green, so more lines removed than lines added. And I have been really enjoying that Slack channel. It's very delightful. [laughs] But, Joël, do you have any thoughts about why it feels so good to delete code?
JOËL: There are probably a few different reasons. Especially when it's not your own code, you're often not attached to it. There's often, I think, the sense when you go into an existing codebase you're just like, oh, everything's just bad, and I don't understand it. And those other coders who wrote this didn't know how to do their job and kind of be the curmudgeon character. So it just kind of feels good to remove that and maybe rewrite it yourself. I would say that's not a good mindset to go in for deleting code. I think there are positive ways where it is actually a good thing.
STEPHANIE: That's fair. Just removing code because you would write it differently is not necessarily a net positive. [laughs]
JOËL: But I think...so when I initially asked the question, I said, "We're hired to write code." And I think that's a bit of a false assumption built into the question. We're not hired to write code. We're hired to solve problems, to build solutions. And as much as code can be an asset in solving problems, it's also a liability. And code has varying maintenance costs that are typically not low. They vary from expensive to very expensive. And so any chance we get to remove some of that, we're removing some of the carrying costs, to use a term that we discussed a few episodes back when we talked about sustainable Rails.
STEPHANIE: Yeah, absolutely. One thing that I remember you sharing about the client project that we're both on in the past is they have a very cumbersome test suite. And in some situations, you have wanted to advocate for deleting some of those tests.
JOËL: Deleting tests is a really, I think, spicy take because you're trying to get better test coverage. And if your test coverage isn't great, you don't want to lose any of that. So there's definitely a loss aversion there, and we might need it later. At the same time, tests have a cost, cost to run, cost to maintain. And if they're not providing a lot of value, then the cost of keeping them around might be higher than any kind of benefit they're giving you.
And I think a classic case of this is tests that have either been marked pending in the codebase with an exit or something like that or that have been marked in your CI server as muted; just ignore failures from this test. Because now you're still having to maintain, still having to execute these tests. They're costing you time, but they're giving you zero benefit. And they're just taking up space in your codebase, making it harder to read. So if you can't get these tests back into the point where they're actually executing, and you're caring about the output, then you probably don't need those tests, and they can be removed.
STEPHANIE: Yeah, that's fair. I'm thinking about the perspective of someone who does not want to delete those tests. I think in the past, I've seen it and even felt it myself as someone who probably wrote the tests, kind of hoping for some ideal world where I will finally have time to go back to that test. And I already put a lot of effort into trying to make it work, and I want to make it work. I want to have the value of that test.
And it's kind of like a sunk cost fallacy a little bit where it's like, I already spent however much time on it that it must have some kind of value. Because just hearing that someone else wants to delete the test can kind of hurt a little bit. [laughs] And it's tough. I do think that it's easier for someone with an outside perspective to be like, "Hey, this test is costing more than the value that it's providing." But yeah, I can see why people might have a little bit of pushback
JOËL: Sometimes, the value of a test is also in the journey rather than the destination.
STEPHANIE: Yeah, that's a good point.
JOËL: So if you're practicing TDD, maybe you use some tests to help you drive out some functionality, help you come up with a design that you want to do. But maybe once you've actually created the design, the test that helped you get there is not actually that useful. I've heard some people will do this by writing a lot of more system tests-like tests that are very integration-heavy, that have a lot of edge cases that you might not care to test at that level, at that granularity. And so they use those to help drive a little bit of the implementation and then remove them because they're not providing that much value relative to their cost anymore.
STEPHANIE: I think that's a really good point. The tests that you write for implementation can have value to you as a developer, but that's different from those tests having value to the business when you commit them to a codebase and incorporate them as part of CI and a CI that everyone else has to run as well. So yeah, I think in that case, the context definitely matters. And hopefully, you can feel good about the value that it provided but then also have that eye towards, okay, what about the business, and what values does the business have?
JOËL: Yeah, and accept that the test did the job that it was supposed to do. It got you to where you needed to be, and it completed its purpose. And now it's ready to move on.
STEPHANIE: Another thing that I recently read about deleting code...and this was from Chelsea Troy. She advocates for regularly evaluating features in an app and deciding whether they're providing enough value to justify keeping around and maintaining for developers as well. And I thought that was really interesting because I don't know if that's something that I'd really considered before that sometimes an app might outgrow some features, or they might not be worth keeping around because of the problems or the maintenance costs that they carry into the future.
JOËL: That's fascinating because I think you're taking the same analysis we were talking about tests and then kind of like bringing it up now to the product level. Because now, we're not just talking about deleting code; we're talking about deleting functionality that a product might have.
STEPHANIE: I think the challenge there is that the effects of the carrying cost of a feature is not necessarily felt by the business stakeholders, or product folks, or people operating at a higher level, but it is felt by developers. If there's a bug that's come up from this old feature, and oh, I have never seen this feature before, and now I have to spend a day learning about what this thing is before I can fix the bug. It did feel like a radical idea that maybe developers can play a part in advocating for some features to be retired, that is, you know, maybe separate from how products thinks about those things.
JOËL: I think in order to be able to make those decisions or really just to be part of those conversations, the dev side needs to be really integrated with the product team and with larger business objectives. And so then you can say, look, if we take a week of one developer's time to provide the support this feature needs and we have one customer paying $20 a month for it, that's not a good business prospect.
Now, is this strategically an area that we're trying to grow? And so yeah, we're doing it for one customer, but we're hoping to get 100 by the end of the year, and then it will be worth it. Then yes, maybe we keep that feature around. If this is the thing, like, we experimented for a few weeks five years ago, and then it's just kind of hang around as a legacy thing that this one person knows about and uses, then maybe it's worth saying, look, this has a high business cost. It might be worth sunsetting that feature. But it's a conversation that everybody needs to be involved in.
STEPHANIE: Yeah, yeah. I like the idea of it being something more proactive versus, I don't know, something that I think I've seen at other orgs and just in general as a person who uses digital products, like, a feature or a product, just kind of dying. And probably the organization just wasn't able to find a team to continue to support it, and it just kind of kept being this burden. And then, eventually, it just was something that they had to let go. But then, at that point, you had already spent all of that time, and effort, and energy into figuring out what to do with this thing.
Whereas the approach that Chelsea is advocating for is more realistic, I think, about the fate of [laughs] software products and features. And as a developer, I would get that feeling of deleting [laughs] code that is so satisfying. And I'm just not burdened by having to deal with something that is not providing value, like cumbersome tests. [laughs]
JOËL: I think it's always the fundamental thing that you have to go back to when you're talking about deleting code, or features, or anything is that sort of cost-benefit analysis. Does this thing provide us any value? And if so, does that value outweigh the cost of the work we need to do to maintain it? And in the case of dead code, well, it's probably providing zero value, but it's imposing a cost, and so we want to remove it.
In the case of a test that is not muted or pending, then maybe it does provide some value. But if it's really brittle and constantly breaking, and it's costing us many hours of fixing time, then maybe it's not. If we can't find a way to fix it and make it more valuable because sometimes it's the other option, then it might be worth considering deleting it. Have you ever, on a codebase, taken some time to actually seek out code that could be deleted as opposed to just sort of stumbling onto it yourself?
STEPHANIE: That's a good question. I think I have not just explored a codebase just looking for stuff to delete, but I have...maybe if you had something under a feature flag and you no longer needed the flag because it was released to everyone, you know, going back to delete it because you specifically made a ticket to make sure that you went back and cleaned that up. I do really appreciate the tracking of that work in that way and just making sure you're like, hey, I want to avoid a situation where this becomes dead code. And even just making a card for it is putting that intention out there. And hopefully, someone, if not yourself, we'll take that on because it's important.
JOËL: Yeah, kind of proactively trying to make sure that the work that you've done doesn't become dead code, that it gets pruned at the appropriate moment.
STEPHANIE: What about you? I'm curious from your perspective as an individual contributor when you are just moving through a codebase, and you see something suspiciously [laughs] looking like dead code what you do with it.
JOËL: I often like to split out a small PR just to remove that if it's not too much work and it's semi-related to what I'm doing. I'd like to give a shout-out to two tools that can help detect or confirm that something is dead code. One is Unused, written by former thoughtboter Josh Clayton.
It uses, I think, Ctags under the hood to track all the tokens in an app and then tries to determine are there tokens that are orphaned, that are isolated, and are not used? And it can then build you a report. And that can be good if you're doing a code audit of a codebase or if you're looking to confirm that a piece of code that you're working on might not be, like, is it actually used or not?
Another one is elm-review-unused, which is a plugin for elm-review which is Elm's linter, kind of like RuboCop. And what's really nice there is because it reads the AST, and Elm functions don't have side effects. You know that if something is not reachable from the main function that, it is completely safe to remove. You've run the script, and it will delete a bunch of functions for you that are unused, and it's 100% safe.
And it is very thorough. It finds all of the dead code and just removes it. It's practically just a...it's not a button because it's a script that you run but that you can automate to run on commit or whatever on the CI. But yeah, that's an amazing experience to just have it auto clean-up for you all the time.
STEPHANIE: That's really cool. I like that a lot. I think that would be really nice to incorporate into your development workflow, like you said, that it's part of the linting system and just keeping things tidy.
JOËL: Yeah, I think it's a little bit harder to have something that's quite as thorough for a Ruby or Rails app just because it's so dynamic, and we've got all this metaprogramming. But yeah, maybe this would be a thing where you would want to run something like Unused or some other linting tool every now and then to just check; hey, do we have any dead code that can be removed?
STEPHANIE: Yeah, absolutely. And I think this is totally a little bit different because we're just talking about tools, but I'm also thinking of red flags on a team level where I have definitely asked in a Slack channel, "Hey, I've never seen this feature before. What does it do?" and just crickets. [laughs] And even the product folks that I'm working with, they're like, "I don't know. It predates me," that being a bit of a smell, [laughs] if you will, to reevaluate some of those things. And those flags can exist on many different levels.
JOËL: That's always terrifying because you're like 80% sure that this is dead code, but there's like a 20% chance that this powers the core of the app, but nobody's touched it in 10 years.
STEPHANIE: Yeah, it is very scary. [laughs]
JOËL: Hopefully, your test suite is good enough that if you comment out that function and then you run your test suite, that it just all goes red, and you know that that's actually needed for something.
STEPHANIE: Yeah, though I think sometimes you might remove a piece of dead code, and there are some issues afterwards, and you find out, and you just revert it, and it's fine. At the end of the day, there are a lot of safeguards in place, and we've all done it. And so I think normalizing it is also very important in that it's okay if sometimes you make a mistake there.
JOËL: Stephanie is giving you permission to go and delete that code today. Ship it to production, and if something breaks, it's okay.
STEPHANIE: [laughs]
JOËL: You can revert it. Hopefully, your company is set up where reverting commits from production is a cheap and easy thing to do, and life goes on. So I'm curious, Stephanie, have you ever gone into GitHub and checked your stats on a project to see if you're more red than green or what that ratio is for you on a given project?
STEPHANIE: I have. Actually, someone else did on my behalf because I was posting a lot in that Dead Code Society Slack channel. And they then shared a screenshot of my overall contributions to a repo, and it was more red than green. I felt pretty good about myself. [laughs]
JOËL: All right. Net negative but in a positive kind of way.
STEPHANIE: In a positive way. [laughter]
JOËL: On that note, shall we wrap up?
STEPHANIE: Let's wrap up. [laughs] Show notes for this episode can be found at bikeshed.fm.
JOËL: This show has been produced and edited by Mandy Moore.
STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show.
JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter.
STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email.
JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week.
ALL: Byeeeeeeee!!!!!!!
ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.
Sponsored By:
- Airbrake: Deploy fearlessly and fix bugs faster with Airbrake Error & Performance Monitoring. Airbrake notifiers are available for all major programming languages and frameworks, and install in minutes, with an open-source SDK-based install and near-zero technical debt. Spend less time tracking down bugs and more time developing. Visit Frictionless error monitoring and performance insight for your app stack.