Navigated to 301 - Bekki Freeman, Staff Software Engineer at Caribou and Co-Organizer of Rocky Mountain Ruby - Transcript

301 - Bekki Freeman, Staff Software Engineer at Caribou and Co-Organizer of Rocky Mountain Ruby

Episode Transcript

SPEAKER_00

Hey, it's Jason, host of the Code with Jason podcast.

You're a developer.

You like to listen to podcasts.

You're listening to one right now.

Maybe you like to read blogs and subscribe to email newsletters and stuff like that.

Keep in touch.

Um email newsletters are a really nice way to keep on top of what's going on in the programming world.

Um except they're actually not.

I don't know about you, but the last thing that I want to do after a long day of staring at the screen is sit there and stare at the screen some more.

That's why I started a different kind of newsletter.

It's a snail mail programming newsletter.

That's right.

I send an actual envelope in the mail containing a paper newsletter that you can hold in your hands.

You can read it on your living room couch, at your kitchen table, in your bed, or in someone else's bed.

And when they say, What are you doing in my bed?

You can say, I'm reading Jason's newsletter.

What does it look like?

You might wonder what you might find in this snail mail programming newsletter.

You can read about all kinds of programming topics like object-oriented programming, testing, DevOps, AI.

Most of it's pretty technology agnostic.

Um you can also read about other non-programming topics like philosophy, evolutionary theory, business, marketing, economics, psychology, music, cooking, history, geology, language, culture, robotics, and farming.

The name of the newsletter is Nonsense Monthly.

Here's what some of my readers are saying about it.

Helmut Kobler from Los Angeles says, Thanks much for sending the newsletter.

I got it about a week ago and read it on my sofa.

It was a totally different experience than reading it on my computer or iPad.

It felt more relaxed, more meaningful, something special and out of the ordinary.

I'm sure that's what you were going for.

So just wanted to let you know that you succeeded.

Looking forward to more.

Thank you for this.

Can't wait for the next one.

Dear listener, if you would like to get letters in the mail from yours truly every month, you can go sign up at nonsense monthly.com.

That's nonsensemonthly.com.

I'll say it one more time.

Nonsense Monthly dot com.

And now without further ado, here is today's episode.

SPEAKER_01

Thank you.

Um I'm a staff engineer at Caribou, and I co-organize Rocky Mountain Ruby with a few other volunteers.

Um, love Ruby on Rails, been working in Rails for about 10 years, 20 years in software, and I live just outside of Boulder, Colorado.

SPEAKER_00

All right.

And and Rocky Mountain Ruby, uh, we must have a mutual friend.

Um I imagine you must know Spike.

SPEAKER_01

Yes, he's my co-organizer, my partner in crime for Rocky Mountain Ruby.

Yes.

SPEAKER_00

Yeah, I've never been to that one, but I've heard really good things.

SPEAKER_01

Yeah, definitely come out sometime.

Um we have a lot of fun.

It it's a great conference because it's small and it you can make eye contact with every single person at the conference by the end of it.

Uh, and we put a lot of effort into making sure people can um can feel comfortable going and talking to strangers.

I know that's a really hard thing for a lot of us, and so we have a lot of opportunity to invite people to meet new friends.

SPEAKER_00

Yeah, what what what is like the size of it?

How many people typically?

SPEAKER_01

This this year we're looking at about 200.

Uh last year was closer to 125.

We build in a lot of time for breaks and we do have lightning talks.

And one of the fun things is a lot of people come and practice their their talks at Rocky Mountain Ruby before they go apply at the bigger conferences.

SPEAKER_00

Oh, yeah.

Yeah, uh that has happened with SinCity Ruby, the conference that I organize.

Um, like sometimes people will come speak at SinCity Ruby as their first talk that they've ever given, and then they'll go on to become uh big stars in the in the programming community.

Um yeah, one one other thing that I did at Sin City Ruby, speaking of like people meeting each other, um, we had this time that I called forced socialization, where each morning I would put people into random groups of like five or so and and give people some prompts, like say where you're from and where you work and stuff like that.

And people like had a love-hate relationship with the forced socialization because they're like, I was really uncomfortable, but it like forced me to meet some new people and stuff like that, and I'm really glad that we did it.

And it sounds like you have a similar like attitude, like facilitating an environment where it's easy for people to meet each other and be as comfortable.

Well, I say comfortable, even though I made people uncomfortable, but helping people meet each other.

SPEAKER_01

Yeah, I think that is a fine line to walk because people are adults and they have their level of comfort with being social, but it's nice to push people out of their comfort zone or at least create a a space where it's not awkward because there's something to talk about, or it's somehow curated, or it's actively encouraged.

So at the very worst case, you walk up to someone and say, Hey, I'm supposed to meet new people, so hi.

And then everyone can share in the awkwardness.

SPEAKER_00

Do you do anything specific at Rocky Mountain Ruby to like make people meet?

SPEAKER_01

The only thing we do is we have big breaks and we encourage everybody to go outside and enjoy the beautiful fall Colorado.

And then we talk about the Pac-Man rule at our opening uh opening talk, opening words.

And we say, everyone it must do the Pac-Man rule.

So when you're in a group talking, you must leave an open slice in your circle that invites a new person to come into that slice and join the conversation.

And so we we explain how to use the Pac-Man rule to be open to new people and then to you know, smile, make eye contact, and say, Hey, where are you from?

SPEAKER_00

Oh, that's a good idea.

Yeah, yeah.

Okay, so I'm I'm not doing Sin City Ruby anymore, but I'm not necessarily done with events in general.

Um, and I like this idea.

My interpretation of what you're saying is like establishing social norms for the conference.

Uh and you could even add things like a rule that like when somebody approaches you and says, Hey, I'm Dan, or whatever, you like that is like an encouraged behavior to like just walk up to people and say your name.

And then when somebody does that, you say your name back and you like ask them where they work or something like that, so that people know that they can go up to anybody, anybody at the whole conference, and it's like a rule for them to be nice to you or whatever in a specific way, and like that can like lubricate lubricate the gears and stuff a bit more.

SPEAKER_01

Right.

Exactly.

Yes, and I think saying it out loud and naming it, it helps.

And one of the volunteers, his joke is hey, I do programmer things.

Do you do programmer things?

And he makes it intentionally very cheesy.

And you know, you get people laughing, and then it's very easy to go from there.

SPEAKER_00

Yeah, well, I hope that someday I can make it out to Rocky Mountain Ruby.

Um, okay, so today we wanted to talk about maybe a number of things, um, long-running applications and maybe working on them and helping get them to a better place and stuff like that.

Maybe you had some specific things in mind.

SPEAKER_01

Yeah, I am passionate about legacy code, and I I don't know why, but I feel like as soon as you write software, it becomes legacy code.

So even the stuff I wrote yesterday is old because now today I have new ideas.

But if we're sitting around rewriting our application over and over again, we're not actually delivering business value.

And I know a lot of people who like writing software because of the beauty of the software itself.

And I love those people and I love having them on my teams.

I write software to solve problems in the real world.

And so I love being involved with software that has actually like generated revenue and created a business.

And when you are um focused on revenue, business, growing a business, you can't just rewrite your software every year or every six months, every time you realize you got something wrong in the abstraction.

And so then the trick becomes how do you adapt your software over time without it becoming bloated and slow and disjointed?

And I'm I'm not good at cleaning up after myself, like in the real world, but I feel like a lot of the code stuff um ends up being like that five-minute cleanup rule of like always do a five-minute cleanup every day, and then your life will feel more zen.

And it's probably the same with software.

But what I found in startups is we're going so fast, we can't follow that five-minute cleanup rule.

We're go, go, go, go, go.

And then nine months later, we're like, oh goodness, where are we?

You know, it's really hard to act actors to this application.

The modeling is wrong now, and it gets a little bit out of control.

And so then how do you get it back?

And that's what I really love.

SPEAKER_00

Yeah, wow.

There's so much there.

SPEAKER_01

So much there.

SPEAKER_00

Yeah, so maybe uh let's dig into this concept a little bit more of legacy software because it's a little bit of an ambiguous term.

It means different things to different people, although when we say like legacy code, everybody kind of imagines the same thing.

But like, what does that mean?

Because like old doesn't necessarily mean bad.

Like, we don't refer to Ruby on Rails as legacy code.

It's been around for 20 years, but it's not legacy code because it's like it's been kept uh in a good state, good state, I assume.

I'd you know, I'd I'm not familiar with the whole Rails code base, but nobody complains about like how creaky and fragile it is and stuff like that.

Um, but with commercial applications, like any any commercial application that you get into, like honestly, I have approximately never started a job at a new company and gotten into the code base and been like, wow, this is great.

It's usually like, wow, this is this is garbage, just like every other job I've ever worked at.

No offense, every company in the world, but the the code always sucks.

Um, and and so what is that that we're referring to when we're referring to legacy code?

I guess it's like design that's hard to work with or something like that.

SPEAKER_01

Yeah, there's a couple official definitions.

And Michael Feathers has a book called Working Effectively with Legacy Code.

And I love this book.

I did a lightning talk um uh intro to this book last year, and he defines it as code that is not under test, which is a very narrow definition, but I think that's fair because when when code's not under test, it's really hard to adapt it without breaking the existing behavior.

And so he says, and I subscribe to this opinion, that the first thing you have to do if you want to start wrangling your code base is make sure it's under test.

And I think a lot of people in the Ruby community are like, well, of course it's under test.

We do TDD and we're very disciplined.

And the I have not found that to be the reality in the startups I've worked at and in, like you said, in the real world, in in people's real code bases.

SPEAKER_00

That is so true.

Thank you for saying that.

Because people say so much, like in the Ruby community, we're really bigger, big believers in testing.

It's like, oh yeah, then where are all the tests?

Um it's just not reality.

Um I have always found Michael Feather's very brief definition of legacy code to be very interesting.

And I buy that definition, like it's a definition that is like useful, but uh it's it's maybe incomplete, right?

Yeah, yeah, and like you know, it it's a term legacy code, you can kind of define it however you want.

It's it's maybe dependent on for what purpose you are defining it.

Um, and if you as a consultant, like Michael Feathers has done, in my understanding, like you go into companies and you help them with their legacy code, then code without tests is a very uh useful way of defining legacy code.

Yeah.

Um I've I feel like there's also an element of like the code is painful to work with and stuff like that.

Yeah.

100%.

Yeah, I mentioned the difficult to work with design.

Um and and there's also maybe like uh you you mentioned or alluded to like concepts that are out of date and stuff like that.

Like there's an entity that used to be called a car, but now it really means vehicle, which could be car or truck or something like that.

And so now we're we're calling all these things cars that are actually trucks and stuff like that.

I've seen that in every single application I've ever worked on.

There's some fundamental entity which has a name that is no longer true.

SPEAKER_01

No longer true.

Oh, that is exactly right.

Um, I would say the last five applications I've worked in, we've found an entity where I'm like, what is that?

Oh, it's actually this thing, but it started as this other thing.

And that is such a natural progression.

And I always say your first abstraction is wrong.

And so when I when I'm like making a new application, I don't stress over the abstraction and I don't try to get everything abstracted out perfectly because I know it's gonna be wrong.

And I see that so much in code.

And when you have 20 engineers working on a five-year-old application, it's really hard to go back and make that right.

And so we just live with it.

And maybe there's a comment in there that says, this car is actually motorcycles, trucks, and RVs.

And it makes it so hard to pull a new engineer into that, into that code base.

The follow-on to that is just what dependencies are in there.

Maybe things that were dependent on each other at first really should have been collapsed into single models, or maybe they're no longer related, or maybe we actually have five join tables that really should just have a direct relationship with each other.

And so, in terms of the hard to work with, we have names that no longer are relevant.

We have dependencies that are potentially out of control or causing a lot of stress in the application because we thought we needed to separate these five tables, but really the fifth table and the first table need to be connected.

The other thing I find a lot is missing indexes.

I think when we first create our database table and our active record models, we're very conscious of what needs to be indexed.

But as the application grows, we start searching on things we didn't anticipate.

And so suddenly a column that didn't seem that exciting when we first made the model is like a core search field.

And okay, now we have many millions of records.

We need to go add an index.

Now you have to have a strategy behind adding that index in a safe way.

And if you don't have a mature organization and good processes, it's really scary to go back and add that index.

SPEAKER_00

Okay, I have a list of notes here because you're touching on so many things that strike a nerve for me.

Um, okay, so a few years ago, I realized that there were certain fundamental important questions in programming that I didn't have answers for.

Um and I'll share two of those with you.

Um, and and feel free to comment on these or not comment on these and just bounce it right back to me because if somebody had asked me these questions a few years ago, I would be like, I I don't know.

I I know the answer, but I can't articulate it, or something like that.

So I don't want to put you on the spot.

But here's the two questions.

Um, what is good code versus bad code?

And and the other one is what is abstraction.

SPEAKER_01

Okay.

What is good code and bad code?

It's that is a hard big question.

SPEAKER_00

And isn't it funny?

Because people talk about bad code so much, it's like, okay, what is bad code?

SPEAKER_01

I think it's just so broad.

And I look at software as a bit of an art.

And so good and bad is a hard question.

It's very subjective.

And if I wanted to be very academic about it, I would say good code is code that you can onboard a new team member into in a short amount of time.

And they can understand and hold the application in their head.

I would call that good code.

Um, I think there's a lot more to it, a lot more nuance.

But if I was trying to distill it into like, how do how do I work with my team and how do I bring new people into a project is like, can they understand it?

I don't know.

What do you think?

SPEAKER_00

Yeah.

Um so I have have been trying to boil down ideas like this into the smallest, most concise, most essential definition that I can.

Um and what I came up with for good code is that it's code that's easy to understand and change.

Now I had Dave Farley on the podcast a few episodes ago, and I asked him this question, and he immediately said, What's good code?

It's code that's easy to change.

And I'm like, huh.

I think it's code that's easy to understand and change.

And he said, Well, if it's easy to change, then it's easy to understand.

So I think it's just code that's easy to change.

And I'm like, okay.

So I think I changed my mind.

I I think now I agree with Dave Farley, and it just means code that's easy to change.

SPEAKER_01

Easy to change.

That's nice and succinct.

And I think that makes sense, especially in a business context, because that means you can add features quickly, and that means you can move fast as a startup business.

So I like that definition a lot.

And I think you're right that easy to change also means easy to understand.

So I get the collapsing of the definitions.

Speaking of abstraction, that abstracting easy to change means easy to understand.

Sometimes saying it explicitly is beneficial to everybody's understanding.

SPEAKER_00

Yeah.

Yeah, that's a good point.

And when we talk about any like um code design principle, um, it all points back to making it easier to change.

And I think that's a good way to evaluate principles because we have a lot of competing principles.

Like we could talk about duplication and how people have different views on duplication.

And it's like, well, does this make it easier to change or hard to change?

I feel like that's a nice objective um measure of any particular principle.

Um, but abstraction, that is a huge one, and that's a word that gets mentioned a lot, but I don't feel like there's a lot of consensus on what that means.

SPEAKER_01

Yeah.

The I'm not even going to try to define it in a strict way.

I'm going to talk about how it makes me feel, I guess.

So everything like in software is an abstraction.

We're trying to take a real world concept and put it into code.

That right there is an abstraction.

It's like a proxy.

And when I say your first abstraction is wrong, I think your car example is a great one because your business is narrowly focused on cars.

So obviously everything is a car.

And if you abstract everything into the concept of a car, you've like put yourself into a hole where now you have trouble adding in and extending that code to be a vehicles in general.

And a lot of times when I say code is over abstracted, what I'm specifically referring to in practice is I have to, in my Ruby mine IDE, I have to command click on like five different methods to get to where the action is.

And I know a lot of Rubyists who really love having one-line methods.

And sometimes that leads to over abstraction where I'm not even going to try to think of an example because I'll just stumble around.

But if I'm in my car model and I see a one-line method, I'm like, what does this method do?

Oh, it calls another class.

Okay.

Let's go to that class definition.

And I go to that class.

I find the one method.

Oh, that calls one line.

So we're still following our very like one-line abstraction principle.

And I have to go to that definition.

And finally, four clicks later, I find out what this method is really doing.

And I just like that.

And I get into so many arguments with people about this concept.

SPEAKER_00

Okay.

Yeah, yeah, yeah.

All right.

So what I've been trying to do over the last while, I've been writing this book, which at this point I think will never come out.

Um but it uh it it's called The Philosophy of Programming.

And my my objective with that is to take these like subjective to to try to take as much subjectivity out of software design as I can and hang everything up.

Global pursuits objective principles.

Um and and not just that, but like the the like meta aspects of it.

Like how do we judge uh software design principles so that it's not just my my feeling against your feeling, my opinion against your opinion, but like objectively say that this is better than this because of this, and it's hard to disagree.

Um crap, I had a response to what you said, but now I forgot what you were saying.

Oh, yeah, yeah.

Sorry, I do remember.

Yeah, you had the um the car example, and you were talking about abstraction and what I would call indirection, where you just have to make all these hops between the thing you first see and the thing that you're actually interested in.

Um so I'll share, if I can get it right, I'll share my definition of abstraction.

All right.

Um it's when we replace lower level details with higher level information um in order to better understand some part of the world.

