Conversations about Software Engineering

Conversations about Software Engineering (CaSE) is an interview podcast for software developers and architects about Software Engineering and related topics. We release a new episode every three weeks.

Transcript

Stefan Tilkov: Welcome listeners to a new episode of the CaSE podcast, a new conversation about software engineering. And today my guest is Mark Seemann. Great to have you on the show.

Mark Seemann: It’s great to be here.

Stefan Tilkov: Very fittingly, we’re here to talk about your book, which is called Code That Fits in Your Head: Heuristics for Software Engineering. What better topic to talk about in a podcast about software engineering? It’s awesome to have you. So why don’t you start by telling us a little bit about yourself.

Mark Seemann: All right. So my name is Mark Seemann as you said, I live in Copenhagen, Denmark. I’ve been here all my life being a programmer, software architect for the last 25 years, basically. I originally have an education as an economist from the University of Copenhagen, but decided that that wasn’t really what I wanted to spend my life on. So I retrained myself into being a software developer. You know, this was back in the nineties. So basically if you could spell HTML you could get a job in IT, and that’s what happened to me.

Stefan Tilkov: Okay. So I’ve known you for a long time from conference appearances and from your blog, which we will definitely recommend and put in the show notes at the end. But the topic we’re talking about today is a book that you recently released, which is called Code That Fits in Your Head. So the subtitle is Heuristics for Software Engineering, and I think both are intriguing and interesting. So maybe we can start this off by you telling us why you chose this title and why you chose the subtitle.

Mark Seemann: So actually I think the subtitle may be closer to the original title that I had in mind. So we can start with that, you know, heuristics for software engineering. So the motivation for the book was that I’ve spent the last ten years, maybe, coaching various different software development organizations on fairly low-level things like how do you do test-driven development? How do you move in a more functional direction? You know, things like that. And during all those years, I’ve started to notice that there would be some explanations where I was, you know, when I would be telling people how or why to do certain things, I could just tell that these explanations resonated with people better than other types of explanations. So I started just, kept reusing, kept coming back to the same explanations again and again, because I could see that these were actually the ones that resonated with people. And after having done that for many years, I started to think about, okay, this actually seems to be a collection of ideas and suggestions that instead of just keeping them local to coaching, you know, a team and so on, I might as well just scale it up and write it down and publish it as a book as well. Because they seem to be ideas that are fairly generalized, reusable, not in the sense that you have to use all the ideas in the book, but you can think of the book as a catalog of ideas. Some of them go together really well. And some of them, you know, you can definitely view those ideas as optional. You don’t have to pick them up, but if that makes sense for you you can pick them up. So I started to think about this as being related to software engineering, in the sense that if we go back like ten years ago, for example, I was very much in the position where I was thinking about software development as being mostly a craft, just like the whole idea of software craftsmanship, but also because my father was a craftsman as well. You know, a real one, he was a bricklayer, stonemason, or whatever you want to call it. And so this whole idea about learning from a master–apprentice relationship and that way of picking up a craft made a lot of sense to me. And back then I felt that software development was basically like that, that you couldn’t really formalize things, that it was all just a collection of personal experiences that sort of came together as you matured as a professional. And then you became better and better at what you did from that set. So if you’d asked me ten years ago, that’s probably what I would have told you. But then because I had this experience with using or reusing the same ideas over and over again with various different teams, because I reuse the things that I could see resonated with people, they also started to think about, okay, so there’s actually a set of things that seem to resonate with people that are more reusable in the sense that I can use the same set of motivations. I can use the same rule of thumbs with, you know, independent teams. So I began coming back to this idea of maybe that’s actually part of what an engineering discipline is. If you have a look at what’s “real engineering,” if you will, real engineering is also quite creative and there’s a lot of unknown… there’s a lot of problems where you don’t know whether you have the solution. If you want to build a bridge across a span of water or something like that you have the general idea of how you would go about solving that problem. But there’s still a lot of problems that you actually need to find solutions for. So I began to view this set of heuristics as being a small step toward something that is more like software engineering, if you will. So that’s why I chose the subtitle Heuristics for Software Engineering. And then the overall title of the book is Code That Fits in Your Head. And the reason for that is that one of the main ideas that runs through the book is this idea of the cognitive constraints that we are equipped with in our brain. The brain is not a completely understood organ, of course, but you know, there’s some experimental evidence that seems to indicate that we have some short-term memory, we have some long-term memory and particularly the short-term memory is actually quite limited in the sense that we can keep about… you know, there’s this famous paper from 1956 called The Magical Number Seven, Plus or Minus Two. So if we just take that number seven as a rough guide on how many things can we keep track of in our short-term memory? That’s about seven. And you know, let’s not fight over whether it’s five or nine or maybe a little bit more or less, but it’s not 50, it’s not a hundred. And once you begin to think about this idea of having a very limited set of things that you can keep in your brain at any given time, that might actually begin to affect the way that you think about how to organize code. So that’s the overall idea in the book, that the code should be organized in such a way that there’s not too much stuff going on at any given point. Of course you have to build a realistic code base where lots of things are happening. If you count all the things that have to happen in a realistic code base, that will be plenty more than seven. That was probably going to be 700 or 7,000 things going on or even more. But the idea is to organize the code in such a way that when you look at a piece of code, an isolated piece of code, and you try to understand that that should not be more than, you know, seven things going on so that it fits in your brain. So that’s the overall idea with the title and the subtitle.

Stefan Tilkov: And that reminds me of one of the very first, I think my very first professional project that I programmed on, that was a long, long time ago, they had this approach where the people wanted to do object-oriented analysis, but they didn’t really know what that was. So they came up with a ton of objects. They had like these two binders, two huge binders of objects, alphabetically sorted, and it was 2,000 things, all on the same level. Like this was sort of the most obvious violation of that rule, that structure missing. And nobody could make any sense of that, even though everything was cross-referenced to everything else. But I think everybody who has tried to maintain structure of some kind has some ideas of how to get to that. So maybe if we approach the book from a top-down perspective, I noticed that you separated it into two major parts.

Mark Seemann: Yeah.

Stefan Tilkov: I think accelerate or acceleration and the other one’s called sustainability. Could you elaborate a bit on that? Why are those… why do you deem those two facets to be the most important ones?

Mark Seemann: So I was actually struggling a little bit with finding good words, you know, good single words that encapsulated or represented the essence of what’s in each part. But the idea basically of the two parts of the book is that the first part is going to tell you a lot of things about how to approach a greenfield software development problem, if you will. And there are lots of ideas there where you can also use those ideas, even if you’re doing brownfield development, but a lot of the ideas in that part of the book are things that people typically will associate with greenfield development, like test-driven development and setting up the development environment, and then things like that, you know, doing a vertical spike through a complete architecture, walking skeleton and things like that. So that part of the book basically gives you an example of how to go from zero code to a working feature. And that’s why I’ve… I was trying to figure out what to call it and then I thought, well, let’s call it accelerate or acceleration, because this is where you accelerate from zero code to some code, at least. So that’s the idea of that. There’s a sort like a narrative through the entire book where we start from scratch and I show you how to build a fairly realistic piece of sample. But then I thought, you know, after the first feature is complete and you sort of have gone from zero code to a working feature, there’s still a lot of other problems that teams typically have to deal with on a day-to-day basis that are not related to starting up something from scratch, but it’s more related to working with an existing code base. So how do you refactor, how do you add new features? How do you troubleshoot defects? All sorts of things like that. And that’s why I created another part and I call that sustainability because, you know, the first part of the book is about … how do we accelerate from zero into a good sustainable pace, but then you also want to be able to sustain that pace afterwards. So that’s why I call that sustainability, because it’s basically all sorts of different ways to approach that problem of, you know, how do you keep a code base from … deteriorating as you add more and more stuff to it? Because that’s what often happens, is that as you add more stuff to it, it becomes more and more difficult to navigate and understand it.

Stefan Tilkov: That’s actually one of the things that I found interesting. As you mentioned, you developed this little case study and you use C# and the .NET environment as examples, but it really didn’t matter, which was something that was very good for me because I don’t know the first thing about C#. I’ve never programmed professionally, except for maybe a Hello, World tutorial or something like that, with C#, but it really doesn’t matter. I can totally see how this translates to basically any language, because it’s not about programming language features, or at least not about the syntax of programming language features. Right? One of the things that I wondered a bit about, I think you elaborate it in the book but I forgot, it was: of all the languages that you could choose, why didn’t you choose F#? Were you tempted to do that? Because I know you have an interest in that.

Mark Seemann: Yes, yes. Now I’m very happy that you found it readable, even though you’re not a professional C# developer. That was very much my goal to be able to get to a wider audience than just the C# people. So, you know, personally, I’ve learned a lot from Martin Fowler books and Kent Beck books, which would typically have code examples in Java or in C++ or things like that. So I aim to be able to be, you know, language neutral in the same way that they were in the sense that if I am a master C# developer, if I can understand that Java code, I aim to write the code so that it would translate the other way, because I have as much Java experience as you have C# experience, I’ve written Hello, World, and that’s basically it. So why didn’t I write it in F#? Well, basically it’s because I wanted this book to … reach as wide an audience as possible and while I really love F# as a language, I’m also painfully aware that there isn’t a big audience of people who readily just go and read F#. They exist out there, but this is definitely like… I think Microsoft itself puts it something in the… they don’t have exact numbers, but they say something about orders of magnitude. So they say something like there’s millions of people who write C# code. And there are hundreds of thousands of people who write Visual Basic code. That’s also on .NET. And there are thousands of people who write F# code, that’s sort of how they put it. So I wouldn’t be able to reach the audience that I’d like to reach if I had written the example code in F#, unfortunately. So that’s going to be my next project. Maybe. I hope.

Stefan Tilkov: As you wrote it, how often were you… how often did you notice that I would really do this differently if I had a, I don’t know, purely functional language. How often did that even play a role theoretically?

Mark Seemann: That comes up a lot actually. But one of the things I did with the book is that I’ve actually written the code in this style called functional core, imperative shell. So as much of the design as possible I’ve actually tried to write as pure functions, even though there I’m trying to be idiomatic to a style of C# that you know, again, that would also make sense to a Java developer, maybe a Ruby programmer. But I’ve also spent a lot of time, the last five years, basically, trying to find ways to translate FP concepts into object-oriented programming and the other way around as well to try to sort of figure out, okay, how different are they actually, or are they more like different expressions of the same fundamental ideas? And I think most of the things you can do in functional programming, you can do in object-oriented programming as well. It’s just that what typically happens is that in many functional programming languages, like F# for example, there are things where that would be a one-liner in F#, and then you have to translate it into C# and it becomes three class files or something like that. But … it’s not that it’s impossible to translate the ideas. It’s just like some of those things become very succinct or the other way around, you know, depending on the direction of translation. But … I think I managed to keep the entire core logic of the example application as I said of pure functions. I don’t feel as constrained as I did, you know… Five years ago, if you’d asked me, I would have said, you know, oh, this C# is so frustrating because there are things I couldn’t do in F#. And I can’t do that in C#, but now I’ve learned how to do them. And C# just creates more verbose code that you normally like, but it’s not that I can’t do them.

Stefan Tilkov: Okay. So let’s not dwell on this any further. It’s not the topic of the book. I really like that. Really like the fact that it’s applicable to a wide variety of programming languages and styles. So maybe if we dive in a bit… It would be totally boring, sort of spoil the fun as well if we went through all of it, but maybe we can pick out a few things just to give listeners an impression, or maybe have some discussion about some of the concepts that you address here. So I’ve picked three. We can of course move on to something else if it comes up. So the three things that I picked up was vertical slices, triangulation, and rhythm. Those are all chapter titles in the book. Maybe we can start with the vertical slice concept.

Mark Seemann: Yeah.

Stefan Tilkov: What you develop in the book is a what you could call a typical, well, maybe not typical, it’s a little small, but you know, from the structure it’s a typical kind of enterprise application that people would provide with a database backend and some frontend stuff like that. So can you explain to us a bit what vertical slicing has to do with this thing.

Mark Seemann: Right. Yeah. So this… It’s not my idea at all. I’ve picked it up from various different people. I think this has been something that… there’s not one person that’s associated with this idea, but lots of people. But the idea is basically that you try to go from, you know, when you’re looking at a feature you’re trying to get a feature or part of the feature completed as quickly as possible. Instead of getting… the alternative would be to get mired down in having to implement a complete layer of things. So it’s easiest… I think it’s most easy to explain the idea of a vertical slice if we try to contrast it with how people often go about things. So what I’ve often seen teams do is that they sort of get hung up on a particular aspect of, you know, part of a layered application architecture, and it’s typically the data layer where I’ve met quite a few teams that basically… they spend months, if not half a year, on just trying to come up with a good comprehensive data layer that can access that database. And they spend a lot of time just doing that. And in all that time, they have nothing to show for their efforts because they’re just wiling the time away on creating a nice data access layer. So in contrast, the idea is to start with, you know, pick some small feature where you could actually say this is realistic to get this small part of the application up and running in maybe one week, maybe two. The shorter the better. So the one that I picked here, so the example code base is an online restaurant reservation system. So the first feature that I actually picked here was just to be able to make a reservation so that … this is a REST API. So you should be able to post a little JSON document that sends the restaurant reservation. And I would consider that feature complete when I have data in the database. That’s basically what that vertical slice is about. So this is trying to go through all the different concerns that you’d normally divide into layers or strata of, you know, a classical, layered application architecture. So a vertical slice slices vertically through all of that. So it involves both the data access, but it also involves the business logic and any sort of presentation logic that might be present as well. So in this particular example, for example, at the outer boundary of the application we have to do data input validation because we get JSON, but you know, there are various ways this JSON could be malformed. So we need to figure that out. Then there’s a lot of business logic that actually has to determine, okay, can we actually accept this restaurant reservation? Because we might not have a table that fits the number of people in the reservation and so on. And then finally, if we decide that we can accept the reservation, we need to actually save it into the database so that we could later on retrieve it. So that sort of cuts through all the different concerns of data, access, and business logic and, you know, presentation layer and so on. So that’s why we call it that. And I know that you’re basically asking for the benefit of the listeners because you know this already. But that’s the general idea.

Stefan Tilkov: I’m also asking because I have some follow-up questions.

Mark Seemann: Cool.

Stefan Tilkov: One of the things that I found interesting was that you sort of stopped at the REST API layer. So did you consider adding an actual UI on top of that?

Mark Seemann: Oh, you definitely could. It’s well, this is really also just a choice that reflects my personal expertise because I haven’t touched UI development for the last ten years. I tried doing some Angular back in 2012 and, you know, basically left it in disgust back then. And it’s just my temperament and I know lots of people who enjoy JavaScript quite a bit. But I’m heavily on this statically typed side of things. So I couldn’t really reconcile my love for static typing with JavaScript. So yes, you could definitely add some user interface on that sort of approach to things. I just didn’t because I have no idea how to do that.

