Kent Beck, 19th September 2018, at @FFSTechConf
KENT: Thank you very much. Jet lag, a cold, I'm just old! [Laughter]. So I'm just knocking it all back on this one. I hear people saying we have this problem with technical debt. We have code that works, there's pressure to add features, and usually my response to that is, well, it is a trade-off.
Honestly, that's not the answer. It's not a trade-off. For fuck's sake, just fix some little things.
People say, well, how can I get time on the schedule? Well, don't get time on the schedule. Just fix some little things.
So, what kind of things am I talking about? Simple things. Like you've got some code, and it's in the order that it was written, and that's not the order that it should be read. Somebody wants to come and look at it that's going to read it. So reorder the items in a file in the order a reader would appreciate. Just reorder the code for fuck's sake!
So, another kind of little thing you can do is fix naming. There can be names, and there's a clear contrast between two names but they're not named symmetrically, so just fix one, or both of the names, so that they go together. Or you will have the same name mean two different things in different parts of the system. So, fix it so that the names are different in the different places. One name that means two things, separate them. Two names that actually mean the same thing, put them together. Fix the names. For fuck's sake!
What about helpers? Often, the code is the size it is because that's how it was written, not because that is how it can best be read. Once you've rearranged some of the code so it can be read more easily, you will notice in the process, here's this big chunk of code, and this little chunk of code using all the same variables, references each other, there are some clear inputs, and some clear outputs, so extract out a helper method that names the intention going on, not the implementation, and now you can read the code, you can say here's what I want to have happen, and here's how it happens. Sometimes, in the process of doing that, you will notice that that same little snippet of code appears in other places too. So refer to that helper method, from all those other places. Extract out the helpers for fuck's sake!
Sometimes, you will have an if-statement, and the effect of the if-then-else is to assign different values to the same variable. If some condition, x is assigned this, else x is assigned that. Now, an if-statement says, "Here are two different flows of control." It's quite a general statement. If what you really mean is assign this variable one of these two values, turn the if-statement into a ternary operation - I know, ternaries, everyone has seen them abused. I didn't get a red flag on that one, so that's good! [Laughter]. There was an informal competition among the speakers as to who could get the most red flags but nobody's even come close yet. If what you mean is this value or that value, then turn your if-statement into a ternary - for fuck's sake!
The last specific thing I want to talk about is guard clauses. So, we've all seen code that says, "If some condition, then return this value else something really, really long that begins with if some condition, then return something else, else something really, really long but slightly less long." [Laughter]. Take that and turn it into a guard clause. You don't mean do that flow of control, or that flow of control. It is the abuse of an if-statement. In this case, you mean here's an exception, there's some computation, but, in this case, never mind. So, take the if-statement, and turn it into premature returns.
You know, that whole return, one exit and one entry? Do you know, some of us are old enough to know why that's there. [Laughter]. And it's because FORTRAN, and it's because you can have multiple entries and multiple exits from the same routine operating from the same common data structure which is fucked up, but just if I say return twice in the same function, the world's not going to end. If I say here's an exception, here's an exception, and here's the general case, then I can read that more easily, so turn these asymmetric if-statements into guard clauses for fuck's sake!
The process of doing this style of what I call "tidying" is the non-non-macho aggressive version of refactoring. This is the yin to refactoring's yang, lest I be accused of cultural appropriation - that's a different set of issues.
So, the process. One tidying per diff. You will be in the middle of coding and see the possibility of tidying. Do the tidying and submit it was a diff. Don't package up a whole bunch of these into some giant clean-up. When a commit message says clean up, and it's 800 lines long, you're just praying that somebody is - it's going to be late in the day, somebody's going to go, "This looks okay", and they're going to accept it, right? [Laughter]. Honestly, that's a bet, and it's a stupid bet. So just make little tiny tidying diffs. If it is really hard to get diffs through your process, it won't help by having 800 clean-up line diffs. Have one tidy per diff for fuck's sake!
Work on this when you're fresh. If you get tired and you're still tidying, you're going to make mistakes. So don't do that. You have some time, it is Friday afternoon, you don't want to start something new but you're not ready to start drinking yet ... [Laughter]. Or whatever outside thing that you do. [Laughter]. Does drinking qualify as outside? [Laughter]. Thank you. It does in the UK. So, work when you're fresh, and stop when you're tired. Tidying is fun. Once you get into the flow of it, it is like bits and pieces, I will submit a diff, I will fix this thing, submit a diff. I'm getting tired. That's the time to stop. So tidy when you're fresh, and stop just before you get tired for fuck's sake.
You don't want to make a mistake doing hard things, but you definitely don't want to make a mistake doing easy things! [Laughter]. That will mess you up.
Some tidyings will lead - and this is why they are sometimes bigger than they seem - where one thing will lead to another will lead to another, will lead to another, and the fifth thing you tidy, you realise I'm not quite sure that I haven't broken something. Get used to practising. As you tidy, you will do four, five, six steps and you will say, "Oh, now I know what I needed to know at the beginning to actually do this." Just throw it away. It is just a tidying. Practice.
Now, I'm going to do this thing first, and then that thing, and I will switch the order of these two, and that's a commit, and then I'm going to break that off from this other thing, so that you're not committed to this whole big thing that you're doing. Practise, abandon, get used to throwing the cards away.
Poker is a wonderful, wonderful practice for programming, because you learned to fold bad hands. Well, I mean, you get lessons. You get expensive lessons! [Laughter]. You get expensive lessons in folding bad hands. You don't actually have to learn the lessons, but there you go.
Get used to practising and abandoning tidying for fuck's sake.
Why are these small things sometimes bigger than they seem? That's the part of this that wasn't intuitive to me. Can you really make big changes in small, safe steps? The answer's yes, and here's how I think about why. I mean, this could be elaborate rationalisation for OCD, but that would also be okay with me.
The value of tidyings is distributed along a power law, so most of the things you tidy won't really matter, just as most of the grains of sand that drop on to the pile don't cause big avalanches. Every once in while, though, you will do a tidying, and that will reveal another simplification, which has some chance of really revealing another simplification. The thing about power laws, you have many, many tidyings that have small effects and a few tidyings that have large effects. If you have more tidyings, that graph grows on both dimensions where you have many tidyings that don't seem to have much effect but the most extreme value you get grows, depending what the slope of this line is. The more tidying you do, the greater the valuable of the most valuable tidying that you have. It's this rich, get richer, one things leads to another thing that causes that to happen.
So, yes, everything I said seems like something small, but every once in a while, one of them will be much bigger than the others in terms of value.
I'm going to close with one last for fuck's sake, and this is addressed to the men in the room. You and I can submit a tidying diff and be regarded as "crafts people", as "detail-oriented", as "concerned about the quality of our work", and that same exact diff, if you to put a woman's name on it will be regarded as "fussy and picky and bitchy" and that is not right. And it is our job, men, as part of being in this industry to fix that. [Applause].
So a tidying - the same work by different people needs to be regarded in the same way. For fuck's sake. Thank you very much.
FLOOR: You talked about readability and having small diffs. Readability is important. The worst I have had is a 7,000-line pull request on GitHub. That isn't possible to review effectively. Do small diffs, please, people. We know about small batch sizes and frequent feedback.
KENT: Today, you don't have to say please! We have an alternative inside this room.
FLOOR: For fuck's sake!
KENT: Thank you very much!
FLOOR: Also, delete fucking code. If it has no value, you have a version control system. Delete that fucker! Thank you.
FLOOR: First of all, a very, very good video where they basically tidy some C# code into polymorphic dispatches. Absolutely beautiful. Worth an hour of anyone's time. A recommendation. I would say, if you have a problem that you can't get a pull requested? That should be fixed. For fuck's sake! Yes.
FLOOR: We have had an interesting situation at work where we have another female engineer on our team now. She's been submitting pull requests and I find myself looking at this thinking what a pain in the neck. It is not funny, it is shit. It's not men's responsibility, it's everyone's responsibility to take people's work seriously regardless of the gender. I am just saying this. As a woman, I look at other women in tech's work sometimes through that same lens, and that's not good. Thank you for bringing it up. It's everyone's responsibility. As a woman, I look at other women's work in tech the same. So it's everyone's responsibility.
KENT: My observation is men are more the problem, so I will address in an optimisation sense the bigger problems first! [Laughter]. But thank you.
FLOOR: K- again. It is contributing to what you're already saying. For fuck's sake, please stop using the word "refactoring". When the "business" hear the term "refactoring" they hear time wasted. They do not hear the benefits of it. Never deliver it - and this is a real problem for story-pointing - if you think it is a two and it's a ten because you know that code is fucking awful, you need to explain it in those concepts. We need to refactor the codebase. No, at the moment, the code does not support those features, we will have to make a number of of changes to work it into that system for optimisation purposes. You don't use the word "refactoring". [Applause].
KENT: Do we have any Scottish people in the house?
with like a really thick accent? Do you really? [Response from audience inaudible]. Is that some kind of racist bullshit? I had a point, but never mind! Who is next. [Laughter].
FLOOR: As one who found a reference in a readme, "We misspelled 'protocol' as 'protocal', so, when you're searching for it ...". Please fix the misspellings in the code for fuck's sake!
KENT: Thank you. Like once you realise that this is a legitimate activity and stop apologising for it, they're all over the place. The possibilities of that. How long did it take to write that comment versus fucking fixing it, right? Yeah. Yes, sir.
FLOOR: Going on - S- again, by the way, going on your tidying comments, I want to use in this as an opportunity, for fuck's sake, TDD is not about unit-testing, and it's Kent Beck talks about module - it's not about those developer tests. If you're tidying, though them away, and worry about the outside-in module .dll, and write the dirtiest thing to pass the line to the test, and carry on to the next test, or refactor.
KENT: Or fix it.
FLOOR: If it is unit and refactoring.
KENT: This whole unit thing really bugs me! [Laughter].
FLOOR: Go on!
KENT: Because it just means "unit".
FLOOR: For any value of unit.
KENT: Exactly. So, the tests in TDD are intended to help you as a programmer and me as a programmer be a better programmer, and whatever those tests are that are helpful, we should be writing them, and that doesn't mean that they will be helpful forever and ever, so deleting a redundant test is a tidying in this same sense. If you get rid of a test that didn't really add any discrimination to this sieve. We are building a sieve. Bad programs should fall through and good programs should get caught. If it lines up exactly with something else that is already there, just delete it. That's fine. There is nothing wrong with that.
FLOOR: So the only thing I will pick up, and I totally, yes, I love improving code, the one thing that I would say is that if you're a tech lead, if you're an engineering manager, don't just, like - I see so many developers trying to sneak tech debt improvements in, get it under the radar, you know, it's not on the road map, do it anyway. For fuck's sake, make the case for working on technical debt for improving the codebase, make it to your product owners, your business stakeholders. For fuck's sake, this stuff is important, but you need to be able to talk about what value it brings. Even if the developers are really pissed off, you need to make their working environments better.
KENT: Yes, there's a legit, I can understand the arguments on both sides, like, there's a kind of a - yes, I don't need to edit myself. There's this kind of childish, "Well this is just how I develop software, so, if I refactor, that's not your problem", right? There is kind of that attitude which I don't like. It might be your best option. I much prefer the, "Well, let me tell you how software development works a little bit." And part of it is sometimes under pressure we do things. Or sometimes we learn lessons. Which ought to be a good thing, and the only way it is a good thing is if we take our lessons and we put them into the code. And that makes more options for you. But which of those you choose is a function of the relationship you have with the person on the other side of that conversation. Sometimes, you really do have to go, "No, this is just how we develop software." [Laughter].
FLOOR: A-. Okay, various people said that we are heartily agreeing with each other in the room, on a lot of the topics, one of the things, I would heartily agree about what you're putting forward, making small changes, improving the state of the codebase, and so on, I've been reading you saying about this for years and years and years, it makes me realise how old I am! But why is this not mainstream? If it is so good as a thing to do, why is this not mainstream, and how do we prove maybe, as P- said, if the companies are doing good stuff, should out-evolve those not doing good stuff. Why are the companies still doing crap still in business? Is it this is small piece of the jigsaw, and it may or may not make a difference?
KENT: One of the possibilities is this just doesn't actually make any difference in the world whatsoever! [Laughter] Which is not a reason not to do it. But it may just not matter. I would hate if that was the answer, but that doesn't change the probability that it's the answer, unfortunately. I think more likely is that it's not that important. It is important. There are moments when it's extremely important, but those moments are so rare, those moments when somebody has a crazy idea, and, because the code's clean, it's so cheap to implement that idea, and that idea happens to uncover an enormous fountain of value that just nobody could even have guessed was there because they didn't have the clean code, like, if you add up all those factors that's going to happen once every ten years worldwide, so, like, but when it does happen, it's going to be really, really valuable, you know.
It is the friends and family in the long-distance carrier wars. In the 1980s, MCI implemented this Friends and Family rate which AT & T couldn't do because their billing systems couldn't handle it. And that changed the economic landscape of long distance. That just doesn't happen that often. So I would get it's more like this is a lottery ticket. It just doesn't pay off that often. But, for me, it's part of me being satisfied with my work, and that's worth something to me every day, even if it isn't to my employer.
FLOOR: Hi, I've got a bit of a controversial one, and mine is for fuck's sake stop following "DRY", so stop following "don't repeat yourself".
KENT: Why did you say that twice! [Laughter]
KENT: I don't even know you and - usually, I wait until we're go ahead friends, and then -
FLOOR: The reason I hate is that because two things. I haven't written a helper method in three years, so I explicitly avoid them at all costs because as soon as you have a generic piece of code that is not business-centric, it becomes a library. You extract it out and you can use it in other places. If it is business-centric, it becomes its own application in its own special place. I get annoyed when I see developers moving stuff around a monolithic application tidying up but what they've done is created a larger spaghetti codebase things referencing things from all over your code and makes it impossible to change it further down the line. If you've got something not repeated but is used everywhere and will break everything it touched.
KENT: You have two scenarios. You have these four lines of code happen to be textually identical, even though they're solving different problems in different contexts. If I create a helper method, now somebody changes this to fix this call sight, it breaks that call sight. That's definitely bad. I have two four line chunks of code that really are the same thing in two different places, now, if I fix this one, I break that one. So, you might be in either one of those situations. The thing I learned to trust is if the code is telling me something, if there is that chunk of code is in a bunch of different places, it means it's really important. And I learned to trust that voice. Now, it doesn't necessarily mean I know how to extract it out - sometimes, I do, and it's really obvious, and there's one parameter in, and one parameter out, and no side effects, and more. That's really safe. Sometimes, that chunk of code changes this global variable, and that global variable. It's going to compound the nightmare, which is that we don't have small enough scopes yet. And then, we have another problem. You know, I came up with this phrase "make the hard problem easy to solve and then solve the easy problem". Warning, making it easy to solve may be hard! Right? That's that kind of, sometimes, you want to tidy, but you can't. Well, then, there's something else you have to accomplish. On the don't repeat yourself - I just copy and paste, because I don't know what the abstraction is. Then I paste again. I still don't know what the abstraction is, and then pasting again is my best option. If I wake up in the middle of the night, or at 9 am after my first coffee ... [Laughter]. And I think that's more likely for me, right? No, it is the 3 am. "I have to code this this". Now I finally realise, "Oh, shit, this is what I really need" then I ought to be extracting it out but I want to do that in this tidying style and not in big style. The reflexive, if I say it two times, I have to unify it, well, only if that makes things better, not if it makes it worse.
FLOOR: Continuing on with this slightly controversial statement, so, every one small change that you introduce in code, depending on your branching process, will result in a diff, and a review, and a PR, and a merge. Of course, if you want to continue on with that, you need to then branch [Off mic] work you're doing, so, I mean, I would probably start off by saying pull requests are for entrusted developers. For fuck's sake, push it to master.
KENT: Yes. If you take that to its illogical conclusion, you come to something I call "Limbo" where it's a system of microdiffs and no code reviews but lots of other feedback mechanisms. So, if you wanted to talk more about that, this is like my active - one of my many active research topics. The pull-request model has advantages and disadvantages and enormous costs that we don't think about, because we don't think about the alternatives. That's it. Finito. Thank you! [Applause].