Um and and I'll also say what I think abstraction is not.

Um an abstraction is not necessarily a generalization.

I think people conflate those two things a lot.

Um an abstraction can be more general than the thing that it abstracts, or it can be more specific.

Um it's it's not always more general.

I think the classic uh idea that people are thinking of is you have two things that are kind of similar, and then you collapse those into one so that you can have uh less duplication.

And so now you have this abstract thing, which is more abstract, it's less concrete.

Um, but now it's harder to understand because examples are easier to understand than abstract ideas, and so it's harder to understand this abstract idea than these concrete ideas that you had before.

But that's not necessarily how it has to go.

You can have something that is um so full of details, you know.

We've all had the experience of opening up a class and it's like 500 lines long and it's just all these details, and it's like, what's the higher level meaning of all this?

And so that's when you can put an abstraction over that and give meaning to all these details, and then if and only if you're interested in these details, then you can dig deeper and see those.

Um, but I've experienced that same thing that you described, where people take it in not a great direction, and so then instead of being helpful, instead of having this layer that gives meaning, what you've done is maybe in addition to giving giving meaning, you've made the details hard to get to.

And so now it's like, okay, great, this is easy to understand at a high level, but what I'm interested in how it actually works, uh that's that's hard to get to.

SPEAKER_01

Yeah.

I I think your definition is great, and it is interesting because the abstraction is supposed to hide the inner workings.

I've not found that to be super useful when debugging or troubleshooting.

Like you almost need to know the detail, but maybe it's helpful when designing or initially writing the code because it it kind of gives a almost like a blueprint rather than the full underlying detail.

But if I have to understand like three service classes, one data object, just to know what a model method is doing, I don't think that's serving my goal.

And maybe goal is where this abstraction concept needs to look.

Because my goal might be different from yours, where my goal is to understand why there's a bug over here or why this this method isn't behaving the way I expect it to.

Well, someone else's goal might be to hide the detail.

SPEAKER_00

Well, you know, uh code has to code has to do two jobs.

It has to serve its functional purpose and it has to do the job of being uh easy to to work with, easy to change.

Um and if you're trying to debug something and you're trying to look into how something works and the structure of the code makes it hard for you to tell how it works, then it's doing a bad job of that job of being easy to understand.

The word that I like to use regarding abstractions is appropriate.

We want it to be at the appropriate level of detail.

And to me, like if you have to dig down into all those other classes when you're trying to debug, then it's not at an appropriate level of detail, at least in that specific scenario.

And I think that like that's probably kind of universal.

Like the stuff you're doing, you're trying to do with the code, it's probably not that different from what anybody else is trying to do with the code.

And and so maybe the the level of abstraction that was chosen for that particular class is not appropriate.

SPEAKER_01

Yeah.

So then, okay, when you find something that's not appropriate, just speaking of long-running apps, so you have an abstraction that is no longer appropriate.

Do you have any good techniques for systematically and safely changing it to a more appropriate abstraction?

SPEAKER_00

Oh, yeah, that's a great question.

Um that okay.

Uh let me answer your question in a circuitous way.

Um okay, so I man, I'm talking about a lot of things that I talked about in the episode that was just released with uh Joel Drapper.

Um, but um we we talked in that episode about how neither myself nor Joel is a fan of the technical debt metaphor.

I have a different one that I prefer to use, which is like a shed full of saw blades metaphor.

Um and you can think of you can divide it up however you want, but you could say that each like class in your code base is a blade or something like that.

And some are sharper and some are duller.

Um a piece of code that's easy to change is analogous to a sharp blade.

If it's hard to change, it's dull.

So when I come across an abstraction that is not at an appropriate level and so it's hard to understand and change, I found a dull blade.

It's hard to cut with.

Um and what I always try to avoid doing is I don't want to just go and like randomly sharpen saws without any justification, with a without a justified belief that that saw is actually going to be used for cutting uh and and we'll get a return on that investment.

I I want every investment to be justified.

I don't expect every single investment to re to give a positive return, but I do want my investment portfolio to to give a good return as a whole.

And so to answer your question about like how how to go about doing that, um, the first thing is I want to obtain that reasonable justification that my investment in sharpening this blade is gonna pay back.

Um and if I am like materially harmed by the dullness of a certain blade, then that can be a sufficient justification, and I can say, okay, this I have a concrete justification here.

I'm gonna go and clean this up a little bit, and and there there's a few times there there's a few certain triggers.

