CoRecursive: Coding Stories - Chat: Loving Legacy Code with Jonathan Boccara
Episode Date: April 3, 2020Legacy code is everywhere. I don't think I've met anyone who doesn't have to deal with legacy code in the substantial portion of his work. Our guest, Jonathan Boccara is a French C++ developer and the... author of The Legacy Code Programmer's Toolbox. In this episode, Jonathan will help us understand and build the correct mindset to effectively work with legacy code by using his approach and processes. "An important message I'm trying to get across is that you should not complain if you don't, in turn, intend to improve the code." - Jonathan Boccara "That would be any critique that's technical. One thing that comes up very often is levels of obstruction. If I had to sum up best practices in, in three words, that would be those levels of obstruction." - Jonathan Boccara "The point of code is to make a piece of software run and to make it run in a way that will make customers happy. " - Jonathan Boccara Episode Page Episode Transcript Links: Fluent C++ SE Radio: Understanding Legacy Code Counting words in your code
Transcript
Discussion (0)
So I get to talk with quite a few people, and what I learned from that is that legacy code is everywhere.
I don't think I've met anyone who doesn't have to deal with legacy code in a substantial portion of his work, at least.
Hello, and welcome to Code Recursive. I'm Adam.
I'm Don. That was Jonathan Bocara.
He's a French C++ developer, and he's on a mission to teach people
how to work more effectively with legacy code,
so much so that he's written a book all about it.
I hope this book will change how people will see their everyday life
with working with existing code.
To write the book, Jonathan needed to define what legacy code was.
It's essentially existing code that's hard to work with.
I had to come up with a more precise definition.
So my definition would be threefold.
First, it's code that's hard to understand for you.
Second, it's code that you're not comfortable changing.
And three, it's code that you're somehow concerned with.
So today, we want to answer this question. How do you get good at working with large
existing codebases? How do you work with legacy code, basically?
And how do you enjoy working with legacy codebases?
We're going to talk about what legacy code is, how to work with it, how to improve it,
when you shouldn't improve it. And as you said, you know,
why you should want to, you know, be comfortable working with it, enjoy working with it.
Yeah, legacy code is after all just code and reading code and understanding it is,
is what our job is all about.
Yeah, there's this quote from Joel Spolsky about legacy code. The reason that developers think
that old code is a mess is because of a cardinal fundamental law of programming. It's harder to read code than it is to write it. Nobody
talks about that, right? It's totally true. Like writing code is easier than reading it.
That's weird, right? Like it's the opposite of what you would expect.
It's very counterintuitive.
Yeah. So today we're going to explain how to live with and love the legacy code
that you have to work with, and how to think about code you're not familiar with in general,
how to get comfortable with it. And to do that, I took my various questions about legacy code to
Jonathan. Yeah, his process is to accept the code, critique it, own it, document it, and improve it.
And we're going to take you through all the stages. Let's start at the beginning.
I've been a software developer for a couple
of years now, like eight years.
I noticed that people
around me, like the people I
met, like at Meetup or on the internet
or wherever, they were
sad about the
code they were working with. And I think
it's a terrible thing because most
of us, we choose our
job out of passion you know quite a few developers have been programming before they were actually
working as a developer and it really saddens me when i see people's motivational weather
over time because it's not what they were expecting and they don't really know what to do with it.
And they feel like they're a victim of code
and they feel like they ended up in the worst place on earth.
When you think about it, when you get into a new job,
like if it's like your first job or something,
you're probably going to get into an existing project.
And perhaps this project or company has been there for years and and some
other people have worked on it perhaps quite a lot of other people and so on your first day you're
going to be thrown into that huge sea of code written by perhaps dozens or more of people over years so you have to be able to work with
that somehow when you enter a company chances are you're going to have to face some code that's not
as easy to work with as as you would wish it were so yeah that's a an essential thing because you
that's what's out there and you have to do something with it. So I would call this acceptance.
Accept that as a professional, you need to deal with old, possibly crappy code.
Yeah. Google has tons of old C++ code. Facebook has tons of old PHP code. Somebody's maintaining
old versions of Windows. And just being old or not being in your favorite language doesn't mean
that it's not valuable code. I feel like this is honestly the hardest part, accepting old crappy code and having to work with it.
Definitely agree.
All right, next up in Jonathan's steps is critiquing.
When you look at a piece of code that you have written a while ago or that someone else has written, something that's not fresh for you,
it happens that it doesn't look quite right to you.
Like, it feels like it's badly written.
And when you see that, you have two choices, I think.
One of them is saying, this is bad code, and move on.
And the second choice is to try to express why this is bad code and move on and the second choice is to try to express why this is bad code
because it happens that you know this this this piece of code is not well designed but you can't
quite place your finger about on what exactly is wrong with it and sometimes it takes a bit of time
of reflection and analysis to exactly pinpoint what's wrong with that piece of code.
And being able to critique this code in depth, being able to voice exactly in excruciating details why you didn't like it,
once you find that, when you identify what's wrong with it you can you know what to pay
attention to you know that that specific aspect of design you know it's important because it made
you feel uncomfortable in the first place and next time you're going to write your own code then you
know need to pay attention to that by doing this kind of, you get better as a programmer.
I often compare that with a vaccine, where you get short of a disease, but that's not dangerous, and your body has time to do its stuff with the immune system, with antibodies or whatever,
and then your body remembers it.
It remembers exactly what's wrong with that molecule or whatever.
If you happen to actually encounter
the actual disease,
then your body is going to recognize it
and smash it apart in no time.
I really like this metaphor.
Don't just say,
oh, this code is horrible.
Understand why it is bad.
Yeah, if you want to be a great developer,
you should actually work on some legacy code.
There is one caveat with this critiquing approach, though.
Yeah, I was going to say,
it's also a dangerous thing to do,
to critique or rather to criticize code.
As a natural reaction,
people don't like existing code
that they feel is badly designed.
And sometimes it's badly designed,
sometimes it's not badly designed, and it's badly designed sometimes it's not badly designed and
it's more difficult than it looks but it's not really the point an important message i'm trying
to get across is that you should not complain if you don't intend to improve the code so you
don't criticize just for the sake of it because it's a natural thing to do. And if you start by saying,
oh, this code is terrible,
oh, I would have done such a better job,
and you do that all day,
then you're going to get depressed
and you're going to depress everyone who sits around you.
So I think you need to be careful
to criticize only for learning purposes
or improving the code.
That's kind of the tricky part. It's
really easy to complain about code that you have to work with. Like it just comes naturally, right?
When you see some code, you're like, this is a mess. And it can actually be hurtful
because the person who wrote it might be sitting nearby. And also like you don't understand the
original constraints. Like maybe this code made sense at some point.
Maybe it still does.
And it's just so complicated that you don't know how it's supposed to work.
I think that what Jonathan is trying to say is if you can try and move past that and maybe accept it, then you can better yourself.
If you have to work with code, be it good, be it bad,
be it the one you wrote or be it the one that someone else wrote,
think about it as your code.
If you're working on it,
this is your code.
You have to take ownership.
And even if you don't think it's good,
even if you didn't write it yourself,
this is your code.
And when you get into
that mindset you have the position as a leader you feel empowered to do things with this code
because this is your code so it doesn't matter that it's bad you have to make the most of it
and you when you take the ownership over the code you're working on you leave this victim attitude
fooling that that's one one thing that's particularly frustrating with legacy code
it's when you feel like you're bearing the consequences of someone who made a poor design
in the past and it's it's not true you know because well in the first place maybe that
person didn't make a poor design maybe just not seeing the big picture and maybe even even in the same situation you wouldn't wouldn't
have them such a bad job this is such a great attitude like i've been you know accidentally
on the receiving end of like what what moron wrote this code um and it's not fun yeah i mean like
ownership is a great attitude and also i think what you're talking about is empathy.
Like, have some empathy for the person that wrote it.
Okay, so far, we have accepted our code.
We've learned how to critique our code and take ownership over the code.
And don't be a dick.
You mean develop empathy, maybe?
Yes, and develop empathy and don't be a dick.
All right, before we leave critiquing,
Jonathan has a rule for what type of code critiques he considers valid. In three words, that would be those levels of abstraction. That's something that's sometimes not respected,
and that makes the code look bad and complicated.
Do you have an example of that?
Yeah, well, you have to choose a name of a parameter or anything else, really.
But let's stick to the parameters example.
That's a tricky thing to do.
Naming is a difficult thing to get right in programming, surprisingly.
I think that to get the right name, you have to choose the name that's at the right level of abstraction.
And to do that in practice, you have to think about what this object you're trying to name represents.
It may sound a bit trivial, but this question, what is this object
representing, I think it's the crux of how to do good naming.
For example, the parameter. If you name
your parameter with a name that reflects
how it participates to the inside of the function,
then you're too low in terms of levels of abstraction
because the parameter represents something
that's at the same level as the name of the function.
If it looks like something that's logical to implement a function,
then it's too low.
And on the other hand,
if you're too high in terms of level of abstraction for a parameter
that would be that your parameter is bound to uh the context that uses that function
does this make sense i think i think i understand if i have some function that is called, let's say, format email, and it takes in
a string and it goes through and it removes any like double line breaks, right? And I call it that
because I use it to format my email. So that is kind of a violation of this levels, right? Because
it doesn't actually format an email. I'm giving it too specific of a name, but it's actually
should be called something like remove extra line of a name. What it actually should be called is something like
remove extra line breaks.
Exactly.
And your parameter shouldn't be called email,
but should be called text, for example.
That's a great example because it shows immediately.
If you're keeping track, we have now covered accepting, critiquing.
And also, you know, using that critique to improve your code
and speaking of fixing the code should i just fix these right away when i find them oh no
absolutely no i don't think so the thing is it would be great in theory if you could fix the
world that would be awesome but the thing is legacy code bays tend to be vast like one thing that
makes codes go into legacy codes is age you know like if you have old code it has
more chances to be legacy than like brand new code you just ship but i'm sure that all the code is not equal. And that really shows at any
scale, even if you look at the function, you're going to see that all lines don't matter.
There are just a handful of lines that really contain some meaningful action. And I think that's true for larger scales, like a code base.
There are some places where you go everywhere, all the time.
Everyone goes there all the time.
That's the places that are hot, if I may say, in terms of cash vocabulary.
It's the places that people change.
They make fixes because they're bugs
or because they're interesting
and the clients want more features in them.
And those paths,
they represent a portion of your code base.
And this is the portion that matter.
The point of code is to make a piece of software run
and to make it run in a way
that will make customers happy.
And that's a very harsh business view but i think that's what code is for in i mean in a professional context of course so making code goods has to somehow improve your business so if you make code better it can be because better code tends to have less bugs right or
because it's easier to add features to better code than it is to code that you can't make any sense
of like for example you shouldn't do a refactoring project just because it's easy to do or just because it doesn't cost a lot like i hear people
sometimes say oh i'm gonna go in that code and and improve i don't know like the names or make
the code cleaner and and that's an easy thing to do and if no one goes through that code that
doesn't matter it's it's it's it's the same thing as fixing some other company code you know
that won't make you better that won't i won't make your business better you're saying the cost is low
but the value is is zero absolutely that's exactly my point um now i'm not saying that naming is
about thing naming is tremendously important but that matters more in code that matters. So my biggest concern is not what
Jonathan just described, like fixing code that doesn't need to be fixed. It's actually just
making code worse by trying to improve it. So I asked Jonathan how to deal with that situation.
I think you can do the same kind of analysis. Like when did choose to to fix a piece of code like to improve its quality by making a refactoring task after it i think it's a great thing not to move on
immediately but rather to think about why it's better and once again once again it's not something
that's obvious to do sometimes like for example i remember one time where we had a slightly complicated if statement,
like something that was an if involving several billions and a bit of nesting,
you know, nothing monstrous, but, you know,
the thing that takes you a few minutes to figure out.
And we were thinking, well, this if we see it often,
maybe we should do something about it.
So we went about and ref refactored it and we
moved it around and somehow it was looking much better much easier to understand and then we
stopped and thought why is that why is it better you know it looks better i feel i can understand
it better and that's the point of code really but why is that and after after a few i don't know
like minutes perhaps or perhaps even more i don't remember maybe an hour of analysis or perhaps like
when you think about when you sleep on it really we realized it was better because it was sticking
to the specification like the business had explained us if such and such condition are met within this
context and without this other then we should do that thing you know and and after the refactoring
our if statement was looking exactly like that and surprisingly it was more nested
by nested i mean when there is an if statement
inside of an if statement,
and you can measure nesting with the indentation,
which is the distance from the left margin of your screen.
And there's this general guideline about if statement
that's a classical thing in programming,
which is avoid nesting.
Like refactor your if statement so that they are as little nested as possible if it can be not listed
at all and in this particular case the the if statement became more nested but clearer and that
was because it it stuck better to the specification so we came up with that guideline that we try to
use every time we have to do
something that's related to conditional try to stick to the specification to what the business
say more than about nesting i like this example uh the structural indenting so following the rule
very clearly um about reducing indent actually would lead you to a solution that
was less good than what you ended up with.
Exactly.
The rules,
it's not,
it's not totally rule based,
but you should be able to explain it somehow.
Yeah,
absolutely.
You have to know the rules.
Like you have to know that nesting is something that can be dangerous.
That's a smell,
but performing your analysis on your codes
allows you to go further,
expand beyond the rules.
And that's like, you know,
another level of skills.
Learn the rules for improving code,
but learn the exceptions.
All right, we have hit accept it,
critique it and improve it.
And there is one more key left to legacy code.
And this one, I have to admit, is not my favorite. That is documentation. To Jonathan,
the magic of documentation is... You can create understanding out of nowhere
with documentation. That's a very surprising thing to know, to because it's it sounds like magic but the very facts of
explaining what you already understood helps you understand more you you probably know that if you
have made a talk or written a blog post or written a book or written actually a piece of documentation
if you explain anything to anyone in any form,
and I'm sure every listener did at some point,
you know that this made you realize things.
And if anything else, it helped you realize that there were things you didn't know.
There were holes in your understanding,
and that gives you more questions to answer to make a consistent hole so that's just one aspect of how documenting helps understanding now that's a great example because you you're saying that
the the actual act of explaining it to somebody via documentation actually deepens your understanding.
It's a way for you to understand it better.
Yeah.
And of course, it goes without saying that it helps the other people
that are going to read your documentation.
Now, I think when you're a software developer,
doing documentation is not hype.
That's not the thing that motivates people
becoming developers, or at least most people I've met.
That's why I think it's important to realize
how important it is,
and that it's not a terrible thing to do.
And one way to see things that I've realized over time
by actually managing people and making them write documentation
is documentation, just like improving good quality,
you don't do it because it's a good thing.
You don't do it because it's a good thing. You don't do it because you're a good person.
You do it because it helps the business.
And knowing that, you're going to quit this horrible,
this horrible for everyone attitude where you write documentation
like we do homework.
You know, like my manager asked me to
do that i don't have a choice i'm going to crank it out and and be done with it and that's the
worst documentation you can make for you for everyone for you because it's going to be a pain
and for everyone because it shows really when you read a piece of documentation that's been
written at someone that didn't want to write it, that just, just cranked it out.
It shows,
and you don't really understand that it's not helpful.
And,
and if it's not helpful,
then you wasted your time.
Yeah.
That's a great attitude.
Yeah.
So one simple tip I was going to say,
when you write documentation is to write it,
not because you have to, because you've been asked to,
or because you feel guilty not to,
but write it to explain something you had a hard time understanding,
explain it to your past self.
Because you know how it feels not to understand that thing.
You know what's easier to understand.
You know what's like the tricky part.
And understand it like you are speaking, yeah, to your past self.
Because other people are like your past self.
They don't know about it.
And actually, your future self has a high chance to be like your past self
at some point regarding this particular topic in other words document things because you're going
to forget them and you're going to need to explain to your future self when you come back to this
code inevitably what it does yeah you're going to be the person reading this documentation so
you don't write it you're just hurting yourself So we understand now how to work with legacy code. We have accept
it, critique it, critique it nicely, improve it, but don't make it worse, and document it.
There's one item from the beginning we haven't covered though, and that's how to enjoy working
with existing code bases. The key to loving maintenance programming
is understanding how valuable of a skill you're developing.
Get good at it, master it, enjoy it.
Or as Jonathan says,
it's a fascinating thing to be programming.
We love that.
But more importantly, yeah,
it empowers you to do great things
and you can do fantastic things with legacy code.
You can find out more
about jonathan and his book at co-recursive.com this interview with jonathan originally aired on
se radio uh software engineering radio it's a great podcast i'm one of the hosts let us know
what you think of this show i'm adam gordon bell i am don mckay until next time thank you for
listening do you have to do something special on a mac then just tap okay
other way oh it's inverted why is everything backwards with with macintosh