Stefan Tilkov: So on the other, well just behind this layer, then, if we go down from the REST API layer way down to the database, I think you picked a traditional MS SQL server, RDBMS, but it could be anything, it could be MySQL server or whatever. It doesn’t really matter. What is your recommendation on how to distribute responsibility among the different layers or types. Does that factor into the heuristics that you give people here? How do people make good decisions about where to put what?

Mark Seemann: Yeah, I actually didn’t write much about it in the book because I didn’t want the book to be a book about architecture. So I left that vague basically. The way that I typically think about this is that I would normally think about those typical three or four layers of application architecture still in the sense that I would think about a part of the data, a part of the application architecture as being the data access components, maybe there’s more than one. And I would think about another part of the application architecture as being the business logic, and then there would be the presentation logic and so on. So that’s often how I think about things still. I probably more write in the sense of ports and adapters than your typical horizontal layer application architecture. But still, even if you look at ports and adapters or Onion Architecture, or hexagonal architecture, there’s sort of more or less three words for the same, maybe with some variations. You typically have the core of the application, which is the business layer, and then you would have some concentric circles around that that would have other concerns like data access and user interface, for example, and so on. But this is just my own default approach to things that I would often gravitate toward, that sort of separation of technical concerns if you will, that I’d like to keep the data access separate from the input validation.

Stefan Tilkov: So what prompted me to ask this was your mentioning that very often you see people or teams stick with data for a very long time. Right. Trying everything to get the data layer perfect.

Mark Seemann: Right.

Stefan Tilkov: Which I can totally imagine, but maybe it’s because you know, sometimes you get this from having one or two experiences recently, right? But my experience is that I’ve seen people spend not enough time with the data layer. So I’ve seen, I’ve seen people spend too much time with an abstract concept of the business layer with the goal of going for an Onion Architecture. We don’t really have time to explain all that, so hopefully our listeners have some idea of what this is, this abstract core of business logic. That sounds like an awesome idea unless it hurts you because he didn’t care enough about the data. So I was just wondering how do, what are some, in your experience, some good heuristics as to how to… how do people find out whether they’re spending the right amount of effort at the appropriate concern or segment or layer or ring or whatever the metaphor is that you use.

Mark Seemann: Yeah, but again, since we’re already talking about the vertical slice, I think that doing a vertical slice is one way to figure out where the difficult parts of your application might reside. So not that it’s, you know, there’s few universal solutions to problems like that, but I think it’ll give you some data on which you can base further decisions. If you try to start out doing, you know, pick one small feature and try to implement it all the way through, this is very much in the style of Growing Object-Oriented Software, Guided by Tests by Nat Pryce and Steve Freeman. And really subscribe to that general idea because I think at least what it does is it’ll generate a lot of insights into what parts of the application actually turn out to be difficult because it might actually not be the parts that you think are the most difficult ones. So you might, for example, as you said, you’ve seen people who may have been spending all their time on the core logic layer. And then they haven’t really figured out how to be efficient, store things, that might be the case as well. But I think if you do one or two, a couple of vertical slices, you’ll probably find out where the pain points are, because it really depends on the sort of application that you are developing. Now, what I know about, the little I know about your career, I think you spend your time with larger systems than I typically tend to spend my time on. And so that’s probably also why you have that experience and I have another set of experiences because I often work with… The kinds of teams that often contact me are fairly small teams that work on fairly specialized types of applications. And sometimes … so I’ve worked with one team that had a very large database, backing it up. But the stuff that we actually worked with was still, you know, a code base that wasn’t that difficult. And I think you may be working on larger scale architectures, and you may run into different sorts of problems. So I also just wanted to point that out because again, I don’t come here with a universal experience. I haven’t tried all sorts of things. And so what I have here is just suggestions for what I’ve found work, work for me. But I’ve found those vertical spikes to work very well for me.

Stefan Tilkov: Yeah. So I can say from my personal reading of the book and my personal experience, my colleagues and I are working on lots of different projects with lots of different sizes. And I found a lot of what you wrote pretty much applicable, potentially applicable to every team. It’s just possibly different parts that they would pick. It’s a collection of heuristics and you pick whatever makes sense for you. And I don’t think you ever suggest that you have the one answer for everything.

Mark Seemann: That’s good to hear.

Stefan Tilkov: I like this. I definitely liked the idea that the vertical slice will help you focus on what’s important. And actually what’s important to the outside users of your system, and not to yourself, to your personal interests or, you know, CV optimization needs or whatever it is, but rather on the actual value that you want to deliver to somebody else. I really like that thought a lot. So if we can move on, one of the things that you talk about a little is triangulation. What is that?

Mark Seemann: So triangulation is a technique that … falls fairly naturally out of test-driven development. So the traditional way that most people are being taught test-driven development is you write a test. You write just enough code to make the test pass. You then refactor a little bit, and then you go on and write a new test. So this is the red-green-refactor cycle. So if you follow this process fairly rigidly you’ll start by having one test case. And that one test case you can… basically the simplest thing that can possibly work there is just to return a hard-coded answer because that’s going to pass that one test case. And then as you add another test case, you have to make the code a little bit more general, because it now needs to be able to handle two different cases instead of just one. And then you add more and more and so on. So it strikes me as a little bit like, you know, traditional triangulation, where if you… let’s say if you want to locate a radio transmitter somewhere, you know, in the old times, maybe when we had radio towers that would transmit radio you could walk around in the surrounding landscape and if you have a radio direction finder and sort of get the idea of the bearing of the radio tower, and if you walk around enough you can do simple geometry to figure out OK what’s the exact location of the radio tower, even if you don’t have visual contact with that. So that’s triangulation and test-driven development just sort of strikes me as being… it’s almost the same, except that the thing that you’re trying to, you know, the position that you’re trying to find, it doesn’t actually exist. It’s more like… with the radio tower, the radio tower already exists and you move around to figure out where it is. Whereas with writing test cases, it’s all sort of almost in the opposite direction, where you say instead of trying to measure where does the signal come from, you sort of point in one direction and then you move around a little bit in the landscape and then you point … in the same direction, but from a different position. And then the cross where all those beams cross, if you will, that’s where your target is. So that’s sort of like the visual metaphor that I imagined…

Stefan Tilkov: The best position for your radio tower.

Mark Seemann: Yeah, exactly. But instead of finding a position for a radio tower, you figure out, okay, what’s the algorithm, or what’s the behavior that you’re actually driving there. This just strikes me as being a pretty obvious metaphor. And I think I may have picked it up from Robert Martin maybe, he’s really, really close to some of those metaphors as well.

Stefan Tilkov: So in general, what role do tests play in your vision of good software development? It’s a critical question. A lot of conversations have been had about this particular topic, still I’d be interested in your opinion.

Mark Seemann: So what I am basically trying to advocate for in the book is what I called, you know, something that you could generalize as being feedback-driven development in the sense that I think… You know, writing code that actually works is actually not that easy. We can very easily make very simple mistakes. And if you’ve been in the game just for a couple of years, you know that you can make all sorts of stupid mistakes where, you know, when you come back to them, find the bug, you know, two years later, you can say, how could I ever have been so stupid to make this sort of mistake, but you make them. So I think it’s very important that you get some immediate feedback on the code that you write so that you can get an idea of whether it works or not. And there are various different ways of doing that. And test-driven development is definitely a very popular and a very well-known way to get feedback on the correctness of your system. It’s not the only one. But it’s a major one that I often recommend that people use together with some of the other ones. But other examples are… again, I mentioned before I like static type systems quite a lot. And you can actually get a lot out of this, the compiler, if you have a language with a good type system. And particularly if you try to design your objects or your types in a certain way, you can actually get a lot of feedback from the compiler itself because it says, okay, this thing is actually not even type checking. So it can’t possibly be right. … Lots of compiled languages will have compiler errors of course, but also compiler warnings. And at least I find with C#, for example, all the compiler warnings that the compiler will emit are almost always worth looking into because there’s… There might be false positives, but in my experience, most of the compiler warnings that the C# compiler will emit will be… You will want to address those warnings because it’s probably an error on your part. So one of the things I recommend in the book, for example, it’s just the simplest thing, is to just turn on this flag you can set where all warnings will become errors and that prevents you from piling up compiler warnings. I remember … once I sat with a team where we were looking through things and they had like hundreds of compiler warnings, which made it really difficult to find… I was looking at some code they just wrote and they couldn’t figure out why it didn’t work. And I knew that that was going to be a compiler warning because I had just looked at the code that they’d written. But they were so engrossed in just writing the code that they didn’t notice. And that’s often what happens when you’re writing code. So I suggested to them, could we look through the compiler warnings to see if there’s a warning? And the guy said, well, we can’t do that, because we have like 300 of them already. So that’s what inspired me. Those sorts of experiences inspired me to say to people, okay, just turn warnings into errors, because that prevents you from piling up all those warnings because you can’t really move on if a warning is an error. So that’s another kind of feedback you can get to … get a little check on not making stupid mistakes.

Stefan Tilkov: Yeah. I seem to recall you mentioned that pretty early on, right. I had to smile when I read it. I strongly support that advice. It reminded me of a project where there were tons of exceptions being thrown in, exceptions, stack traces being printed in the logs, but that was just normal operations. So you just expected them to be everywhere. So it was complete… all the information was completely lost because if it’s noise, then you filter it out as noise without ever paying attention to what’s there. So, yeah, that really is a problem. Using the tools that you have at your disposal is definitely an obviously good idea.

Mark Seemann: And this is also one of the reasons why I’m fairly aggressive when it comes to thresholds in general. So, for example, with warnings and errors, the correct number of compiler warnings is zero. And also, as you mentioned, you know, unhandled exceptions in production, the correct number of unhandled exceptions in production is zero. Exactly for the reason that you mentioned: if you have a lot of them already, the important ones will just be drowned out by all the ones that aren’t “normal.” And again, this comes back to this distinction between the two parts of the book, the acceleration part, and the sustainability part of the book, because it’s much easier to eradicate all that noise if you do it from the beginning. Because I would often … If I’d say to most organizations, you know, the correct number of unhandled exceptions in your production system is zero, people would just laugh at me and say, that’s not possible because they have so many. But I know it’s possible because if you build that idea in from the beginning and say, there can’t be any unhandled exceptions in production, well, the fact is there will be, but then again, it becomes… So this is an idea from lean software manufacturing or lean software development that comes from lean manufacturing, this idea about all defects are stop-the-line issues. So if you actually see an unhandled exception in your production system, that becomes top priority because you don’t want those to build up. And I find that, with my limited experience, that it’s possible to actually eradicate those unhandled exceptions in production, if you go after them very aggressively from the get-go.

Mark Seemann: Stefan Tilkov: That makes a lot of sense. So if you say that one of the strategies to get to this is to do it right from the beginning, right? And to treat violations of the rules as things that stop the line. What do you do if you inherit a code base that doesn’t follow, didn’t follow those rules, how applicable are the strategies and heuristics for a project like that?

Mark Seemann: Mark Seemann: Right. That’s why the second part of the book has some ideas for dealing with some of those things. So for example, if you have this code base with, you know, 300 compiler warnings, it’s probably not realistic to just say, well, our top priority is to get to zero compiler warnings straight away. But what you can do is still, you can start to sort of chip away at the compiler warnings a little bit at a time. It’s one of those maintenance tasks where you can actually distribute them over a team and take them in small bites. So if you basically, if you have, I know this is probably unrealistic to many people, but if you have like an hour of idle time somewhere, because you’re waiting for something else, you’re waiting for a code review or whatever else it is, it’s actually a really nice little thing, you know, a little extra task you can take on and say, I want to go particularly after a certain category of compiler warnings. So maybe you can filter those warnings into various different categories and so on, and they will also typically have different sources. So a normal code base is often assembled from various different libraries that are assembled into an application. So maybe you can just look at one library and one category of errors in that particular library. And then you can say, okay, so I’m going to go after, you know, I have two hours to spend here because I’m waiting for a code review or whatever it is, you can say, okay, I’m going to go for that category of warnings in this particular library, because instead of being three hundred warnings, that’s going to be ten warnings or something like that. And then you can go for those and you can say, I’m going to eradicate those warnings from that library. And then you can commit that to your source control system and send a pull request for that, or merge it into master, whatever. And then you just, you know, you improved the situation, just a little bit. And then at least in C# you can then go and change the settings of the compiler for this part of the code base, where you can then say, alright, so for this category of warnings in this particular library, those category warnings should now be treated as compiler errors, because there are no more of those categories in that part of the code base. So you can sort of slowly migrate, you know, a little bit at a time so that you could sort of get to that goal of zero warnings. But maybe it’s going to take you a lot of time. But it’s one of those things again, where you can say, lots of people can do that, they can do it in their idle time if they have idle time. And I think lots of people will just probably feel that they have no idle time, but I think if you actually look at what programmers do, I would believe that those people actually have lots of idle time, they just don’t often identify it as such.

Stefan Tilkov: It probably depends on the culture of the project. Right? Well, in your organization, whether that’s seen as a good thing, there’s somebody who says, well, yeah, awesome that you did that. Or whether somebody says, well, why did you waste your time fixing something that didn’t need fixing? Which I agree is not a good reaction, but if you have to fear for that reaction, it’s highly unlikely that you’ll do something like that.

Mark Seemann: Yeah.

Stefan Tilkov: Maybe related to that, you mentioned before that you changed your mind a bit from the craftspeople view to the engineering view. One of the things that I understood and I associate in my head with the craftspersonship thing is that you take pride in your work. You don’t do shitty work. You always want to do things that don’t insult your personal honor and the way you want to do things. Is that something you still believe in, or have you dropped that along with the movement from craftsperson to engineer views of things?

Mark Seemann: No, I still take lots of pride in my work and I believe strongly that we should try to do the best that we can. So the idea of moving toward something that’s a little bit more engineering based again is more because I realized that a lot of the rules of thumb that are used to do good work, in my own subjective opinion, were things that were teachable and applicable to more than just me. So that’s why I began to see that as a small step toward something that is more engineering based. It’s not that I… So I don’t see that as being opposed to the idea of craftsmanship. I see it more as being maybe not a parallel, it’s not pulling in exactly the same direction, but they can definitely be aligned, those two forces. I can also imagine how they can be pulling in opposite directions, but it’s sort of like if you imagine that these are two forces that pull along two different vectors. The idea here is to make those vectors pull in fairly much the same direction. So that’s the way I believe that you can be most productive. But what you just said here, with the example of if you have a culture where people are actually being told that they can’t “waste” their time on doing maintenance work like that, that’s a typical example of where you have those two vectors pulling in basically the opposite direction of each other.

Stefan Tilkov: Completely agree.

Mark Seemann: And people often ask me, what should we do about that if we are in that sort of culture, and what I’ve tried to tell people is that… I don’t know. I mean, that’s not… why are you asking me about this? I actually don’t have a good answer to that in the sense that… I understand why people ask me because they feel that I’ve somehow convinced them to do something else. And then they sort of want me to convince their colleagues or their managers as well. And what I try to tell them is the reason why I convinced you is because you were ready to be changed. But I can’t go and change some people who are not ready to be changed. You need a salesperson to do that, and I’m not a salesperson. So you need someone else to do that. But, you know, ultimately it boils down to Martin Fowler’s change your organization or change your organization.

Stefan Tilkov: I completely agree with that. I think my personal view is that … this craftsperson view is a little too idealistic for my taste. To sort of draw the motivation from some abstract, almost spiritual view of the whole … Maybe I’m not spiritual enough for that, that’s entirely possible, but for other people that is maybe the right way to do things. I think that the move toward engineering that you suggest, this is just a neutral thing, or this is just a trade-off. Of course it might, at the moment, it might not be the best investment of time to invest this one hour into getting rid of compiler warnings, it migth not the best use of that engineering time, right? Could be better spent writing a test or automating something or improving build time by 5%, whatever. I have no idea. But sometimes that is the best investment of your time. And in general, of course you should aim for all of this, but I think it’s sort of… the engineering view is that all of this are trade-offs. There is no truth. There is no, this is the right thing. There’s no good or bad. There is nothing, you know, you’re not a more worthy person if you follow this line, it’s just that this particular situation calls for this engineering approach and this calls for that engineering approach. So I think it’s a little more science driven or neutral. That may just be my rationalizing what happens to be my current opinion, which changes all the time as well. So just posing this to you for comments.

Mark Seemann: No, it makes much sense to me. And that’s also the direction I’ve been going in for the last couple of years. Exactly. Because if we make it all crafts based, it becomes all personal, it becomes all subjective. And it also makes it much more difficult for us to work together. At least that’s how I see it, because everything starts to boil down to do I like this or not? Instead of trying to evaluate, does this code solve the problem? And one of the things that is my focus in the book and in general is that code has two purposes. It has the immediate purpose of making the software do the thing that the software is supposed to do. But then it has the secondary purpose that it needs to be in a state so that, you know, the next person who comes in and has to work with that code can effectively work with the code without generating too many new bugs and so on. So this comes into this whole idea of being readable and understandable and so on.

Stefan Tilkov: And also detach it a little bit from you personally, right? From you, you as a person are not the most important thing here. It’s the code. I like it a lot.

Mark Seemann: Exactly. It’s actually very impersonal. The focus is actually on anyone else than me in the sense that this code needs to be understandable by someone else. I may even know because there might be a new employee who we’ve got hired next month that has to work with this code. And I don’t even know who that person is yet. And the code should be to a standard where that person can come in and take that code over or also work with it. And also I’m just being kind to myself six months from now, because six months from now, I’m a new person as well. So yeah, so a lot of the ideas in the book just try to give you some good rules of thumb of trying to evaluate is this going to be readable and understandable by someone else.

Stefan Tilkov: Awesome. So maybe let’s move to the last thing that I picked, and talk a bit about rhythm. Is this about music or what’s the topic?

Mark Seemann: If only it was about music! But it’s about the way that you can approach your day or your week or your months. And I think I have two subsections in that chapter. I have one on personal rhythm and one on team rhythm. And again it’s just some general observations about how you could organize your day. So it’s not one of those productivity manuals that tell you to organize your day in a particular way, but it’s just some ideas. And to start with a personal rhythm, what I’ve often found is that getting away from the computer regularly is actually what makes me most productive. This goes a little bit counter to the general programmer ideal of being in the zone. Lots of people like to be in the zone and this idea of where you just sit and program and six hours just went by and it’s dark out. And you feel that you’ve been very productive. But what I’ve actually found with these sessions where you just program and code and code and code and code away is that you can often lose sight of what it is that you’re doing while you’re in the zone. So you can actually waste a lot of time going in a wrong direction because you never stopped to, you never paused to reflect on whether this idea, the direction that you’re going at the moment, is actually a good direction or not. So I use various different life hacks to force me to stop every so often and go and do something else. So I have the Pomodoro timer that goes off every 25 minutes, just to remind me to have a break. So for me, the Pomodoro is almost the opposite of what it is for a lot of people in the sense that I actually use it to force myself into taking the breaks. Sometimes I also use it for the normal way, but this idea of having a break… personally, I have this rule that I have to get out of my chair and out of the room, I have to leave the room. And then what very often happens is that I get a new insight while I’m away and doing something else, even if it’s just for five minutes. And in general, if you expand on that… I’ve been working from home for many years now, so I usually do some either grocery shopping or I do some physical exercise during the day. And my general experience is all the insights, all the breakthroughs that I’ve ever done in software development, they’ve always come when I was away from the computer. So taking those breaks and getting away from the keyboard at regular intervals has actually, at least in my experience, been a very big productivity boost. And I’ve asked around a little bit, not scientifically, but just whenever I had the opportunity to ask other people, and that seems to be a general observation that most people have. So that’s one thing you can do.

Stefan Tilkov: I recall a talk by Rich Hickey of Clojure where he was talking about Hammock time. Which I think is way underappreciated. So.

Mark Seemann: Hammock-driven development.

Stefan Tilkov: Yes. This was all I think related to personal time, you also mentioned team rhythm. Right? How are those two things related?

Mark Seemann: So again, this is not a prescriptive set of things you must do, it is just some ideas that you can consider to do as a team. And when I’m talking about team here, most of my experiences are with small teams, like ten people or something like that. So one thing that I talk about in the book is, for example, a code review. And I think there are lots of good reasons for why you would like to have code reviews. But then we often run into this problem that when people try it out, they say, well, yeah, but you know, if we submit something for a review we have to wait three or four days before someone will actually pick it up and do the review. So that’s not really efficient. So one of the things you might actually do is that, lots of teams already have a little bit of rhythm to their day, lots of teams, for example, do a data standup. So some of the ideas in that chapter is just to say, well, you could also have another part of that daily team rhythm where you say, well, we set aside particular parts of the day to do reviews. A review in my opinion is something that all team members do on a regular basis. It’s not one gatekeeper who sits and says what can and can’t go in. You want other people, you want your peers to look through what you wrote so that they can verify whether it’s readable or not. So one idea is, for example, you can say just the hour before you go to lunch or the half hour before you go to lunch, you could do reviews. So each person takes a different review. Or maybe just when you come back from lunch or something like that. But just find some time where you can agree on this is when we do these things. For example, like code reviews. Because my experience is that if you can get people to do regular code reviews and everyone does them, then you can often have a review cadence where you wait one or two hours maybe, and then you get a review result. And then, while you’re waiting for the review, you do a review yourself. So it goes both ways. So that’s one thing you do. And then there are some other rhythms you can do on maybe a weekly or a monthly basis. I talk a little bit about checklists in the book as well. And one of the things that I’ve noticed is that you have to be a little bit systematic about certain things that need to be done in the code base because otherwise everyone would forget how to do them. So one example is the updating dependencies. Every code base today comes with lots of dependencies. It doesn’t really matter whether it’s a JavaScript or with npm or in C#. You have newgit and so on. And you can’t go and update dependencies all the time because with certain environments at least you would basically be doing nothing else than updating dependencies all the time, which is probably too frequent. But you can also fall too far behind. I’ve seen code bases where they haven’t updated the dependencies in three or four years. And that now means that they can’t update the dependencies anymore because now that suddenly becomes a major undertaking because there’s so many breaking changes in doing these updates. So if you have some sort of team rhythm that’s already centered around doing something every week or something every month, you might want to consider making that part of the team rhythm. So for example, not that I recommend that, but if you’re doing Scrum and you’re doing two-week sprints, for example, in Scrum, it might be a good idea to say, well, when we start a new sprint one of the first things that needs to happen is to update dependencies. And again, this is just a suggestion or an idea for inspiration. So if you’re going to identify something else where you say that would actually be a really good idea to do on a semi-regular basis, but we should remember to do this. That’s something to just be explicit about.

Stefan Tilkov: Makes perfect sense. Okay. So those were just three topics that we picked. There’s a whole ton more in the book, which I can thoroughly recommend. I’ve found it to be a great recommendation for people who are maybe on the boundary of becoming from a somewhat experienced to a more experienced engineer, if we want to use that word. So it maybe accelerates you a bit, maybe the two titles “Accelerate” and “Sustain” or acceleration/sustainability also pertain to people’s careers while they’re absorbing this stuff in here. I like that metaphor for that as well. So a strong recommendation, we will definitely put, of course, a link to the book into the show notes. Typically at the end of the show, we ask for recommendations for other resources. I noticed that you have a very extensive bibliography and lots of references in the book. So I think that’s probably what you would recommend, I guess.

Mark Seemann: True.

Stefan Tilkov: It’s been a pleasure to have you on the show. Do you have any famous last words that you want to add when we say goodbye?

Mark Seemann: Well, obviously I hope that people would pick the book up and give it a chance. But you can also go and visit the blog of mine, blog.ploeh.dk, which I’ve been writing on for 15 years now. It’s completely free. So I don’t want you to think that this is just a sales push… you can always just go to the blog…

Stefan Tilkov: An occasional sales push is perfectly fine, you don’t need to worry about that.

Mark Seemann: Yeah yeah, but there’s lots of free material as well.

Stefan Tilkov: I can definitely recommend the blog as well.

Mark Seemann: And we just talked a little bit before we started recording here about conferences. I’ll probably be touring around with the NDC conferences this year, if everything goes according to plan. So I hope to see some people again in 2022.

Stefan Tilkov: Hope to run into you again at one of the next conferences. Thanks again for being on the show. It was awesome. And thanks to our listeners for listening. And until next time. Bye-bye.