Um one is like right after I make a change, and there there's a um there's a clear dull blade in there, I'll I'll go and do a follow-on change, or right before I make a change, I'll go and do that.

Um I guess it's kind of rare.

Like rarely will I like find some problem unrelated to an actual change I'm making and go try to improve that.

I I rarely do that because I think that's a little less justified.

SPEAKER_01

Yes.

SPEAKER_00

Yeah.

I I have more thoughts, but I think I'm losing my train of thought, so I'll just say that much for now.

SPEAKER_01

Yeah, I always try to make sure that the changes I'm making in the code base are part of a feature or a necessary improvement to the end product of the software.

I think that's a wise thing to do because otherwise you end up in the trap of just rewriting code for the sake of rewriting it.

And I don't like imagining future features.

And sometimes if you're in there and you think one of your blades is dull, but you don't know because you haven't used it in a while, uh, you might go in and actually change it in the wrong direction.

And if I I'm gonna try to stretch your metaphor really far, it's gonna get more dull instead of sharper inadvertently.

So I think it's important to always ground it in a business need or um a feature that needs to go into the product.

Sometimes I do try to undertake a refactor in advance if I know the feature is coming and I know we need to do some cleanup before, but you still have that new feature in mind and the needs of that new code in mind as you're doing the refactor.

Organizationally, I I struggle with how do we make sure we don't get stopped in the middle of that cleanup?

Because sometimes the business priorities change, and now you have a halfway done cleanup of the code and you have to move on.

And by the time you come back, you've forgotten or you know, the code has drifted in a different way than what was anticipated.

How do you keep your cleanups, your sh your blade sharpening small enough that you don't end up in a situation where you're halfway done and you have to move on to something else?

SPEAKER_00

I'm so glad that you brought that up.

Um, so my answer for that is no different from how I do anything else, which is that I work in small atomic uh units of work.

Because like at any time with any kind of work, you could get pulled off in some other direction whenever.

And so you don't want to get caught in the middle of this big project that's not uh releasable until it's all the way done, because a 90% done project that you can't deploy has zero value.

SPEAKER_01

Zero value, yes, negative value, even.

SPEAKER_00

Yeah, because you've spent all this investment building the thing and the opportunity cost of not doing something else, and now that's all just potentially down the drain.

You don't know if you're gonna be able to release it, and even if you do, you'll have to come back later and pay again the cost of like getting back into the context and remembering what it was and stuff like that.

So I try okay.

Uh when I have taught classes over the years, my students are consistently surprised by how frequently I commit.

Uh sometimes it's as frequently as like every few seconds.

Like I might make a one-line change and then do a commit.

And people are like, What why did you commit even though you made that like tiny change?

That's crazy.

But it's like, what is the cost of making a commit?

Like a commit is almost the cost is so negligible, you know?

Like it takes a little bit of expenditure of mental effort to come up with a commit message, maybe, but like it's such a small cost.

Um and and if you commit frequently like that, making each of your commits atomic, um, then you can give yourself a clean mental slate like every few minutes or seconds, and you can go ahead and forget about what you're working on.

You you don't have to keep as much in your mental RAM, you know.

Um I think there's huge value in being able to operate at like a lower RPM.

Um because if if I'm if if I'm okay, I'm I'm I'm drifting all over the place, but usually in a day I run out of brain power way before I run out of time.

Um so like I don't want to be operating at max RPM all day because then I'll like run out of juice at 1 p.m.

or whatever, and I won't be able to do anything else.

But if I can operate at a very low RPM, then maybe I can work all day and even have time to like talk to my family after work or something like that, and not just like sit on the couch.

Um so those are big reasons for working in those like small atomic um pieces of work, like at the commit level, and then it's nested.

Um, like I work in small commits and then I work on small features.

Like, okay, I'm not gonna try to refactor the world.

I'm gonna try to refactor like this one method or this one small class or something like that, and only do the bare minimum necessary uh that's justified by the the return on investment that I expect to get that's connected to the business need.

Um and then I deploy.

So like maybe I commit every few seconds or every few minutes, um, the whole refactor takes me like an hour or two, and then once uh immediately once I'm done with it, I'll deploy it to production.

And maybe it's a month-long refactoring project, but even if it's a month-long refactoring project, I'll do it in those tiny chunks of work deploying like every day.

SPEAKER_01

Yeah, and so are you starting at the lowest end of the dependency chain?

So, like the the if you have five models that are all dependent on each other, you're starting at the lowest one, slowly working your way up, and then eventually you get to the controller level at the end.

Is that kind of how you approach it?

SPEAKER_00

Good question.

So let me rephrase your question to see if I understand.

Um, if you think of code as like a tree, are you asking if I'm like starting at the leaf level?

SPEAKER_01

Yeah, or maybe the roots.

SPEAKER_00

Yeah, depending on yeah.

Um is

SPEAKER_01

Is the leaf the controller or right?

SPEAKER_00

Uh good question.

I'm not sure.

Cause like sometimes it's more like a um it it's a change that goes through all those different levels.

Like here's a refactor that I'm working on on a personal project of mine, if you even call it a refactor.

Um there's something that I call a repository that I used to call a project.

I'm trying to make it match GitHub's terminology, and I've unthinkingly called it a project, but then I realized that what I was calling a project is actually a GitHub repository, and GitHub has something else called a project, so it's really confusing if I call it a project.

Um, and this term is baked so deeply into the application.

So no.

Yeah.

So over the course of a long time, like like months and months, I've been chipping away at that and renaming instances of project to repository.

So most recently, it was like a couple of like links and routes and redirects and stuff like that that were still referring to project, and I stumbled across these.

You know, this is a great instance of what we were just talking about.

Um I've only been renaming uh project to repository in the instances where it causes me some pain.

So I ran into this.

There was like a bug specifically because it was redirecting to project and not repository.

I'm like, all right, I don't want to build further in this direction and like go deeper in this bad hole.

Um, so I'm gonna stop my work.

This is another thing.

I'm I'm gonna pause my feature work.

I'm not gonna mix the refactoring with the feature work, I'm gonna just like stash this and switch to this refactor and and rename project to repository.

And again, that that appears at all these different levels, leaves and branches and all that stuff.

And then I deploy that, and once that's done, okay, this like painful obstacle is now out of my way, and I can resume my feature work.

So the starting point is really, I guess, situation dependent.

SPEAKER_01

Yeah, and what you describe as working on a project that basically you're the only developer in it, it sounds like only developer, yeah.

Yes.

So it's moving at your pace, and that works fine for a big refactor like that.

But if you are on a big team or you you're in a monolith where, you know, I'll say 20 people, but it could be a thousand people are working in the same code base and the code is moving quite quickly, it's very it's a very different story to just say I'm going to go rename everything and I'm gonna take a couple months to do it in a very piecemeal, like calm way.

And that's where I struggle is combining the organizational complexity with having code that needs to be brought up to the modern naming or the modern abstraction that you're using.

SPEAKER_00

Yeah.

So I have a lot of thoughts on that, but I've been talking a lot.

Do you have thoughts on that?

SPEAKER_01

Oh, goodness.

I have thoughts.

I don't know that I've ever succeeded in fully doing something like this.

And at that, and the companies I've been at in the last, you know, seven years, um, our code base is full of half-done renamings.

And so now I feel like renamings are just a bad thing to try because they always get halfway done and then stop.

And it is so hard to do something in a big code base that that is that invasive without just breaking everything for everybody or or having it go stale.

And so I don't have a solid solution to propose.

Um, but I I struggle to even approve a project that involves renaming things, even if we know that cars should be vehicle or project should be repository, because it causes so much disruption.

And it either has to be done in one fell swoop, which is not the way we should do refactors, right?

Or everybody has to um pause working in that area of code for you know a couple weeks or a month while we do it safely.

SPEAKER_00

Yeah.

Okay, I'm so glad you bring this up.

Um, even though this is a personal project, it is a commercial project.

Um it's I've mentioned it on the show before, Saturn CI, it's a CI platform.

Um, and I recently got a couple new customers, and I am scrambling to get some certain things in place so that these customers can get onboarded and operational.

Um and I did this particular project repository rename uh during a I was working all weekend um to like scramble to get something ready.

So this was done under great time pressure.

Um and and I 100% agree with like you can't just do a big rename in one fell swoop for multiple reasons.

One being that's just really risky, um, and also like you said, you can't just like pause everything and do this rename because you still need to be shipping value.

Um so my approach with the rename that I'm doing is piece it out over a long period of time um and uh let each rename be driven by by actual um uh pain, you know.

Um and I also have kind of a rule, like you could call the rule don't make it worse.

Like, don't get even more deeply committed to going in the wrong direction.

So if I come across a thing that will force me to uh grow the problem and like build something on top of something that's called project, and now I have even more instances of project, I'll say like, okay, no, I'm not gonna do that.

Let's rename project to repository in this instance, so all this new stuff can say repository instead of project.

SPEAKER_01

Right.

Yeah, it's a good pragmatic approach, yeah.

SPEAKER_00

Yeah, and the hard thing is is discipline because there's just no way around just having to have the discipline to stay on that uh rename project long after it's fun and feels important and stuff like that.

You have to keep going for like months and maybe years.

SPEAKER_01

Yeah.

The yes, so many thoughts.

It's so hard when you have a team of people, and um, some of the people might be feeling the pain much more acutely than others, so then you have to convince everybody on the team that this pain is worth fixing.

And then yeah, wait, why I can't do that.

Why do you have to convince everybody?

Because people are the core of everything, and people are the core of a software team.

And if you have half the team silently, or maybe not so silently, grumbling about this uh refactor going on that is causing them trouble, it takes away a lot of the synergy that might need to be happening in a team.

And if if everybody doesn't agree that a thing is necessary, there will be resentments about the time and investment and the trouble that this big refactor is causing.

So I feel like a lot of these refactors need a lot of social engineering and a lot of time to really um convince people that they're worth doing.

Um, but it can get even broader than that, where if someone a little bit removed from the code, like a manager or an executive or even a product manager doesn't know the pain and you haven't adequately expressed why this time is necessary to spend, I think that you lose a lot of trust in the in the engineering organization.

And then that's when things get stopped halfway through or people aren't fully bought in, you won't get the investment needed to actually see this refactor through.

SPEAKER_00

Yeah.

Wow.

SPEAKER_01

That and that's where your solo project, I'm a little bit jealous that you get to just rename things in your solo project.

SPEAKER_00

Yeah, it's it's great.

Um, and this is like one of the big reasons I'm doing this is to like so I can turn this into my job and not have to work for anybody else, and then I can just do everything how I want.

Um, but dear listener, uh, what Becky just said, like, there's so much wisdom there.

Like please pay attention to that because that is such a big thing.

Like, all this technical stuff, like a prerequisite to getting to do any of these technical improvements is is being competent on the psychological side of things.

Absolutely.

And you know, the only reason I'm interested in any of this stuff is to like make things better globally.

Like, like if it's not better for the business, then it's not better, you know.

I don't do anything just for like the craft of it or something like that.

I'm I'm only interested in good software design precisely because good software design is good for the business.

SPEAKER_01

The business, yes.

SPEAKER_00

Yeah.

SPEAKER_01

You and I are in agreement on that.

SPEAKER_00

Yeah, and you know, when I asked why does the team need to be convinced or whatever, I think your answer was so spot on.

You have to like it's it's kind of a political thing where you have to like rally everybody behind this idea and cultivate support for it.

SPEAKER_01

Yes.

And that's one of the reasons I love the staff engineer role is I feel like a lot of my job is rallying the team and working with people and helping socialize new ideas or the the organizational maturity that we want to get to in order to produce that business value.

SPEAKER_00

Yeah, and it's important to uh rally people around that idea and cultivate support for it.

SPEAKER_01

Agreed.

Agreed.

SPEAKER_00

Um, okay.

Well, we're almost at at time.

This time has really flown by.

Um but before we wrap up, is there anything else you wanted to mention or uh anywhere you wanted to send people to learn more about you and what you're up to?

SPEAKER_01

I avoid social media like the plague.

So the answer is no, but you can come see me at Rocky Mountain Ruby.

Um and if you are going next week, please come and say hi.

And I do check LinkedIn every once in a while.

So Becky Freeman on LinkedIn.

SPEAKER_00

Okay.

And when is, in case anybody's listening to this in the future, we're recording in 2025, but when is Rocky Mountain Ruby 2025 exactly?

SPEAKER_01

2025, Rocky Mountain Ruby is October 6th and 7th, so about one week from today.

Okay.

We're basically sold out of tickets, so I don't even get to plug the conference.

SPEAKER_00

Okay, well, around October every year, that's about when it happens, right?

SPEAKER_01

Exactly.

SPEAKER_00

Yeah.

All right.

Well, Becky, thanks so much for coming on the show.

SPEAKER_01

Thanks for having me, Jason.

This has been super fun.

Never lose your place, on any device

Create a free account to sync, back up, and get personal recommendations.