Crafting Code Podcast
$ cd episodes/003-two-conversations-pass-in-the-night
~/podcast/episodes/003-two-conversations-pass-in-the-night $ ls -1a ~/podcast/episodes/003-two-conversations-pass-in-the-night $ cat episode-summary.txtCoding is a specialized skill where we learn to communicate with a machine. Unfortunately, this can often blind us to the fact that crafting code involves a lot of communication with humans. Writing clean, expressive code communicates with other coders. Communicating well with non-coders helps us understand business needs so we can write the right code.
~/podcast/episodes/003-two-conversations-pass-in-the-night $ cat references.txt- Clean Code. Robert C. Martin.
- Domain-Driven Design. Eric Evans.
- Naming as a Process. Arlo Belshee.
- Design Patterns: Elements of Reusable Object-Oriented Software. Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.
$ cat transcript.txt
[00:00:00] Allan Stewart: Welcome to Episode 3 of the Crafting Code Podcast, where we discuss the importance of doing the right thing at the right time and with the right tools. I'm Allan Stewart, a software architect, and lately I've been thinking about the problem of batch sizes and Brandon Sanderson novels.
[00:00:16] Dave Adsit: I'm Dave Adsit, CTO, and lately I've been thinking about coupling, cohesion, flow of value, and low-code solutions across a company.
[00:00:26] Matt Baker: Matt Baker, I'm Matt Baker. I'm pretty sure I work in software. Some days I'm not sure. Lately I've been thinking about the Kafka Wire protocol and using fast feedback loops to engineer a game I've been playing called Rocket League.
[00:00:40] Allan Stewart: So our title, episode title for today is Two Conversations Pass in the Night. We'll be talking about communication and how communication relates to crafting code. As we look at the Software Craftsmanship Manifesto, it definitely talks about some things that require communication. Well-crafted software, right? The code itself can communicate something. We want to work in a community of professionals and have productive partnerships. All of these things require some communication, but it's not always as simple as we wish it were, hence the title. So we're going to kick things off by talking about writing code for humans. So if we want to write some code, a lot of the time, especially when we're first learning how to code, it's all about syntax. It's all about getting the computer to do what we want. And so we tend to think about code as communicating with the machine, getting the machine to do what we want it to do. But why would we want to communicate with humans through code? Yeah, it's an interesting question. my
[00:01:50] Matt Baker: my mind immediately went to a place that's not necessarily the question you were asking but um, I, I'm thinking about early on when I was writing software, one of the most important important things to me was terse syntax. The shorter I could make something or the more compressed I could make something, the better. So as you started talking about writing code for humans, now in my career, I look at things like terse syntax is definitely not optimizing for
[00:02:27] Dave Adsit: humans. Yeah, a lot of the platitudes that we've heard, or the quips about writing code, kind of flashed through my head. But I think at the end of the day, I'm tired of producing legacy code. I want people who come behind me to not resent me for the things I did to their code base. So I would like it if they could see the code and understand, at the very least, understand the intent, even if the code didn't do what it was supposed to do. So I think that's the big thing for me these days when it comes to writing code for humans.
[00:03:15] Allan Stewart: One of my favorite quotes from Martin Fowler says, says, "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." That, kind of, at the turning point of my career, right around the time when I was first learning about what it meant to be professional and write good code, write clean code. I came across this quote in his refactoring book. And it's really stuck with me because code Code tends to get read a lot more than you write it the first time. When you're writing it, you're in one frame of mind, but when you read it, you're in a different frame of mind. So even if the only other human that reads it is yourself down the road, it can make a huge difference if you have communicated your ideas clearly. And if you're working in a team, then it's all the more important that they understand what it was that your code was doing.
[00:04:17] Matt Baker: I think when you, when you talk about communicating clearly or writing code that humans can understand, the word that comes to mind for me is plain. Express yourself in code plainly. Avoid the fancy syntax sugar. Avoid the, you know, Kung Fu coding. Try and make it as plain as possible. I'm thinking about that cartoon where it shows an engineer over the arc of their career. And at the beginning, they're asked to write a Hello World program and they write it in console.log Hello World. And then five years into their career, they've written, like, a mother object factory that produces, like, a writer reader streamer that, you know, and it's a few underlines of code. And then at year 10, they're back to the console.log Hello World. And I think we all go through that progression and right now for me I'm just at plane, like, how can I write the simplest, plainest code possible, you know, and I've started to really value that more than I value some, like I was saying, terse syntax, or maybe some kung fu code that, you know, takes you a while to untangle but
[00:05:24] Dave Adsit: is intellectually impressive. Yeah, I really appreciate that. I think that one of the places is where I've tripped myself and others up many times in the past is by trying to use clever ways of communicating inside of a code base instead of, I don't even know, examples are hard to come by these days because I've completely given up the habit, but, you know, naming something after a Star Trek character because that's what I thought of in the moment, or this part of the the code kind of reminds me of that time I was hiking. And so I'm going to name it after the hike that I was on. None of that communicates to anyone else, including me a month later. And so now I'm just like, VAR board equals new board. Not because I'm bored, but game boards come into a lot of my coding these days.
[00:06:25] Matt Baker: Well, I think you could say also var, you know, file reader equals new reader, or var, like, HTTP response from payment API. Like, these are...
[00:06:39] Dave Adsit: Those are names that I would understand a week later. That's right. Yeah.
[00:06:43] Matt Baker: And I also think that they are names that are constantly abbreviated. Like, I don't know exactly how to categorize those, but depending on the code base you're looking in, you might see, like, one or two letter variables holding those, or, like, R for response. And you know, I going back to that plane thing, I definitely appreciate a code base where they've, they don't care about being a little verbose if it means that they can communicate better.
[00:07:06] Dave Adsit: Well, it all gets compiled out anyway, right? Like, the computer doesn't care what you name the variables anymore. And if you're using any kind of modern tooling, the tooling is going to help you type the long variable name in the context where it's relevant.
[00:07:23] Allan Stewart: And again, even if you do have to spend some extra keystrokes because you added some additional letters, some additional context, it's going to be worth it because you're going to read that a lot more. And the more that your tooling helps you, the more that you can focus in on what is it that that I'm trying to accomplish with this code, rather than some kind of Hungarian notation of the types of all of my variables and how many, you know, bytes of memory they've all allocated and all this other stuff, which was important at one time, especially when we didn't have the tooling. But with what we have now, we can really focus on the domain of the problem rather than anything else. And that's hard enough, right? Right? There's the famous Phil Karlton quote, "There are only two hard things in computer science, cache and validation and naming things." And I found that to be so true. Like, there'll be times where I'm just like, okay, here, I'm, I'm writing this code. And I know what I want it to do. But I don't know what it's called. What even is this thing that I'm creating?
[00:08:32] Matt Baker: What do you do in those
[00:08:33] Allan Stewart: those moments? What do you do? Oh, that's a good question. Because I was going to say, you know, why is it? Why is it so hard sometimes to name things? But it's kind of a fundamental thing. And so what I do is give it the best name that I can in the moment and move on and hope that before I'm done, because done for me includes some measure of refactoring and going back and making sure that it works well, that I will discover what it was that I was naming in the the first place. One of my coworkers put me onto a great article where they talk about naming things applesauce or other similarly, obviously wrong names. As long as you're not working for Del Monte, then it's probably not actually a variable for actual applesauce. And that's a clue to other people. "Okay, this is wrong and broken. Please figure out what this really is and fix it."
[00:09:25] Matt Baker: it, this code is not yet done. I, uh, I've even named variables like, "I seriously can't be bothered right now," like, and you're just like, "I can't think about this. I'll come back." But for the same reason, like
[00:09:38] Dave Adsit: that, that'll catch my eye at some point. Yeah, in, in the way that I or a or r won't. Exactly, you know, you put a single character as the variable name and you might think that you meant it.
[00:09:53] Allan Stewart: Or you just gloss over it, right? Because it was just that one character. And I, it was probably like an index or something. X, it was probably just like a lambda expression. And who even cares? Until it turns out that you did actually care.
[00:10:11] Matt Baker: Yeah, I'm to the point now where I hesitate to even use I, the variable name I in for loops, where I think if there's one place in computer science, or at least in computer programming, where a single letter variable is acceptable, it's a for loop, but even there I'm pulling back on that and saying I should be able to say what I'm looping over, even if it is index, you know. I, I have done some of the mathematical
[00:10:41] Dave Adsit: coding where it felt like the most correct domain language for the solution was to use the characters characters from the way the problem is written by the experts. And a lot of times it's very simplified. On the other hand, I don't know how to type a theta on my standard ASCII keyboard. So sometimes I don't do that either. Sometimes I'll expand those out. I'm like, but what does this character mean? And use that instead, because that helps me remember what they're talking about when they're doing the fancy math or whatever.
[00:11:20] Matt Baker: What's that one, is it Prolog? The programming language that has sort of cryptic syntax? That's what I'm thinking about like... Prolog does. ...theorems expressed in a very interesting language. Yeah, for sure.
[00:11:35] Dave Adsit: I guess that was actually one of the things that was considered an advantage of early Scala is is that you could use Unicode characters to represent functions in the code. And then later people were like, "Yeah, but don't. We tried it and we could never reproduce or read the code that we'd written."
[00:12:02] Matt Baker: It's just sort of a, it's a one and done. It's like immutable coding. Like you write it one time, if you need it again, you have to write it again.
[00:12:12] Dave Adsit: That seems fair.
[00:12:13] Allan Stewart: Going back to this idea that naming things is hard. I think part of it is because, you know, we're trying to figure out what is going on in the code, what we're trying to accomplish. Sometimes we're not as clear with the domain as we should be, but sometimes it's just, there's these lies that creep in, and they're unintentional. We get in there and we say, "Oh yeah, this is account ID or user ID." And we didn't realize until later that it mattered a lot whether it was, you know, what kind of a user was that your customer? Was it your internal admin? Was it somebody else completely? And as we start figuring out what these things are, we get rid of the lies. Another one of the really big lies, I think, are side effects. We get in there and these are lies that, that the code tells us because Because when you're in the code, you're writing that function, you can plainly see that it writes to the database. But then you go step outside that class and you're somewhere else in the code and it says, you know, "Calculate foo." And you're like, "Oh, great, I'm going to calculate foo," never realizing that it's also saving that to the database.
[00:13:27] Dave Adsit: And emailing a copy to your accountant.
[00:13:32] Allan Stewart: So this takes us to kind of a related idea that we can just touch on for a minute. Clean code. One of the concepts of writing clean code is that you're creating very legible, readable, understandable code. So I'd like to ask the two of you, what does that mean to you? Like, in practical terms, if you're going to sit down and write some code, or if you're thrown into a code base that you haven't seen before, how do you tell? What does it mean to you whether whether that code is clean or not clean?
[00:14:08] Matt Baker: I think there are a large list of tactics that you can employ and their footprints will be all over a code base that I would call clean. Some examples that come to mind, maybe short functions, classes that try and do one thing. We could go on and on, I guess, about all the tactics. But the way lately I've been thinking about it, I'm trying to think about it as simple is a conversation. My communication is only as good as you understand me. So if I say something and you don't understand, regardless of who's at fault, I failed to communicate. Similarly, if someone can't understand my code, I would not call it clean code, regardless of how perfect it is. If it doesn't communicate the idea, then you fail to do one of the things you were trying to to do. So, you know, as, as of late, I've been trying to look at it as well. Does, can someone read this and understand my intent? And if so, I know that's clean code.
[00:15:08] Dave Adsit: I think for me, my favorite definition of clean code comes right out of the book of the same name, which is the code pretty much does what you expect. So you read it and then you read it deeper and you read it deeper and And you're like, "Oh yeah, it did what it said all along." To me, that's clean code. There are some other things that I look for. I really like the idea that if you have clean code, when you decide to improve it and you start applying your refactorings, you pretty much end up back where you started. It. You had an idea of how to improve it, but then you went kind of around in a big circle. And now the code is the same, but slightly different. And you are different in that you understand why it was the way it was to begin with.
[00:16:09] Matt Baker: I love that. I love that. What goes through my mind is, your relationship with the code changed. Code didn't change. Your understanding Understanding of the code changed.
[00:16:20] Dave Adsit: When I've gone through some of those cycles at the end, I just do a Git reset hard because I realized that I didn't do anything that improved the code in that time. And I may through my manipulations have introduced problems, but now I understand why it is. And so I just move on.
[00:16:41] Allan Stewart: Yeah, I really like finding those code bases where you have that consistency, kind of that elegant nature of the code where it is what it says on the label. It does exactly what you expect it to. And when you need to work in that code, you're able to go and make changes with relative ease. You can understand what it's doing. You can understand the gotchas. There isn't this interconnected, you know, I often think about it like this spider web that goes throughout the code. And if you pull on one little part of it, then it causes a ripple effect way off into some other part of the code. And whenever that happens, that level of coupling, it's just a nightmare, really hard to work with. And you get afraid of changing anything. And clean code is easy to change. So I suppose that there's probably something about testing in there, too, because testing is definitely an enabler for changing code, for building confidence and whatnot.
[00:17:43] Dave Adsit: about. That makes me think testing is a skill and coding is a skill. And one of the things that you said, Matt, is that when someone else looks at the code, it communicates to them effectively. Is it reasonable to think that there are different skill levels of code base? Maybe this code base is too complex for your current skill level. This is a black diamond skill code base, and you need to go ski back over here on the, what is it, a blue circle or something, you need to go back to the beginner slopes because this code base is too hard for what you can do now. Is that a sign of a failure of the developer to rise to the needs of the code base? Or is that a sign that the previous developer failed to simplify the code base sufficiently that the new person could understand it?
[00:18:43] Matt Baker: No, it probably just depends. My mind goes to, I'm taking the model you're presenting and applying it to books. Let's say literature. If you're reading a really advanced book on some topic and you've never studied it before, so you don't understand it, I don't think it would be fair to say that the book was bad at communicating. I think maybe, you know, it could also be fair to say that you don't speak the language, so you don't understand what it's telling you. So I think it's a fair point, Dave. There's this, like, "you have to be this tall to ride" element to it where someone might not understand a code base. I'm reaching for a concrete example. One of the first ones I go to is something like a bit mask. I don't think that, you know, a novice engineer is going to be able to understand why you're, what a bit mask is and how it's serving a particular code base, or at least that's been my experience. And I was one of those people. And so that's an example in my mind where a bit mask could be a great expression of the problem domain, but it is a, you know, it's harder to understand than declaring a string, and it could be something that someone might not understand. I don't think it would be fair to say that that code wasn't clean.
[00:20:00] Dave Adsit: I think the same could be said for certain patterns and practices, you know, depending on whether you consider dependency injection, a pattern or a practice, test over in development is definitely a practice that we apply, which has its own collections of patterns. And so if you don't understand the tests and you don't understand the dependency management structure, that code is going to be super foreign to your current level of understanding, but that doesn't mean that it isn't good or clean code.
[00:20:30] Allan Stewart: Yeah, it makes me think that there's probably often a happy middle ground for most applications. You know, there's going to be some parts of the domain that are more tricky, or there's going to be some parts of the code base, like just some architectural decisions that were made. Like, this is how we do the dependency injection, or we always put our tests over here. Just even certain patterns, like we use workflows and repositories. And in this part of the code we use a strategy pattern, and I think if you do a good job of communicating that it can be kind of like those signs on, on your ski slope there, Dave, where you say, "Yeah, this part of the code base is black diamond, so we're putting up a big sign and telling you beware, here there be dragons. This is the place to be careful." But I think it's more fair to say that most of the time, software projects are more like the entire ski resort than a single run. And when you get there, you know, maybe even if you're an experienced skier, maybe it's best that you warm up a little bit on the slopes. Maybe don't tackle the quadruple black diamond, whatever, I don't ski, clearly, difficult slope. Yeah, you know, the ones with the slaloms and the jump that they do at the Olympics. Maybe that's not where you should start, even as an expert skier, when you're first coming to the resort. And if you're very first coming to a code base, the code base might be clean. And one of the ways you can tell is you can say, "Okay, this is where I can warm up." These are the signposts that let me know what's up in the different parts of the code base.
[00:22:11] Dave Adsit: I actually worked in a code base that had comments at the top of some files that said something to the effect of not a drop code, which told me two things, or maybe more. First, this code was important enough that you should never try to work on it when you had been drinking, which told me that one of my co-workers sometimes worked on the code while he was drinking, which was in and of itself interesting. So, yeah, I've actually seen that in practice. I think the code that was specifically not a drop code was all around payment collection and processing, which made me feel good because I didn't want any of that code to be intoxicated.
[00:23:00] Matt Baker: You know, I'm thinking of the ball marker. I think there's also an aspect of observing the, I'm going to say the culture in the code. We talked about testing. I think a code base, one of the things that we'll have is a statement on whether or not it's been written using TDD. I think you can see that in the testability of components. And I believe that if you've worked in a code base that wasn't written with TDD and you've tried, you've experienced how hard that is. And if you've had a code base that's TDD and had someone write code in it, not doing TDD, that to me feels like a, going back to the skiing metaphor, you remember that game on the old Windows PCs, the abominable snowman that would be chasing the skier? I feel like the person that goes into a TDD code base and doesn't do TDD is that snowman. But, but I, I, uh, I just, I, let's just keep the ski metaphor going, I guess. Um, no, but what I want to say is sometimes a code base and the way it is written should change the way you might approach a problem. In cases like with TDD, if you don't do TDD but the code base does, you should do TDD. Similarly, if, if the code has a comment above every file describing the file, maybe you should consider or including that comment for the file, even if you're vehemently anti-comments because there's something to be said for consistency when we talk about clean code.
[00:24:32] Dave Adsit: It makes it a lot easier to write that regex that cleans all those comments out of the entire code base. You would have never done anything like that. I have never done anything like that
[00:24:44] Allan Stewart: as far as anyone can prove. So as we've been talking, we've been touching on a related topic of communicating with other people, right? So we've been focused on, like, how does that look in code? But the importance is communicating with other people. Maybe it's our future self, but more often it's people within your team, within your business. If we are talking past each other, if we're not connecting, it really makes it hard to get anything done. It makes it really easy within your code project for people to come in and today I make one change, and then, Matt, you make a change the next day that kind of undoes something that I did. And then Dave comes along and just deletes the whole file because his reg checks was wrong. And, you know, and we're all having these kind of competing things because we're either not communicating or not communicating well enough that we're understanding each other.
[00:25:41] Matt Baker: I think there's lots of ways in which communicating shows up in writing software. One of the ones that's sticking out to me right now is engineer to engineer. I know when I've been in mobs and pairs, if you have people that are very ideologically opposed, you can kind of reach stalemate sometimes about, "No, we have to use Angular, we have to use React, or we have to use X pattern, and we have to use Y pattern." And one of the things that's sticking out to me right now is the ability to navigate those conversations. If you can't, you can end end up with a, you know, a code base that's a bit schizophrenic where you see both people trying to shoehorn in their, their pattern. God forbid they're doing, like, they're coding independently and just racing one another. You know, even if they're coding together, I think you can see maybe disagreements that engineers are having.
[00:26:27] Dave Adsit: Yeah. Yeah. I, I think that this is actually one of the hardest things is because we have this habit in our industry of talking about engineering Engineering and the business. Engineering is very much part of the business. Without engineering, a lot of our businesses would not exist. And without, well, but I'm going to say the reverse too. Without the people doing marketing and sales and accounting and HR, most of what we build as engineers would be pointless. Good point. In a business context. So we are all in the business, but one of the things that I've seen a lot is just, there's some kind of impedance mismatch between the people writing code and the people not writing code. We talk about the world in a different way. We use the same words with different definitions. Just communication is very challenging across that divide in particular. So much so that we've created a job in our industry, the product manager, who is supposed to translate somehow from business ease to programmers ease and back and forth across those two languages. And I think that that creates one of the big challenges that we see, right, is that we are not speaking the same language with one another in a lot of cases. One of the guys that I used to work with was into meditation and mindfulness and thinking about what he could do at any moment to fix a problem. And he told me once that the problem with communicating with another person is that it has to go through four phases. There's what you think, and then there's the outbound filter that your thoughts get translated through into language. And then the person who hears you parses that language through their own set of filters, and that creates a thought in their head. And very often, maybe every time, what you had in your head and what they have in their head don't match. And so that is where we have, that's where communication has to be robust enough that we are aligned around what we're doing, even if what's in my head and what's in your head don't actually perfectly match.
[00:29:08] Matt Baker: I think there's some tricks, some tips and tricks you can use to navigate some of that. One comes to mind from Linda Rising. I don't know if she came up with this or she just passed it along in a talk, but she spoke about when you have two people in the situation, like what you've just described, Dave, one tactic you can use to ensure successful communication is to have, you know, person A say back to person be what they hear person be saying until person be is satisfied. That they understand, and then you can flip and do the reverse. Not too similar from, like, or not too different from, like, the way maybe our TCP protocols work. You know, "Did you hear me?" "Tell me what you heard." "Okay." "Yes, that's right." You know, and then just sit and do that constant exchange.
[00:29:52] Dave Adsit: Yeah, that active listening and replay. And it's more time consuming. Communicating effectively is more time consuming than just firing off a sentence and walking out of the room and assuming that the people who were you left behind will definitely understand what you did and what you said and what you meant and build the thing that you intended as opposed to ignoring you and going back to what they were doing anyway. So I think a lot of this comes back to the idea from Domain-Driven Design of the ubiquitous language, which is to take the language that you speak and put it in the code, and take the the language that the engineering team speaks and align it with the language that the people who are not in the engineering team speak.
[00:30:40] Matt Baker: So do you mean that literally, Dave? Like, if my engineer said, or, excuse me, if someone in sales said, "I just sold the blue component, I can't think of a better name," you would expect the code to say blue component. And that example, you would expect to be pervasive in the code?
[00:30:57] Dave Adsit: Yes, I would expect. So language is something that evolves, and it's not something that is, with a couple of notable exceptions, it's not something created by a person and then distributed. Language evolves as it is used. And so as I'm talking to the salesperson about the blue component, I would expect us to come to an understanding that makes sense from a technical perspective and from a sales perspective, and ideally also from a marketing and accounting perspective as well. But at the very least, at the very least, I want my product manager and my engineers talking the same language. I would like to see that beyond the team, but that's not always possible or reasonable. Sometimes you're so disconnected from different different parts of your organization that you, A, it's irrelevant, and B, you don't have any opportunity to coalesce around the language. I think I want to say that there's a warning there that if you are trying to create a unified domain model for the whole company, you are doing ubiquitous language wrong. Because ubiquitous language is bounded by a context. Can we talk about why?
[00:32:17] Matt Baker: Can we take a minute and talk about why that's true?
[00:32:21] Allan Stewart: Yeah. Oh, definitely. I was just getting to this too, right? Because this is where the other really useful thing out of Domain-Driven Design, the bounded context really comes in and shines.
[00:32:32] Dave Adsit: First of all, no one has ever successfully shipped an enterprise data model. And if they said they did, it's because they didn't know how much code existed that ignored the enterprise architects in their ivory tower.
[00:32:44] Matt Baker: Dave, will you state your phone number so people that want to prove you wrong can text you?
[00:32:50] Dave Adsit: You know what? They could, but I won't believe them because I've worked at all of those places that said they had it. And I was in the code and I knew it was a lie. I will only state my phone number if they state their phone number so that the people who actually work on those systems can call and tell me that I was right.
[00:33:08] Allan Stewart: I think they just look it up in the person record, because every person will have a phone number at all times in the unified model.
[00:33:17] Dave Adsit: Well, a collection of phone numbers with types. Oh, for sure. Right? So, I mean, and a lot of that talks to what is clean code? It's code that does what you expect, and it doesn't have a bunch of extra nonsense. And a lot of these enterprise data models and company-wide unified modeling schemes suffer from that. They're not focused on the problem at hand, the solution we're delivering for it, and they're not focused on the people building that problem, building that solution for that problem and delivering it to users.
[00:33:49] Matt Baker: Yeah, I agree. So if you take, let's take the extreme here. One, you know, enterprise data model for the whole company. It sounds like we all agree that's a bad idea. And a way to approach solving it is a bounded context, or you create a series of boundaries in the system. And that does something. So I'm wondering if we can talk about what's actually happening. Because I don't disagree that introducing bounded context is the correct solution to avoid the enterprise data model. But I want to talk about why.
[00:34:22] Allan Stewart: I think it comes down to the context part of it, because language exists within a context. At least in English, there are so many overloads for pretty much everything you say. You can't hardly speak a sentence without offending somebody because there's an overload of one of the words that you use that was, you know, very, you know, triggering for somebody, and yet somehow we have to, to move on. And there are definitions. I have a good friend that I would talk with at length on many occasions where he would write, like, a blog post or something and ask me to review it, and I would review it and I'd say, "Okay, this is what you wrote, but I think this is what you meant." He's like, "Oh yeah, well, if you look up the definition for that word, definition three or four or seven is the one that he was thinking of." And I was like, "Yeah, but I'm not sure everybody's going to be thinking about it that way." Yeah, so you got to have that context. Just, I mean, and that's just kind of for spoken language in general, having that context, and if you're solving a specific problem. If you're in code where the code is very exacting, it's very technical, you need to be able to express things in that context, which might mean that for you, something as simple as a user, you know, it might have many different manifestations, or your product blue, that's going to mean something different to different parts. You know, shipping, they care about, well, product blue means that it's going to weigh 16 pounds and we have to pay this much in shipping. Meanwhile, somebody else doesn't care at all about that because they care about, like, how much markup is there and how much, you know, percentage margins we can get on, on blue product. Yeah, I, I'm thinking
[00:36:13] Matt Baker: about, a, an example, and I'm going to try this out and it makes sense in my head. Let's, but I think what Dave said about all the filters being true, so let's, let's see how it goes. You know, if you you have a store that sells baseball bats, and you write software for that, you're going to have something in there called a bat, probably. And it's a baseball bat, it makes sense. If you also try to open maybe a sister company using the same software that sold, I don't know, creatures that fly in the night, you're going to have bat in there as well. And it's sure not going to be a wood thing that hits balls anymore. And so you're going to have to clarify, because you chose to to combine two disparate domains with one piece of software, you now have an overload of bat. And it's really just a side effect of combining two domains that probably didn't have any business going together anyway. So coming back to the enterprise data model, I wonder if one of the reasons it suffers is you're just unnecessarily polluting domains. You're just saying you can all go together and not maybe paying homage to the fact that introducing one domain into another other affects them both. And one of the things it can do is overload terms and introduce complexity that you then have to solve. And so when we bound, we're saying there's a fixed set of things in here that cohesion in the domain is pulling together. And we're going to let that just exist on its own. And some other ones will develop and we'll let those exist on their own. And we will very gingerly integrate them only where we absolutely need to.
[00:37:44] Dave Adsit: Yeah, especially for the shipping department who doesn't want to have to try to stuff flying mammals inside of a tube. So obviously the solution there is to create a unit of inventory, because as a salesperson, the number one thing that you want to do is go out to customers and offer them units of inventory. "How many units of inventory can I sign you up for today?" Sounds an awful lot like the sales pitch I I get from seven-year-olds during candy bar season for the PTA fundraisers. It's not how we communicate effectively. It's not how we, I guess one of the things that I'm thinking about is that a lot of what makes us human and makes us work well is the fact that we bring an emotional or creative element into the logical side, right? So we bring that, we bring that creativity, we bring that emotion into the code. And so there's more than just the bits when it comes to communicating with people. I want to evoke an image in your mind when you read the code, when you read the specification, when you look at the user experience design that was presented by the UX designer. I especially want to do that if I'm a client success manager and something is going wrong for a customer and I need help from the engineering team. I would like you to come along with me on an emotional journey. And if we're not communicating effectively, then we're not going to be able to solve those business problems well on an ongoing basis. I think a lot of that comes back to the idea of terminology. There's a lot of specific terminology that we use in different fields. We have a bunch of things in engineering that we use. Like, earlier Matt was talking about a bit mask, and it would not surprise me if a large number of the engineers who hear you say that don't know what you're talking about, but it would surprise me greatly if anybody outside of engineering knew
[00:39:59] Allan Stewart: what a bit mask is. Agreed, terminology can also be, the flip side of the coin is that it can be a huge enabler. We talk about the problems that happen when you're not communicating. If you're saying the same words, but they're meaning different things, or everybody has a different name for the same thing, then it's really hard to know what anybody's talking about and to communicate clearly and solve that business problem. But that flip side is that when you do know the terminology, you can go a lot faster. So I'm thinking about some of the times when I've done pair programming with you, Dave, we can talk because we have worked together for a really long time. We can talk in a lot of shorthand and just say, "Oh, I want to do something kind of like this." And we use a couple terms and we know, or at least apparently we know what each other is saying because we seem to be pretty happy with the result that comes out. You can move really quickly with that. I really like pair and mob programming for this because down at the code level, that gets you thinking about how do I talk about this thing? For a long time as a coder, I just wrote code solo. And I learned a bunch of patterns and I learned some things, but I didn't know how to talk about them. In my brain, I knew what the syntax was and how to express it in code. But I couldn't tell somebody, you know, "What's the difference between a parameter and a field?" "What do you mean by injection?" There's these terms that we can use, and once people are on the same page, once that, once we've had the opportunity to talk about code and learn how to express ourselves well, then suddenly we can go really fast because it's not, "Well, do you mean something like this, or do you mean something like that?" Or you say something and they start typing in the code and you're like, "No, no, no, that's that's not what I meant." In the worst cases you devolve into, "No, no, what I mean is private class foo." And you're telling them exactly what to type, which is very inefficient.
[00:42:07] Dave Adsit: Yeah. I like that a lot. There's, I can think of a lot of times where you and I have just talked about a handful of patterns that we intend to tie together. And it represents a whole day's worth of coding to test drive it out properly and ensure that it covers all of the things that we we wanted. But the design session was, "I think we should tie this pattern to that pattern to that pattern." And you would say, "No, but this pattern instead of that one." I'm like, "Oh yeah, that makes sense." Right. But that only comes because of time spent learning the specialized language of software development. Time spent working together to understand and building, bringing our own knowledge of patterns and practices and then applying it by saying, "I know this software pattern. I want to use this this way." And you say, "Well, I've heard that software pattern is like this." And then we come to a mutual understanding of the pattern, and then we can use the pattern to talk about it, the thing together.
[00:43:06] Allan Stewart: Absolutely. And that applies not just for writing code, but the same things, I feel like, apply at the business level where we are talking with other departments, where we are figuring out what is it that we should build? What is our company strategy, when you're on the same page with the ubiquitous language, you're talking about the same things in the same way. And you're understanding when you mean the bat that is a living mammal versus the wooden stick, then you go really fast.
[00:43:33] Matt Baker: I think that if you pair a mob with someone or a set of someone's enough, you can get to the point where you can say things like, "Do the thing," and they'll know what you mean. Like, they'll be able to anticipate where you're going and they And you can really cruise like you're both talking about at that point. Then it's just a matter of how fast can you get the keys out of the keyboard. Those are very cool moments in programming when you get to that point with someone.
[00:43:59] Dave Adsit: And in case anybody thinks that "do the thing" is an exaggeration. No, you can literally say, "Do the thing." No, like we did in that one the other day. And then they, "Oh, yeah." Yeah. And then they write the code exactly what you intended for them to write. And it looks like magic to anybody outside of the group. Someone did tell me to hurry and make fewer typos today while coding in front of a group. And I wasn't sure how I could do both at the same time or even either alone.
[00:44:36] Allan Stewart: Well, to be fair, you were the one setting a two minute timer every time that you did some code.
[00:44:41] Dave Adsit: Well, there were constraints. There were constraints, to be honest.
[00:44:48] Matt Baker: We're going to have to do an episode about one to be tuned into later. We'll have to do an episode about interesting programming practices like two-minute or five-minute increments. There's some fun things there.
[00:45:00] Dave Adsit: Yeah. And why every programmer should know the rules to Conway's Game of Life. Also, as an example of poor communication, if you introduce an activity to a mixed group of engineers and not engineers, and you refer to "Game of Life," the engineers may in fact picture Conway's Game of Life, and the not engineers may in fact picture a board game in a white box with little cars and people that drive. And you will have several minutes of confusion trying to understand what the other person is talking about when they say, "We should definitely go to college." And the engineers say, "We already went."
[00:45:51] Allan Stewart: Another area where I feel like clear communication and not talking past each other is super important is with the times where, as technologists, we say yes or no, or worst of all, give an estimation. Because these are opportunities for a lot of talking at cross purposes. If you say, "Yes, this is possible," did the person interpret that as, "Okay, we're going to do it"? If you give an estimation, is that a promise? Oh, well, "You said it would only take about two days worth of work. And two days later, they come back and like, hey, why have you missed the deadline?"
[00:46:32] Dave Adsit: My favorite version of that is, "This would take probably two days." And two days later, they come back and ask how it's going. And you have to to explain that it will take approximately two days in six months when it comes to the front of a queue that is a mile long.
[00:46:54] Matt Baker: I agree. And I, you know, I don't blame them. I think that if I went into a mechanic and they looked at my car and said, "Yeah, about three days." And I didn't hear from them for two weeks, you know, or I called them after three days and they're like, "What are you kidding me? This is going to take a month." Like, I would feel a little bit like I missed missed something, you know. And on this point, for me, I've gotten to the, now when people, when I have these conversations, yes, no, estimation conversations with people, at the end of them, I try and recap by saying, "I want to say back to you exactly what I think I've agreed to is this. Is this what you understand?" You know, and then I get a yes or no from them, because if you don't, you just, there's all these unmet expectations that are going back to Allan's comment earlier, their side effects maybe of the conversation.
[00:47:42] Dave Adsit: Well, and I think we should probably put a pin in this as well, but when it comes to estimation, there are so many problems with it. And rather than asking someone how long something's going to take, I've gotten to the point now, and maybe this is just executive speak, but I've gotten to the point now where I say, "It is worth this many days of your effort for you to do something on this problem." That's smart. I think that's very smart. And then at the end of that many days, I can decide if it's worth having them continue or not. Yes. Agreed. But I think we should probably push that off because while that does have to do with effective communication and some perspective. It's much more tied up into process and culture and ways of working. And I think the key thing to think about today when it comes to estimation is that estimation is where we reveal that every engineer is truly a grand optimist. Because every engineer, when asked for an estimate, will give you their best case scenario. Maybe they're better than best case scenario, even knowing after observing the world for however many years they are alive, that their best case scenario very rarely ever happens.
[00:49:07] Matt Baker: Yeah. On that point, one of my pet peeves is when someone says, "Yeah, I typically just double or sometimes triple the estimates my engineers give me." And I don't know that I fully understand why that bothers me so much, but something you said, Dave, brought it to my mind. And it's just the most annoying thing to me. I just, if someone's doing that to me, I'm going to be bothered by it.
[00:49:30] Dave Adsit: I can tell you why that bothers you so much, because that is a great violation of flow efficiency, which we can get into in more detail later. Good call.
[00:49:42] Allan Stewart: I think it's also a question of trust, right? We want to be seen as professionals. And so we want people to take us at our word and not be sandbagging. But the reverse is also a problem because so many times we can estimate something and, or say yes, that this is possible, or no, it's not possible, or this should be easy, or whatever the things are that we say. And then reality creeps in and it's harder than we expected. There's more complexity. The code is more entangled than we had assumed. And suddenly we can't meet that promise. Us. And so being really clear about those things is very important.
[00:50:23] Dave Adsit: Well, so there's two last things I'd like to say around that topic specifically. One is that often yes, no, or an estimate are a poor way of communicating, "Go away and leave me alone before you break my mental model and I have to start over for the day." Because that's an expensive thing for an engineer to do, right? You've built up a mental model. Someone wants to ask you a question and your answer is "Go away." And they keep asking you something and you finally say, "Two weeks," and then they leave. And so you go. I think that that's one of the things that is specifically related to communication. That is one of the things that we get caught up in when it comes to estimation. And I think that the other thing in that space is that we don't communicate the full context text of an estimate. We don't communicate the best case, worst case, and median case for the estimate. And we don't give appropriate feedback when we have adjusted our internal estimate. Like, I get into the code and I know almost immediately, "Oh, my estimate was wrong." I should go tell that person, or I should just dig in and try to keep the original timeline. And that's where it comes back to communication for me is that we need to communicate when context change, when information comes in, when we know more than we did. And that can be hard for a lot of people to revise an estimate.
[00:51:52] Allan Stewart: So in my line of work, kind of the specialization that I've taken on software, I really have enjoyed architecture. And for me, one of the things that comes out of architecture is this idea of the synthesis between, here are the things we can do technically, and here are the things that the business needs. Because if we're not building code that is solving a business problem, then we're going to have trouble. We're going to get to the point where we're just not, we're not making money or we're spending too much money on the wrong things. And so communication becomes a really important issue in there. How do you bridge the gap? How do you let people understand, hey, here is a broad vision of what we want to accomplish and why?
[00:52:43] Dave Adsit: Well, in the absence of any better idea, I get a whiteboard and some markers and start drawing and talking. Sometimes the drawing is related. Sometimes it's not.
[00:52:59] Matt Baker: Yeah, I think a whiteboard is so underappreciated here. I tend to shy away from big architecture drawings. In fact, at this point, I feel like I tend to shy away from architecture drawings altogether because they become lies so fast. You know, it's almost like this is a point in time thing, that point. So, so I like the whiteboard. Another thing I like about the whiteboard is people are right there with you and they can probe your thought process as it's evolving, where, you know, I can't do that if I just give you some PDF. So I know I've always personally appreciated whiteboard sessions when I'm trying to learn a topic from someone or when I'm trying to teach a topic to someone or, you know, Allan, back to your point, trying to explain the architecture of a sufficiently complex system.
[00:53:48] Allan Stewart: Yeah, there's something about visualizing that is really helpful. And there probably are some times where having something a little bit more formal is useful. But more and more, I find myself wanting to just go with a few different shapes, a few boxes and lines that kind of sketch out the idea of what I'm talking about, even if I'm putting it to a document that's going to get shared around. Because some of the more formal things, if I'm going to use UML or architecture diagramming tools, that half-life of their relevancy is so short, it feels like, that it's a full-time job just to keep it up to date.
[00:54:24] Dave Adsit: One of the things I like about having an architectural vision is that it tells us where we're trying to go. It's not necessarily like a representation of how where we are now, but it, it helps us see where we're trying to be, and then gives people the freedom, or it pushes down those decision-making rules so that people can actually make the decisions that get us closer to that as they work in the code. I think important things for me to see in an architectural vision are, where are the boundaries and the interfaces. And then I give people the admonition, "Do the best you can inside your boundary. I don't want to tell you how to build your piece unless you ask. I want you to do the best that you can with what you know, with your specialized knowledge, being very close to the problem and solution." And so I think that that's one of the important things about the a vision, it's hard to communicate. It's even harder to set a vision.
[00:55:32] Allan Stewart: Going along with that, I think that there's a lot of room for communicating through exercises or demonstrations, especially the hands-on type of things where, I mean, we know we're learning as people, educational models are improving and whatnot, that people are going to learn a lot better if they do something hands-on, if they can try it out, if they can give it a go themselves, selves rather than having the professor at the lecture hall telling them about, "Well, if you were to do this, this is what would happen." But that just doesn't stick. And so if you can find exercises that you do, there's one that sticks in my mind, an exercise that I did one time where we were learning how to use a message broker. We were using RabbitMQ, and there was this exercise that was set up. There are many ways that you can do message brokering. And this is the pattern that that our company has chosen. Here is an exercise for ordering pizzas or something like that. And just watching messages go through the flow of different parts of the system that was super helpful for me. And we learned about how to crash a RabbitMQ server too.
[00:56:39] Dave Adsit: I think that one of the great things about those exercises for communicating an idea is that you get the really fast feedback. And usually you've got exercises that are guided. And so you have a tutor who is watching and helping to correct and point you in the right direction when you are either making obvious mistakes or getting stuck or whatever in a way that we don't necessarily have in our regular daily work.
[00:57:09] Matt Baker: I'm thinking about, you know, exercises to learn, and pair coding jumps back out to me again. One of the things I love about pair programming is, you can, while carrying out the duties of your job, you can have some fun with it. And one of the ways you can have fun with it is create a constraint where there's one person at the keyboard and they aren't allowed to think essentially. They just need to follow the direction of the other person in the pair. So that person forces the other person in the pair to articulate their ideas well enough that, you know, the smart keyboard can type for them. And when I think about exercises to learn, you know, effective communication. I think that's a great one with lots of tight little feedback loops.
[00:57:53] Allan Stewart: I believe that Llewellyn Falco calls that strong style pairing, and his little quip to go along with that, that I really like. "For an idea to go from your head into the computer, it must go through someone else's hands." And that really speaks to communication because it's so easy to run away with the keyboard, especially when you're first learning how to pair program. It's just like, "oh, oh, I've got an idea. Give me the keyboard because I'm not going to actually express the idea. I'm just going to turn it straight into code." And I might not even write the code that well that expresses my idea because it's the first time that I'm going at it. If I have to say it out loud well enough that somebody else can type in what I was intending, then you know that you've achieved that level of clarity, that yes, they understood what I was saying because they were able to type
[00:58:43] Dave Adsit: I really like that tonight we've talked about, incidentally, two of my favorite techniques for improving your technology org. I've long said that the best way to improve your code is by testing it, and the best way to improve your team is by having them pair, and then later I amended, or mob.
[00:59:02] Allan Stewart: I think the final thing that becomes really important when we talk about communicating an architectural vision, especially, is figuring out how do we communicate the value of something that we're doing? Because in the small, when any individual engineer is working on some piece of code, if they get the idea that they want to do something because it's cool, we want to apply this pattern, we want to use this new framework, we want to do whatever other resume-driven development concept is coming to their mind, in the small, it's usually not actually all that bad because it takes time. There's an inertia required in order for that thing to either gain traction and take hold of a database or a code base. But in the large, that can be much more difficult. You know, a lot of times it's easy for us to say, "Oh, well, we want to architecture and all the people are talking about the microservices. So we better start doing some of that." And we're not thinking about the problem. We're thinking about something else. We're thinking about some cool way or technology. We've got this real technology focus of what we're doing rather than a business focus of solving a problem.
[01:00:19] Dave Adsit: Yeah. Most of your customers don't come to you to buy a microservices. They come to you to buy that blue component from earlier. "I would like one 16 pound blue widget, please." Like, "Did you know it was created with microservices?" "I don't care what it was created with." "I would like a blue 16 pound widget."
[01:00:41] Matt Baker: You know, microservices, I heard it called recently "a modern software practice." As in since the Stone Age? Yeah, I just, I find it funny. Anyway, I'll just repeat what you said, Dave, if I go on it again. But I just think that, you know, when we talk about things like microservices, I, yes, definitely a big, like, squirrel or big, like, shiny toy syndrome in the whole industry. And I think this dovetails for me into a lesson that I believe. I have this theory that every engineer learns this lesson. If they're lucky, they learn it on something trivial. If they're out of luck, they learn it at the expense of maybe their job or the company they started or, you know, the demotion at work. Or when you elevate what you're building over why you're building it, you're in trouble, I believe. And a way to avoid that is to constantly express the value you're delivering to the people you're delivering it to, I think. Like, if you can orient yourself and constantly be, you know, saying, "Well, here's the value we're delivering, here's the value we're delivering." You tend to draw your focus away from, you know, that cool new programming languages or that cool new architectural pattern or that cool new database. And you get back to focusing on the problem at hand. And so I might be a bit opportunistic here in raising this point, but I think that I really do think that every single engineer is going to learn that they need to be thinking about why they're building what they're building and who they're building it for way more than they think about the cool tech or the cool new pattern.
[01:02:19] Dave Adsit: 100% agree with that. I think that that speaks to the idea that you should be communicating with people who are not engineers about the thing that you're building. And you can be excited about a technique that you're using to solve a problem, but the technique should not eclipse the problem. Nobody buys the technique from you. And I could be perceived as kind of ragging on microservices. I think that's a great pattern for a specific problem set. I also think that in many ways, it is a reinvention of things that came before, possibly with additional or different constraints. So many times we fail to learn our terminology and we reinvent it when we actually need the same type of solution again.
[01:03:13] Matt Baker: Yeah, it's interesting. I want to piggyback on that point as well and say microservices definitely has a place. I also believe it's true that it's grossly overapplied in the last, I don't know, seven to eight years.
[01:03:27] Dave Adsit: Well, and in some part, in some ways that comes back to communication, right? Apparently when the first patterns book was written, almost no one was using a singleton, but singleton was one of the patterns in the first patterns book that people could easily understand, and so they started using it in software so that they could be pattern driven software developers, and the use of pattern the use of the singleton pattern went up dramatically. So I've read. I think the same is true for any exciting new thing. It's like people try to apply the basic understanding of that thing because communicating effectively the full context of when something is applicable and when it's not is challenging. And wading through all of the possibilities is also challenging to to our human minds, the way we think about software. Again, it comes back to communication. I can explain the singleton to a brand new programmer really easily. I can't necessarily explain the nuance of an event-driven microservices architecture backed by a streaming data service with document data stores at the edges. I can't even say that quickly, let alone explain it to a novice quickly. So I think that that, you know, that is one of the fundamental problems is that communicating is hard work. We need to apply ourselves to do it well, both within our industry, across our team, outside of our team, into, into our business, right? We need to be working at communication, not least of which in the
[01:05:17] Allan Stewart: the code. Well, I think that will bring an end to our discussion about communication today. Really important topic in the world of crafting code, of professionalism, and we're going to let this conversation pass into the night and recommend that all of our listeners join a community of professionals by attending a software crafters group or meetup near you. A lot of them are going going virtual in the era of the coronavirus. The Utah Software Craftsmanship Group at utahsc.org meets on the first Wednesday of each month in Draper, and recently there have been a lot of virtual attendees. Maybe we will see you there.
Copyright © 2026 - Crafting Code Podcast