Today we’re talking about the Zombies of the developer’s world — dead code and how to get rid of it once and for all. What happens to dead code is that it dies and then rises again to wreak havoc on your codebase! In this episode, we get into why you should attack your dead code with a vengeance and talk about the tools you need to find the Zombie code living in your codebase. There is a real temptation to keep stale code: What if I need it in the future? Will I offend the developer? What if I delete the wrong thing? The truth is, it gets easier the more you practice, so be relentless in chopping down the dead ends: you will save yourself and future developers a lot of headaches. And if you want to be proactive, do not write code that you are not going to use. Take the YAGNI approach and only write what you absolutely need. Tuning in to this episode, you will also learn how to identify dead code when you can no longer view your work objectively and hear about the difference between static and dynamic analysis and other ways to track down this culprit.
Key Points From This Episode:
- A quick definition of dead code and how you may be hosting it unknowingly.
- How dead code adds unnecessary complexity to understanding a codebase.
- The first step to banish dead code: follow the YAGNI principle and only write what you need.
- Why some might be hesitant to delete dead code and refactor or restructure for simplification.
- A creative idea for incentivizing engineers to delete dead code.
- The accumulation of dead library code when using only one feature of an entire library.
- Learn how to identify dead code when you can no longer view your code objectively.
- Distinguishing between static and dynamic analysis.
- Using in-depth analysis tools and/or your IDE to identify dead code.
- A solid argument against keeping dead code in case you need it later.
Transcript for Episode 148. Managing and Deleting Your Dead Code
[0:00:01.9] MN: Hello and welcome to The Rabbit Hole, the definitive developer’s podcast in fantabulous Chelsea, Manhattan. I’m your host, Michael Nunez. Our co-host today.
[0:00:09.8] DA: Dave Anderson.
[0:00:10.8] MN: Our producer.
[0:00:12.0] WJ: William Jeffries.
[0:00:12.0] MN: Today, we’ll be talking about managing and deleting your dead code. Once and for all.
[0:00:17.6] DA: It’s coming to get you.
[0:00:19.1] MN: Yeah.
[0:00:20.0] DA: Zombies.
[0:00:21.2] MN: The zombies.
[0:00:21.8] WJ: It’s alive.
[0:00:22.8] MN: Yeah, they rise up, they die and they rise up and they wreak havoc on your code base. We’ll talk about some reasons why you should attack your dead code with a vengeance and some tools that you can use to find the dead code that is living in your code base to get rid of it.
[0:00:41.4] WJ: What is dead code?
[0:00:43.0] DA: Right, what is dead code?
[0:00:44.6] MN: Dead code is pretty much a deprecated code that could exist in your code base and you realize you’re not using it anymore, it could be a component and react that seems like no one’s fine use of it or particular function that no longer is relevant.
[0:01:00.3] WJ: Or maybe you don’t even know that it’s dead.
[0:01:02.9] MN: That’s the thing. But like, you, you don’t know that it’s dead but like, in essence, it is dead. This is not being used, that’s the problem.
[0:01:11.3] DA: You could look at it and be like, it’s a whole fully featured class and it’s like this looks very important.
[0:01:17.5] WJ: Yup, but it’s actually – hasn’t been used in years.
[0:01:21.0] DA: Yeah.
[0:01:21.9] WJ: It’s just like a perfectly preserved corpse, like a three year old cheese burger from McDonalds.
[0:01:27.8] MN: Pristine looking cheeseburger.
[0:01:31.1] DA: That is true, the code will not change much like a cheeseburger. Just stay there. Yeah, it’s just a memory of a different time, you know? But yeah, I don’t know, whenever I’m trying to understand a code base, I feel like sometimes you run into dead code and it adds a lot of complexity to understanding what’s going on whether it might be like features that were half baked.
Okay, we’re going to need this, we got to have this ability.
[0:02:06.6] WJ: Or you’ll be like, it totally calls out to that third party micro service but actually, there’s a class that wraps the third party micro service and then that class is never evoked.
[0:02:19.1] DA: Yeah, this is a killer feature, everybody’s going to want it and then nobody wanted it or there was something that was more important and then it never finished it.
[0:02:26.5] MN: Right. The first step of getting rid of dead code is to not write the code like YAGNI as you mentioned, right? This feature is supposed to have all these cool things, but we need to find out whether we’re actually going to need it or not. Because if not –
[0:02:40.7] DA: That’s true. Yeah, I mean, it could be that the piece of work that they were carving off of themselves wasn’t like a fully baked user value, it wasn’t a user story.
[0:02:54.8] MN: Right.
[0:02:55.6] DA: No one could use it and so it just sat there and it couldn’t be leveraged and nothing called it.
[0:03:04.5] MN: What if I really liked the code that I wrote and it’s not dead to me, I like it and I want it to exist in the code base forever?
[0:03:12.6] DA: Well that’s creepy. I mean, everybody’s using source control, right? Or using it.
[0:03:22.6] MN: Hopefully yes. We use Git.
[0:03:23.5] DA: For sure.
[0:03:25.6] MN: So we can then refer to it at a later time. Do a couple – what is it? Just go to Git log, no line or one line and see the particular work and then be able to see it from there.
[0:03:37.1] DA: Yeah. There’s some things that I could see like getting a little bit challenging with that, digging through the history to try and find what the file might have contained especially if you’re like refactoring a lot and like moving where stuff is. I feel like that could be a little bit of a whack a mole and that could be like why people might be a little afraid to like delete something.
But then by that extension, you’re probably also afraid to like make any drastic changes to your code at all like doing refactoring and restructuring things in a way that makes them easier to understand.
[0:04:16.0] MN: Yeah, because it could – I mean, having to go back to your source code to see that piece of code and then try to do the refactor can cause some confusion, especially if another person is trying to do this refactor of code that someone else throw without the context as to why they wrote it in the first place.
I imagine it will be really time consuming to go and fix some of that code so if the person responsible for writing that code had deleted it, then the next engineer – future engineers would thank you because then they would have never had to see that code in the first place. I think one thing that I’ve imagined is that if you have dead code and it was tested well but it’s not being used then you’re testing suite is spending a lot of time running this code that no one is using or that is deprecated and no longer needed anymore.
Your test week can actually just be a lot faster if you remove the implementation and those test associated to it.
[0:05:15.3] DA: It feels double good if you can delete both of those things then your PR gets like double negative.
[0:05:21.4] MN: It’s a ton of lines.
[0:05:22.0] DA: Lines.
[0:05:22.4] MN: Yeah, those PR’s feel so good when you guys got a ton of red deleted all these code, yes.
[0:05:29.6] DA: Really like a colleague of ours was working on a client with I would give away little tiny plastic dinosaurs for every thousand lines of code that was deleted?
[0:05:42.5] WJ: Yeah.
[0:05:44.1] DA: Maybe it was like something smaller. I want to say it’s a thousand months.
[0:05:47.0] WJ: Yeah, I think I took a lot.
[0:05:48.6] DA: Yeah, which I mean, you can do that, I could delete a thousand lines of code.
[0:05:54.0] WJ: I mean, I could delete a thousand lines of code, I don’t know if you want me to.
[0:05:58.3] MN: I’ll get it for the dinos.
[0:06:00.9] WJ: Which ones, does it matter?
[0:06:04.0] MN: Remove the no modules, does that count?
[0:06:07.5] WJ: That will get you a lot of dinosaurs.
[0:06:08.6] DA: Wow.
[0:06:09.8] MN: That’s like cheating though, you can’t get that no modules. Yeah, maybe incentivize actually deleting code in your team. I imagine is probably why they did it so that they ensure that the code that exist in the code base was code that was being used and every time you got a chance to chop it up then you are rewarded for that and I think that’s probably a really good incentive to allow your engineers to explore more efficient ways of building things so they could delete that code later on.
[0:06:43.5] DA: Yeah, I think yeah, if you delete code, then that’s less code you may need to compile.
If you actually delete it and then you deleted the package from your package at JSON then you would actually save a lot of lines of code.
[0:07:17.7] DA: I didn’t think about that but yeah, if you ever depend and it’s not used, that is dead code.
[0:07:22.7] WJ: Yeah, this is what makes branch shaking so beautiful is that even if you’re third party library is used, it’s probably only partially used so there’s probably dead library code.
[0:07:34.9] MN: Right. That stuff like, can get really massive really quick.
[0:07:39.6] WJ: Right, you bring in jQuery and then you use like one feature.
[0:07:44.1] MN: Lodash and then you just use map like – kind of wild. But lodash could be massive and like – well, massive in the sense that it’s much bigger than using map, it’s probably like 16 kilobytes or something crazy like that.
But if you just use the one function from that library then you don’t need to import the whole thing.
[0:08:02.8] WJ: Shake your branches.
[0:08:02.9] MN: Shake your branches, it’s good for you. Dave, you’ve mentioned before, you’ve often would read code and try to understand and analyze what some of the code is doing and may find dead code in the midst because you have fresh, brand new eyes to see the dead lurking around the code base.
[0:08:20.7] WJ: I see dead code.
[0:08:22.5] MN: What if you’ve been in the code base for six to eight months and suddenly you’re looking through the code base and may not see with the very same eyes you had six to eight months ago and you can’t see the dead, are there analysis that we can use to identify the code?
[0:08:39.9] WJ: I mean so you got static analysis and you got dynamic analysis.
[0:08:45.0] MN: So what is the difference between the two?
[0:08:46.3] WJ: So dynamic analysis is more thorough but more complicated. Static analysis is easy. You run a static analyzing tool on your code base, something like I think Go tools for Go is a static analysis tool. It is easier with compiled languages or a strongly typed languages because you can make more assumptions about what code is and is not being used and then you know like an editor plug in, you can highlight in your editor code that is never called.
Dynamic analysis is more complicated, you have to instrument the code itself and then run the code and see which lines get called. It is like if you use a test coverage tool and then it tells you which lines of code work all during your test except you put traffic on your codebase while it’s instrumented and then it tells you which lines of code are not being executed when it is actually running.
[0:09:43.4] DA: So that means it is going to actually somehow modify the code that is running so that it will have some extra instrumentation on it.
[0:09:51.8] WJ: Yeah, I’ve only ever looked into one instrumentor and the way that it worked was it depended a function call to the end of every line. So at the end of every line we just add like a semicolon and then this function call and that function call would tell it the line number for that particular line and then that generated a report like a map and then using some kind of visualizer tool like an editor plug in, you could show in the codebase or you could generate reports in HTML.
[0:10:26.3] MN: I see, so you could have it line by line tell you exactly what code is not even the cyclomatic dependency like in F statement, could you see which one is not being called ever?
[0:10:38.8] WJ: So if you are doing this in production. So like Scythe is a production dynamic analysis tool and then while your code is running in production the instrumentry is detecting which lines are getting called and which ones are not. So it could be that you have it and if else and the else is technically reachable but for whatever reason in production nobody ever reaches it in which case maybe you can delete it.
[0:11:05.2] DA: Like there is a really aggressive guard clause or something like that. I was looking at some code actually earlier today and the method signature said it could return an error, this is Go, I am looking at Go code and you have to return errors as if they were regular things, which is a different topic I guess but like the method signature said it could return the thing you want or it could return error but never returned an error. So every single place of this was called, which was many places we have to handle the error even though it never returned the error. So dead code.
[0:11:47.6] MN: Oh man get rid of it, chop it up, delete it. Out of here.
[0:11:53.7] DA: Yeah, besides more in depth like dynamic or Scythe analysis tools, using your IDE can be pretty helpful too for finding dead code if it has stack analysis in it working in like fine usages of a method and often it’s pretty good where you can see where the implementation is actually being called or where that class is getting in instantiated.
[0:12:21.2] WJ: Yeah and then you don’t have to worry about that extra performance overhead that comes with having static analysis done in production although I think there is a strong case to be made that it’s worth it.
[0:12:34.3] DA: Yeah totally. I mean if your code base is like out of control and you just need to figure it out like you just can’t wrap your head around it, it sounds like a good option.
[0:12:44.6] WJ: I mean I guess you could also put it in UIT or put it in another environment and then replay production traffic on that second environment.
[0:12:55.5] MN: Yeah because that way you could then see it in a safe place rather than having it in an actual production.
[0:13:00.6] WJ: Yeah that is a lot of work though.
[0:13:02.4] MN: Ain’t nobody got time for that. I think I mentioned before about a particular way of handling dead code is to YAGNI right like, “You ain’t going to need it so don’t write it unless you have to” but I recently ran into the language no code where no code is the code that you write and I think if you write no code then you never have dead code to support in the first place, which is really, really interesting stuff.
[0:13:33.8] DA: It’s like a Zen Buddhist attitude towards it.
[0:13:38.7] MN: Yeah exactly, there is no dead code if there is no code at all.
[0:13:42.6] DA: Yeah it’s like sort of like desire being the root of all suffering. It’s the code.
[0:13:48.9] WJ: Very wise.
[0:13:49.3] MN: You have the shaking emoji on that one but yeah, I mean dead code is definitely something that we all have to face at some point in time when we are handling code bases but we should definitely try and take them out as fast as possible before they get into production traffic and it’s crazy.
[0:14:08.9] DA: Yeah but you don’t need to use a chainsaw like if you just use some trimming shares and just clip off the dead twigs.
[0:14:17.2] MN: Like a bonsai tree, you get a small little scissor, you cut it out.
[0:14:22.0] DA: Yeah, like if you are working on something and you see that it’s not being used then be brave.
[0:14:28.4] WJ: But I don’t want to hurt the original developer’s feelings.
[0:14:32.5] MN: Hey, you got to let go of the code. Don’t be like me and have it forever. That’s not cool, I was joking.
[0:14:41.2] WJ: What if we need it later?
[0:14:43.3] MN: No, we’ll write it better that’s the way to do it. You will be much better than the time you first wrote that code. It will be a lot better, trust so delete it or at least keep it in a notepad somewhere else out the codebase. That’s the way to do it.
[0:15:00.7] DA: Yeah is it like that genius of code? Are you solving the most intense problems you have?
[0:15:06.5] WJ: You should frame it put it on the wall.
[0:15:08.7] DA: Right, print it off, just use a piece of paper, well aiding that by a living piece of paper, get a frame from Ikea, print it off, put it on the wall and then delete it from the codebase.
[0:15:20.9] MN: Yeah, do what you got to do but you get to get it off the codebase.
[0:15:24.3] WJ: You got to hire a Dutch master and have it done up in oil, oil painting.
[0:15:28.6] MN: There you go oil painting this guy arts.
[0:15:32.0] DA: That would be really tough.
[0:15:32.9] MN: That guy arts but you got to get rid of that code, future you will thank you, future engineers will look at the codebase will thank you, everybody will thank you.
[0:15:42.3] WJ: Actually you know it will probably be totally thankless. No one will even know.
[0:15:45.9] MN: You say nobody wouldn’t even know, exactly. So yeah on second thought nobody is going to know here it is, the future people will have less headaches because of you, so you should do it.
[0:15:55.9] WJ: You can thank you, you can thank yourself.
[0:15:58.1] MN: Yeah delete that back code and be like, “Yeah, I did that, uh” and then you know slam your laptop down and walk away.
[0:16:04.4] DA: Give yourself a pink dinosaur.
[0:16:06.0] MN: There you go, you buy all the dinosaurs and whatever you want to do, delete, you give yourself a dinosaur whatever it takes. Whatever it takes people, let get rid of that dead code once and for all.
[END OF INTERVIEW]
[0:16:17.9] 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: