« All Episodes

How We Construct Software, Part 4a: Code and Communication

Published 2/15/2019

In part four of our discussion on how we construct software, we're discussing a theory of communication, and how it applies to code. This is a two-part episode (A and B) - subscribe so you don't miss the second half!

Today's Episode is Brought To you by: Linode

Instantly deploy and manage an SSD server in the Linode Cloud. Get a server running in seconds with your choice of Linux distro, resources, and node location. Developer Tea listeners can get a $20 credit and try it out for free when you visit: linode.com/developertea and use promo code: developertea2019

P.s. They're also hiring! Visit https://www.linode.com/careers to see what careers are available to you.

Get in touch

If you have questions about today's episode, want to start a conversation about today's topic or just want to let us know if you found this episode valuable I encourage you to join the conversation or start your own on our community platform Spectrum.chat/specfm/developer-tea

🧡 Leave a Review

If you're enjoying the show and want to support the content head over to iTunes and leave a review! It helps other developers discover the show and keep us focused on what matters to you.

🍵 Subscribe to the Tea Break Challenge

This is a daily challenge designed help you become more self-aware and be a better developer so you can have a positive impact on the people around you. Check it out and give it a try at https://www.teabreakchallenge.com/.

Transcript (Generated by OpenAI Whisper)
This is part four in a series of episodes on Developer Teaabout code construction. We're discussing not the specific methods of constructing code. We're not talking about what editors to use or what language to use or even what paradigm to use. Certainly all of those things matter and they're related to the things that we're talking about on this series. But we're discussing more about the human behaviors and the collaborative efforts that we put forth when constructing software with other people. My name is Jonathan Cutrell and you're listening to Developer Tea. In the past couple of episodes we've discussed the complexity that is the construction of software. And we haven't really approached the discussion of software itself very much. Mostly what we've focused on is the individual perspectives that may shift the way that we see software, the way that we visualize it as individuals and then put forth whatever that is into a code form. But what exactly are we doing when we write code? Is it as simple as moving bits around? Certainly if you're listening to this podcast then you probably don't believe that that's the case. Code takes on a lot of meaning. It takes on a lot of different forms. The job of code is kind of like asking what is the job of sound? What is the job of letters? How do we put sounds together in the right way? That's kind of similar to asking how do we code well? Good code is highly contextual and that's because code is a communication tool before anything else. And if you're writing a note, a quick note, one that is disposable, then getting that note reviewed by an English professor seems like a silly idea. And anyone looking at it trying to scrutinize the plot of your grocery list, they're probably misguided. So how can we think differently about the role of code in our jobs? As software developers, coding is only part of our job. And hopefully that's not a revelation, it wasn't intended to be a revelation just a reminder that code is only a small portion of our job, which is really why this podcast exists in the first place to discuss everything else. But we need to understand the role of code. And to do that, we need to understand a better picture of communication from the ground up. We're going to talk about the communication model in today's episode, but just to kind of lay the foundation for this. And this is going to be two parts in this series. We're going to talk about the communication model over the course of two episodes, because there's a lot to discuss here. But I want to talk about for a moment what we're doing when we write code and how much communication is actually happening. So if you take a step back and you think about what software does, if you think about whatever app that you've created in the past, whatever thing that you're working on today, and whatever you will work on in the future, all of these things exist to run. And when they're running, they're processing some kind of stream of events or information. This stream could be instructions, for example, coming from other computers, or it could be individuals who trigger different types of requests to your application through another machine. The code you and your team create is responsible for managing that stream of events and doing something with it, changing that stream in some way, or maybe magnifying parts of that stream, or even creating new streams. And the code itself is a communication tool that represents what happens to that stream. Now, this isn't to be confused with streaming data, that's a more technical term. We're more talking about the concept of a stream of events. You can apply this same concept even to one-off scripts. The stream of events that is happening to the one-off script is that you're actually running that script. Perhaps the stream of events is that the script is going out and getting information and then doing something with that information. So I want to make sure that you don't get hung up on this concept of a stream or of event-driven programming or something like that. That's unrelated to what we're talking about in today's episode. So in order to accomplish this kind of thing, we, as teams, we communicate about, first of all, the code itself and not the code that we're writing, but the coding, the practice of writing code. This is kind of a meta communication where we discuss different dialects or flavors, ways that we can communicate better through code, best practices. Now, it should be noted that this discussion about code that we're having on the show kind of compresses out the possibility that one language performs significantly better for your problem set than another language. So we're assuming that your performance problems are not at stake in this discussion. This is often not the case. And I don't want to minimize these best practices' discussions because they are very important. But this is something that we communicate about. And sometimes we have arbitrary differences between various languages, various opinions about how to perform a particular task, what kind of naming structure do we want to use? And for the things that we're trying to accomplish, usually as teams, those discussions are much more weighted towards opinions than they are towards some restriction that you can't bypass. So we communicate about coding, the coding itself, what languages should we use, what kind of paradigm are we interested in? What fits our problem the best, and some of that is how do we understand our problem so that we can map that problem best to the code? So we communicate a lot about coding. We also communicate about the things we are trying to accomplish with that stream of information. So this is kind of a parallel discussion that we discuss. What is it that we are trying to do with that information that's coming into the, to whatever our application is? And so this isn't a direct discussion about what the code should do. What this generates is some kind of objective criteria that we're trying to meet. And then we take that criteria and we feed it into the exercise of communicating through code. So we communicate about the things that we want to try to do, but we also communicate about the effects of those decisions, the people who are affected. We communicate about the emotions. These are a third and fourth and you know, tenth order effects of writing code. When we write code, the first order effect is that bits are moved. You create a positive or negative charge and that's not necessarily as meaningful to us until we recognize what the culmination of all those bits changing does to another person. So it's critical that we talk about these kinds of things. In addition to discussing what should our code look like, we should be discussing what does our code do and how does it affect other people. And other people in this case could be other people on your team. It could be your customers. It could be the people that are around your customers, your customers, friends and family, or maybe even your customers, customers. And let's not forget ourselves. How does this code affect us? How do we feel about this code and fast forward into the future? If we're working with the same code, then how does it affect us then? All of these discussions are pointed at actually changing code. We will change something in the code to affect something that we discussed outside of the code. This is a very important concept to grasp because a lot of our discussions may be well meaning. But if they don't result in some kind of direct change to whatever it is that we're responsible for, in most cases for developers, that is the product, that is the code that you are writing. Then those discussions don't have much of an effect on the work that we do. We're going to take a quick sponsor break and then we're going to come back and talk about a basic model, a theory of communication. We'll discuss that model of communication right after we talk about today's sponsor. Today's episode is sponsored by Linode. With Linode, you can instantly deploy and manage an SSD server in Linode Cloud. You can get a server running in just a few seconds with your choice of Linux distribution, resources, and the location of the node. With $20 worth of credit, that's free money basically. You can get started on Linode on, for example, their 1GB of RAM plan. That starts at $5 a month and under that $20 worth of credit, you essentially give 4 months for free on this plan. With that plan, you could, for example, boot up your own virtual machine on top of this native SSD storage, by the way, and a 40GB internal network. If you wanted to, spin up another node and then communicate between those two nodes, you could do that very easily and with high performance. It's all on top of Intel E5 processors and Linode is continuously improving. For example, there's new data centers opening in India and Canada before 2020. And there's block storage now available in Newark, Fremont, Dallas, Atlanta, Frankfurt, London, and Singapore soon to be released in Tokyo. Linode is a company of developers for developers and they happen to be hiring. Head over to linode.com slash careers to learn more about that. And if you want that $20 worth of credit, go and sign up for Linode. Head over to linode.com slash Developer Tea and use the code Developer Tea2019 that's Developer Tea 2019 to check out. Thanks again to Linode for sponsoring today's episode of Developer Tea. So let's discuss the basic model of communication. Now this is a little bit of a mashup of multiple models of communication, but this is essentially what most people agree on as the primary, the primary kind of building blocks for a communication theory. So the most common model of communication theory goes something like this. You have a messenger and that messenger sends a message across a particular medium that is intended for an audience. That audience provides feedback along the way that message may be interrupted or otherwise garbled by some kind of noise. Now we're going to look at each one of these things that's messenger message, medium, audience, and feedback as well as noise. We're going to look at all six of these in today's and the next episode of Developer Tea and we're going to start with the messenger. We're going to use the concept of a single developer writing code with a multi functional team that includes other developers, maybe a product owner, a designer, maybe a stakeholder. That developer is writing this code to accomplish some kind of specified behavior. Remember that stream we discussed earlier that developer is trying to modify that stream of events. The team will review the code and subsequently the team has to rely on that code and work with it. They have to use whatever that code provided to them or maybe they have to change it. But ultimately once it gets accepted that code becomes a part of that product, what that team is working on. So the messenger in this case is kind of our hero. He's our protagonist. It's you, the coder. And you're responsible for crafting a message. Now code is kind of the primary medium that you're going to use and we'll talk about the medium in just a little bit. But code has the intent to modify that stream of events of information in some specific way. And as we've discussed in previous episodes in this series, the way a given messenger chooses to communicate could be vastly different from another messenger. This is how you and another developer on your team approach problems with totally different ways of solving them. Even well-scoped minor problems can be solved very differently depending on the developer. And you may solve a problem differently from one day to the next. Now it's important to note and perhaps most important to note that you have a lot of personal experience and motivations. You have a lot of context. And when you're writing that code, it's very difficult, perhaps not even worth it to try to shed that context. Often that context is actually helpful. The messenger's experience and personal opinions will heavily influence the way they choose to communicate in code. Now this is not a pure transaction. You're not just moving bits exactly the way that they should be moved because should is a really difficult thing to understand. Instead it's a highly personal and human experience to write code. Now it's very important to understand that you have different motivations based on whatever your role is on this team. And really whatever your role is in general. When you craft a message, often there's some kind of persuasive element. You're trying to convince the team. There is some goal to sending the message. Otherwise you wouldn't send the message at all. Maybe the goal is to convince your team that you are doing a good job. It could be as simple as that. Or maybe you have a very highly motivated stake in whatever it is that you're building. This is probably a better scenario, a more satisfying scenario for you. But often our motivations are not simple. They're not easily summed up. Perhaps for example the last bit of code that you pushed had a bug in it. And so maybe some of your motivation on this new push is to gain back the trust of your teammates. You'll notice very quickly that when you start talking about motivation, you can trace a lot of the decisions that you make back to some kind of emotion or a human need. These feelings can't be discounted. They absolutely affect the way that you communicate. Now it should be noted also that code is not your only method of communication. We talk about our code. We write documentation around our code. We discuss what the code should be in meetings and even nonverbal communication like managing our code in a particular way or doing a midnight push. All of these actions, all of this behavior is a part of your communication as the messenger. So it's important to understand that the messenger's communication is not limited and it's not directly controllable. It is a very human thing. And on the other end is the other human, the audience, and in this case many humans typically. And the multifunctional team works alongside that messenger to both understand their message and hopefully to help refine that message through some kind of feedback, which we'll talk about in a future episode. But here again, we run into an interesting situation. Not only do we craft messages and code with a heavily influenced lens. So naturally one person will see it differently than another. But we also decode messages from others through a different heavily influenced lens. When we recode, we read it with a different perspective than we write it. We judge the messages that others provide differently based on who they are. This is actually a studied phenomenon. People are less likely to agree with their own judgments and decisions when they don't realize that they made those decisions themselves. This ultimately means that the reviewers will, on average, be harder on the code than the writer will. But there's some caveats to this. For example, what is the actual role of that person? Remember we mentioned that this is a multifunctional team. And so you have different motivations, even intentionally so. The developers' motivations are naturally going to gravitate towards maintainable code, while the product owners' motivations are naturally going to gravitate towards making progress on a product roadmap or something similar to that. A stakeholder's motivations may be slightly different, perhaps weighted towards the highest economy or most lucrative decision that can be made. All of these different motivations will change the way that you see or hear that message. Beyond these more obvious roles, there's also some caveats to the idea that other people will be harsher on your code than you will. For example, if the reviewer can connect an authority figure to the messenger, they may be swayed to review that code less harshly. They may even trust the authority figure more simply because they have some authority. Even despite their best efforts otherwise, authority has a major psychological sway over the way that we view the messages of others. Perhaps an interesting exercise would be to review code without knowing who wrote it, but our intuition doesn't always serve us wrong. It doesn't only make us do bad things. We develop, for example, trust in others' work based not only on their title of authority, but also on their practiced intuition, on their proof. We may unknowingly, for example, pay more attention to a particular piece of code if we know that that developer is new on the project. The audience's role, in many ways, is to see clearly what the messenger's message is. And then to determine, in our case, whether that message is acceptable, should we change the message? As we mentioned before, code is kind of a multifaceted medium. It holds both messages that we communicate to each other, but it also has an effect on that stream of data, that stream of events that we mentioned at the beginning of the episode. So the message crafting is not completely separate from that modification of the stream. Both objectives need to be met. The code needs to communicate clearly to the audience, but it also needs to accomplish that modification of the event stream. It needs to do whatever it was intended to do. Even the best written, most eloquently communicative code, if the message is wrong, if the thing that is being communicated is not the thing that needs to be communicated, then it doesn't really matter how eloquent it is in the first place. Understanding the messenger and understanding the audience is really kind of half of the battle, but there's more to it than that. We need to discuss the message itself. We need to understand the medium that the message travels across. When each understand the feedback.