Crafting Code Podcast

~/podcast

$ cd episodes/073-software-imitates-life

~/podcast/episodes/073-software-imitates-life $ ls -1a
. .. episode-summary.txt published.txt references.txt themes.txt transcript.txt get-mp3.sh
~/podcast/episodes/073-software-imitates-life $ cat episode-summary.txt

Biology has a lot to teach us about successful complex systems. As with other disciplines, we can adapt biological concepts to help us create better software — both in code and in how we work. In this episode, your hosts talk about how we can apply concepts from cells, genetics, and evolution to practical concepts like team creation, code communication patterns, and architecture. You may never code up your own genetic algorithm, but we think you'll find the concepts interesting and useful.

~/podcast/episodes/073-software-imitates-life $ cat references.txt ~/podcast/episodes/073-software-imitates-life $ cat themes.txt ~/podcast/episodes/073-software-imitates-life
$ cat transcript.txt

[00:00:22] Allan Stewart: Allan Stewart, Software Architect, and lately I've been thinking about the shared understanding and surprising gaps you encounter when role-playing in various settings.

[00:00:32] Dave Adsit: I'm Dave Adsit, an engineering leader, and recently I've been thinking about how transaction costs affect not just the desirability of an exchange, but can also strongly impact whether it happens at all.

[00:00:46] Allan Stewart: Our topic for this episode is "Software Imitates Life." As I've gotten into software architecture, I've thought a lot about systems and emerging emerging behaviors and, like, systems thinking. And one of the things that I have noticed is that there are a lot of successful biological systems that we can learn from. And it's interesting to see places where that shows up in the industry. And so today we're going to talk about some of those ones, some very practical ones in my mind that have come up because of software imitating

[00:01:22] Dave Adsit: life processes. Yeah, I agree with that entirely. I have long used biological processes or biology as a metaphor for things in software development. The first one that we're going to jump into is team creation and the cell division metaphor. So I'm just going to very quickly run through the phases of cell division, or mitosis. Basically, mitosis creates two genetically identical daughter cells from one parent cell. And each one has a full, the full capabilities of the parent, full chromosomes, full, you know, organelles, all of that. And so it goes, but it goes through several stages. And the first one is interphase, which is actually not part of mitosis. And in interphase, the cell is just doing its thing. It's fulfilling its purpose, it's growing. And at some point it starts duplicating its chromosomes. The analogy to a a team is that the team is just doing its work and growing. It's hiring additional team members. The second phase, or the next phase in the series, is prophase where your chromosomes condense and you start to form syndromes, which is basically like this idea that the chromosomes start getting pulled to the edges of the cell, right? And this, the analogy to a team and the team division is is that the team identifies natural seams in its responsibilities. You know, the team has gotten too big. You're like, "okay, there's now too many of us in standup. There's too many of us in retro. We're not as effective in our communication. Things are starting to feel a little clunky, but it's because we've hired and gotten big." And now we want to start prepping for a split. And so the first thing that you do as a team is you start finding the natural seams in your responsibilities. Possibilities. So the next is metaphase. So in metaphase, the chromosomes line up on the metaphase plate, which means they're divided in half the cells and got this plate in the middle that the chromosomes are on each side. And the team members start separating into sub teams with work and work rituals becoming duplicated. So you might have stand up one, stand up two, you might have a combined retro, or you might start having two retros. And now you've got two two sub teams that are responsible for one work board, one board, one Kanban board, one work list, whatever, right? So there's still functionally one team from the perspective of the organization, but they're starting to behave as though they were two sub teams. Next is anaphase. And in anaphase, the sister chromatids split apart. So the chromosomes break up into two separate chromosomes, right? And in this phase, I look at a team as pulling the work apart. You know, now we're going to split the board and now the product manager has to go to two standups every day and put work on two boards and then two backlogs, right? The next phase is telophase where chromosomes are enveloped by a new nuclei, right? So now you've got two nuclei inside of one cell wall. At this this point, I think that the team rituals are fully separated, including your work tracker, right? Everything is fully separated. And the last part of mitosis is cytokinesis, where the cytoplasm divides physically, splitting the cells into two separate daughter cells. And for teams, you fully separate into independent work streams. And now you have two full teams where once you had one team. So this is a process that I've used with teams many times. I've taught it many times. And I've encouraged us to do team creation in this very structured way of, like, let's grow the team too big. And then let's use a structure to split everything apart so that we have two daughter teams from the original team.

[00:05:31] Allan Stewart: And it's a process that I think is just fantastic. Like, the more I've experienced in working with different organizations, especially when they're growing, especially when you're making changes, going through a process like this. And yes, we can kind of create an analogy between the different phases. And, you know, what's part of pro phase versus meta phase? What's part of anaphase versus telephase? Like, I don't know that that. That it kind of doesn't matter, right? So important. Yeah. But, but to me, the way that I think about this and how much I like it is in contrast to other ways of creating teams. I have seen cases where teams were created by just sort of fiat or, you know, it's like, "oh, well, we're just going to grow one team and then arbitrarily cut it in half." And there wasn't time given to let things kind of line up and figure out which people are going to fit best onto these new teams. Because even though they're working together as one team, and that might be fine, once you start splitting it up, you discover that the sub teams are not the same as the whole team working together. Other. Yeah. Alternatively, I've seen things where, you know, one person is pulled off a team and then they hire up new, it's like, "oh, you're, you are now founding this new team and we're going to hire new people." I've seen ones where teams are just created from whole cloth, right? Like, "Hey, we need a new team. So we're going to hire four people, all new people, and they're all going to be new and they're all going to do this new thing." And the thing that I really like about about the cell division metaphor or method of creating a team is all of the cultural and knowledge transition that gets baked into the process that people understand how it is that we work at this company. They have a history of these are things that we've done and the decisions that we've made. And even if you hired new people, they have been part of this larger team, at least for some amount of time that they learn what it's like to be, or, or even if not hired, like maybe they're transferred from another team because we're trying to bulk up one team because we're going to split it. However it happens, they gain all of this shared understanding about the domain, about the code, about how the people like to work. And I think that it's really a great way to keep that, I don't know, to keep a kind of a through line of uniformity of how we work as we split up teams.

[00:08:25] Dave Adsit: That's exactly why I've used it. I like to maintain the continuity of the team and the continuity around delivery and the practices and culture that we've got in the, in the organization. And when you do some of those those other strategies, like hiring a product manager and then hiring a team to support them, all net new people in the organization, you lose a lot of that. But what I like to think about is, there's always trade-offs, right? Like, what do you gain if you follow this method versus another method? What do you lose if you follow this method versus another method? I also like to think like, how likely is my strategy to succeed? And I will say that I have seen this strategy succeed many, many times and maintain a continuity of culture and of, you know, valuing the things that we value as an organization and maintaining that knowledge transition that we talked about. And I've seen other strategies have less good results, you know, just bringing in a whole new group from the outside that has had different results, often worse results than doing something something like this. So if you can take the time, I would prefer to follow this method. I will say you've got to spend some time if you're going to do it this way, where you don't necessarily have to spend time if you're willing to just let stuff be broken a little bit and go, if you are optimizing for speed over continuity.

[00:09:53] Allan Stewart: Yeah. I also really like in this method, how how it kind of keeps the socio-technical system intact or, like, it's less disruptive to it because on the social side, people understand what's happening. It's not, I mean, how many times have people talked about, "oh no, we're having a reorg in our company. Something has changed." And, like, there's a lot of uncertainty there and there's often, you know, bad feelings about it because on the social side, it wasn't, it wasn't communicated, people weren't given a chance to feel it out and, and even participate in that process. It was just, it was just landed on them. Yeah. And on the technical side, yeah, having, having people who come in, it's like, "oh, this is the way that we've done things, these are the processes, these are the, uh, even the languages and technologies that they use." Having uniformity there definitely has a lot of advantage. Yeah.

[00:10:57] Dave Adsit: Well, and you can extend this metaphor. We won't really dive into it much, but you could extend this metaphor and say, you know, a collection of cells doing the same thing become a tissue and they work together with other tissues to form organs, whatever, right? The same thing happens with teams. Collection of teams working together on the same monolith might be, or the same product, that might be a department or a product, and multiple products working together forms a company. You can extend this metaphor maybe beyond the point of utility, but it definitely works well for team creation. The next thing that I like to think about is communication. You know, the natural world has developed many, many, many forms of communication, many patterns for communication. And I like to use a model that is related to how cells communicate as a model for understanding OO at a deeper level. All right. So when we talk about cells and communication between cells and the metaphor with object-oriented programming, there are several different types of signaling that cells do, and they have metaphors in OO or in software development. And so the first one is autocrine signaling, which is when a cell emits a chemical message that you actually consume yourself. This is typical in immune cells and cancer cells. It's kind of weird in OO. Like, you don't self-signal that much. If you find yourself sending out a message that you then consume directly, you know, you send it out to the bus, you get a third party involved, and then it comes back to you, that might be a sign of some kind of a cancerous architecture, right? So don't do that one very often or have a very, very good reason why you are. But more common, you've got paracrine signaling, which is you release a chemical message. It's picked up by nearby cells. One example is neurotransmitters used in between neurons. And this is my analogy to queuing in a bounded context. You're putting a message on a queue or you're handing work off to a queue or a boss, some kind of a message broker, so that you can handle it locally within your bounded context or your product. These kinds of signals, these chemical signals don't go very far. They don't escape the bubble of where they're being produced. They're consumed where they're produced. Right. And so for me, that that's like having a cue to order and order work and like offload spiky, spiky workloads, level out that workload type of a thing. So that's queuing within a bounded context. The next one is endocrine signaling, which is actually a lot more broad, right? This is you're releasing hormones into the bloodstream or some other broad system where they're communicated widely, and then they have impacts throughout the whole system. To me, this is PubSub. I am going to publish a message and there are an arbitrary number of consumers who are are going to subscribe to that message. And then they're going to react to messages they've received. It's, you know, I'm publishing a message about an event that has occurred. And now you get an opportunity to respond, like grab, grab a copy of that message and respond to it. Right. So endocrine signaling is a really powerful architectural metaphor across the system, across bounded contexts. I'm, I'm publishing messages about events and you're picking up messages about events and then doing things in response. The last one is direct contact signaling, which is communication via physical contact through message channels rather than releasing messages, right? So this is, I think, less common in the physical world, in the world of biology. You don't often see two cells that, like, connect up and create a message channel between them and and share data that way. You do see it a lot in engineering though. This is, to me, this is creating an API and consuming an API or doing remote procedure calls. Any kind of RPC based communication is this very direct contact signaling. And it's one that I would use judiciously. I would say, or rather I would use it cautiously. I would lean into the other more common biological logical methods of paracrine signaling and endocrine signaling, you know, the local queues and PubSub. I would prefer those at an architectural level over RPC and APIs because of the coupling

[00:15:51] Allan Stewart: they create. I like to think about different types of programming paradigms, such as object-oriented or functional with kind of a reductionist lens. Oftentimes you can learn some really interesting interesting things when you kind of pare it down to like, well, what really makes this happen? And so these communication patterns really remind me of ideas that came out probably initially around, like, Smalltalk and some of these early object oriented communications, the early patterns that came up because how, how you communicate, right? Like, and, and direct contact signaling is one that we learned from a very early age, right? You start writing some code and you say, "oh, well, I just, you know, let me just new up this other class and I'm going to send it a message by calling it, you know, and you're passing data back and forth." And so we get really used to this. And so it's really easy for us to extend that into, "oh, well, everything's just APIs," but having a broader understanding and a broader sense of, "okay, well, what options do we have?" And what ones are actually successful in complex systems that exist in nature? Well, I think that this is a, it's a great way to look at it because yeah, you might not have direct contact signaling happening as much like a cellular level, but there are a lot of biological systems at higher levels that use this kind of thing. So it reminds me that biology found reasons to use all of these. There are probably reasons that we should use them in our code, right? Like, there's, there are different contexts. There are different reasons that you might want to have a different tool at your disposal. And, like, we always say in our introduction, that we want to know the right tool to use at the right time so that we actually get a good result out of it.

[00:17:49] Dave Adsit: Yeah, absolutely. And one of the things I was thinking about as you were talking is that the the language around using objects has changed drastically since the days of Smalltalk. When I listen to the Smalltalk people talk, they talk about sending or receiving a message. An object receives a message. How does it handle the message it received, right? And now we just talk about calling a method, calling a method. And so our language has changed and it's changed the way we think about the system and the architecture around it. And I think that that is something we should be aware of and perhaps use more precise or better language to help us communicate and think about these patterns in the right way. One of the things I think about sometimes at a higher level is you've got things like ants. They communicate with signal. They send signals to each other all the time. Ants will leave a chemical trail as they traverse the wilderness and everything's the wilderness to an ant, right? So as they're moving around, they're leaving a chemical signal. And as you see more and more of that signal, other ants will start to follow it because they assume there's a reason all the other ants have been going this way. And I think for me, there's something there that I haven't fully worked it out, but I think it's some kind of an analogy to observability in your system, logging and monitoring. One error message is not a signal, but 500 is. Maybe. Probably. Unless I've got a really, really messy system. So maybe there's something there that could be developed or, like, you think about how bees communicate by dancing and buzzing and, like, using the sun and external, you know, they've got all kinds of crazy stuff that, if you're another bee, it's really easy to understand. But if you're not, you're not going to, it's going to be very difficult to interpret the signals that you're receiving. So I think there's, you know, additional communication things that we can learn from systems that have evolved and become perfected over millions of years.

[00:19:51] Allan Stewart: Yeah. It reminds me of the Boids that you can look up online where you can create different, it's like mimicking flocks of birds, but just by some behavioral, simple behavioral rules, which are really cool.

[00:20:07] Dave Adsit: The flocking behavior. Yeah. Yeah. It's flocking behavior is, can be expressed using a very simple algorithm and it leads to extraordinarily complex group behaviors. Fascinating, fascinating group behaviors.

[00:20:23] Allan Stewart: Well, going down back to a cellular level, one of the areas that I have always found interesting are genetic algorithms. They are not things that I have used very much since graduating from from college, but they're really cool. And they have some really powerful practical applications. So a genetic algorithm is basically a computer program that solves problems using these ideas from biology, right? But specifically selection, mutation, and crossover, right? Talking about genetics. So there are some other evolutionary algorithms that are inspired by biological evolution. But I feel like what we're going to talk about here is kind of like the core idea behind the whole set. And then there are variations that go off of there. So Wikipedia says that a typical genetic algorithm requires a genetic representation of the solution domain. So we need some way of representing our data, right? This is a data model that isn't just a representation of how we would normally think of the data, but is influenced by our understanding of genetics so that we can do operations like crossover or mutation that would actually make sense in the algorithm. So you need that representation and then you need a fitness function to evaluate the solution domain. So you can say, "hey, is this one fit?" So I said we were going down to the cellular level, which is true because we're going to talk about genes, but it's also kind of at the higher level as well, right? Because it's a population representation when you do one of these genetic algorithms and it's a survival of the fittest, right? Very Darwinian approach to finding which answer to this problem is the most fit, that survives the best. So you end up with a bunch of pieces, right? So you start by initializing an initial population of solutions. This could be completely random. It could be seeded with certain known inputs, depending on the kind of question you're trying to answer. A good example of a question you might answer with this is the traveling salesman. You've got all of these different locations that the salesman needs to go, and they have different distances or prices along different routes. So if you fly from New York to Boston, that's going to cost you a certain amount. It has this much distance, et cetera. And so if you were going to initialize that, you might just come up with a bunch of different random routes as a starting point, just to give it something to work with. Or you might say, "no, here, we've already got some that we have figured out. By hand, we've decided these ones are pretty good, and let's see if we can optimize from there." So that's the initialization phase. You also have the idea of selection out of a population, which ones are the best, you're going to use that fitness function that we talked about to evaluate them and say, "oh, well, this path is going to cost us this much money, but this much time. And which one are we willing to trade off?" So you pick out of those, you select which of your solutions from the population are best to try to make a new one. And then you start applying genetic operators on them. So you do things like crossover, mutation, recombination. So you take two solutions that seem pretty good. These are good ones. Let's combine them in interesting ways. It's like, "oh, well, once you get to New York, instead of going on to Boston, we're going to change it and we're going to send you down to DC instead because that's what this other solution was doing." And so you play with that. And it creates a new child solution, right? So you've got two parents creating a child, and then you put those children into the new population. And over multiple generations, you're hopefully working towards better and better, more fit solutions. You can also add some heuristics in there, which are basically optimizations to make the algorithm faster, right? You can imagine if it's just pure randomness, it might go down some really terrible roads that don't work very well. You might know that, "hey, there's a particular city that's really hard to get to, and we always want a particular solution here. That's always going to be better." So there might be things like that that you put in to optimize. And then eventually you've got to stop. This could just run indefinitely. And so you just have to figure out how do you know when you're done. Termination is the last piece. It's kind of like your base case in recursion. Eventually you want to end and not have an infinite loop. So did you find a solution that meets some criteria? Did you run it for a fixed number of generations or something else to let you know that it's stopped? But then at the end, you can often get some really surprising results. Speaking of Wikipedia, if you go and look on there, they have a really cool picture of an antenna that was created using genetic algorithms. And it's a really weird bent in certain ways antenna that was used for, I think, a satellite because it had the radiation properties that worked really well for what they needed, which I think is fascinating, right? Right. Like, I'm old enough to remember when you had to move the antennas on a TV to try, or on a radio to try and get it to pick up the signal well. And having a computer create a smaller, more effective antenna, definitely useful.

[00:26:25] Dave Adsit: Yeah, I've seen one where they did something similar with a spigot that was supposed to create high pressure water. We all know fluid dynamics is complicated to say the least. And so they just ran a genetic algorithm to create this, this faucet or spigot or something, this nozzle that created a high pressure stream of water. And what it came up with would have never been generated by a human engineer because they would have been laughed out of the building. And then eventually had to be 3d printed because of the complex baffles inside of it, but created a very high pressure stream of water from the input that they had available in the very fascinating things can be done with this type of algorithm.

[00:27:11] Allan Stewart: Yeah. And they're fun to write. I've played around with some stuff before. I don't know that I have found, and it might be just the domains that I've worked in, there hasn't been a particular place where that has made sense, but it's the kind of thing that I like to keep in the back of my mind and say, "hey, sometime in the future, I may run into a problem where this is the kind of solution that will make a lot of sense." And as we get more and more into AI and and non-deterministic systems that are being developed, I can't help but think that some of these ideas become more and more useful as we're playing around in the world of uncertainty, of non-determinism, and you want to get good results, even if they're not the straightforward path that you classically have trained yourself to write those programs.

[00:28:10] Dave Adsit: Well, yeah, I know we've talked about it in terms of e-commerce in the past when we start to go beyond AB testing to multivariate testing. Like, how do you generate the correct test cases to run and how do you select which ones survive, which ones are the fittest and which ones are the least fit and should be terminated. And so I think that you can get into cases where you would use this in a standard software development project, but it would have to be one where you are going beyond the basics. Yeah. So we're not the only ones who have drawn an analogy to biology, so much so that Neal Ford and Rebecca Parsons wrote a book called Evolutionary Architecture, which is about bringing together the concepts of evolution and software architecture.

[00:29:00] Allan Stewart: Yeah, as an architect, I really appreciated that book. To kind of sum it up, it's a pretty big book. It's got a lot of great information in it. But if I were to distill it to two ideas, I would say it's kind of the approach to software architecture that guides incremental change, avoiding degradation, while allowing for an architecture to change over time. Right. It's, it's very easy for us to get very rigid minded in our thinking about a software architecture. And we say, "Hey, this is the initial definition and we go for it." And we didn't make something that was flexible. We weren't thinking about how it's going to change over time. This book gives some really good suggestions about that. So it borrows the same idea of fitness functions that we were just talking about, but instead of applying it at a solution level, it's more of, this is a guide for something that you want to see happen in your architecture, especially around the so-called illities of an architecture, like the availability, scalability, some of those kinds of non-functional requirements. So for example, you might put unit test coverage as a rule in your system. And you set this up as a fitness function to say, "hey, we do not allow the unit test coverage to drop beyond a certain threshold." And if it does, then we fail the build and we do not allow that to get deployed. Other examples might be a code analysis, right? So you might have some static code analysis that gets run, or you might have something that looks at particular architectural boundaries. For example, you might say, "hey, you can depend on the data layer, but it's not allowed to bind to other parts of your system." So that you don't get loops or cycles in the graph, I mean. Or you might, in these days, you might hook it up to an LLM and say, "hey, I want it to do a code review every time." And if it doesn't meet certain thresholds, then it doesn't pass. Or there could be performance tracking. So we don't let it get slower. And oftentimes these fitness functions are kind of a ratchet, right? So you want to get more fit over time, just like in our genetic algorithm. You want to get better and better solutions each time. So your unit test coverage, well, maybe it used to be 60%. If it fell below 60%, it would fail and not let you proceed. But as you improve your code base, hey, we're now regularly getting 70% plus code coverage. And so we ratchet it up and say, "hey, well, you can't fall below that anymore." And that helps you get further and further towards this, in this case, test coverage. But for each of them, get better and better, closer to the performance or whatever architectural quality that you're really looking for.

[00:32:02] Dave Adsit: One of the things I really like about that is that it reinforces the idea that change is inevitable and also incremental. We're not going to stop the system and rewrite the whole thing. We are going to be continuously improving and we're going to be improving in a direction. I think about some advice I was given by a very experienced architect early in my career, which was that at every 10X of scale, you should be, at every order of magnitude scale, you should be rewriting your system. And his advice was not that you should stop and rewrite at that point, but that if you have increased your customer load, your volume, your whatever, 10X, then as you got to that point, you should have refactored and rewritten and improved your system to the point where it can now handle that new load. And the corollary to that was, if you don't have to do that, you have over-engineered and over-designed and over-architected. And so you've made a mistake and wasted resources at one scale if you didn't need to make that kind of change to get to a 10x scale, which has helped me a lot with avoiding things like gold plating and over-engineering. Yeah. And, you know, we've built tools that allow us to easily do this kind of incremental change, right? Just about every organization that I work with these days talks about continuous integration and continuous deploy pipelines, CICD. And sometimes I think that people forget what CICD means. They just say it because they've got a pipeline and it runs, but we need to truly understand continuous integration, continuous delivery.

[00:33:50] Allan Stewart: Yeah. Yeah. Yeah. There's a lot of good things to be said, both in the book, Evolutionary Architecture, but also just generally about incremental change and how you get from one place to another. I've experienced a lot of cases where developers get kind of paralyzed and you look at a massive system and you think, "I'm just overwhelmed. How am I supposed to change this mess that I have into something better?" And well, you do it in these little, little steps, right? Everything from how you evolve your database schemas, you know, that are in backwards compatible ways, and how you structure your code and where you use abstractions and things like that. It matters a lot. If you can come up with these small scoped changes where incrementally you are or shifting the playing field in your code base, eventually it snowballs and you see really big results that happen that almost inevitably have come from the little pebbles that started the avalanche.

[00:35:01] Dave Adsit: Yeah, and one of the things I think about is homeostasis, which is a body's desire to resist change. And these fitness functions and these ratcheting effects are a way that we can overcome that homeostasis. Oh, the system's a mess. It's always been a mess. It'll always be a mess. Well, the system apparently desires to be in a mess. But if you do the right things over time, you can work out some of that chaos and create areas of sanity within the broader system. And those can start to expand. So more broadly, the concept of not just evolutionary architecture, but evolution of systems, I think has been influential in how I think about software. So much so that for every architect that I've worked with, I've recommended that they pick up a copy of the book, The Red Queen Hypothesis, which is from a completely different domain than software development it's very directly from the domain of teaching people biology and evolution. The Red Queen, of course, is, is the Lewis Carroll Through the Looking-Glass, where The Red Queen says, "where I'm from, it takes all the running you can do to keep in the same place," right? The, the hypothesis here is that as every organism in an ecosystem is in competition with every other organism, right? Right. You've got predators, you've got prey and you've got parasites and you are running as fast as you can to get ahead of all of them. And they're also running as fast as they can. And so you stay in the same place perpetually. So the core application of the Red Queen is that there's a predator prey dynamic, you know, faster gazelles escape slow cheetahs leading to survival of the fastest cheetahs, but not the slowest gazelles. There's a host parasite co-evolution. It's very similar to predator prey, except it's a poor parasite that kills its host. In fact, the parasites that kill their hosts also die, and therefore we're not fit for the environment. And so there's weird dynamics with with parasites, and some parasites even benefit their host and then they might be called symbiotes, but they're actually still pretty parasitic. There is this weird thing where people will buy certain parasites to either lose weight or to suppress their immune system so that they have a less strong allergic reaction to their environment. Right. So, and then one of the other, the core app core concepts is sexual reproduction, which, you know, I, I like to reference our discussion of genetic algorithms, rhythms recombination of things in different ways, some of which are better and some of which are worse. Anybody who has multiple children knows that they are all better at something than their siblings. Or anybody who has ever interacted with humans in general knows that humans have different

[00:38:03] Allan Stewart: skills at different levels, they're all very different despite having come from the same

[00:38:07] Dave Adsit: parents. Yeah, right. You're like, "how did you all get to be so different?" Uh, and then one of the other concepts that comes out of this book is the idea of antibiotic or pesticide resistance, right? You create an environment that's hostile. Some of the creatures will survive, and they now have a new resistance or a new innate capability that they would not have had before all of their competition was wiped out by an outside force. Right.

[00:38:34] Allan Stewart: You don't want all of your, uh, Taumoeba to escape the xenonite.

[00:38:39] Dave Adsit: That is correct. You're going to have a bad time if that happens.

[00:38:43] Allan Stewart: I really like the idea, especially that quote with the Red Queen, "it takes all the running you can do to keep in the same place." I have felt that working in software systems, where it seems like the more effort we put in, we keep working and we're making things better, but there's still so much to do. And it never ends. That's the thing. Is if it did, we would not see company dynamics work the way that they work today. If you did a little bit of work and then you were done and you receive this big win and that's the end, well, that's a different kind of market than most people work in software. Even the people who are doing more of a project-based work, oftentimes they're consulting consulting or things like that, where they do finish up a project and they're done and they get their money and move on. Well, they move on to more projects. They move on to take those learnings and apply them somewhere else. So it might be different than when it's the product, but they're still running. They're still on, still getting back on that treadmill.

[00:39:58] Dave Adsit: Yeah. I have a story. You and I have experienced this together and we, I know we've each experienced it independently, where you go into a system and it's down all the time and keeping it up is a Herculean effort. And, you know, everybody's used to the system going down every week and having incidents every week. And you start putting in place things that improve it and improve it and improve it. And you get to the point where you only have one incident a quarter or, you know, cause you never are going to have perfect software, right? We work at systems at at a scale where it's, it's not even expected that it'll be perfect, but the total reaction of it's down all the time. And we're constantly propping it up. Everybody in the company is like, "well, it's down." And, you know, they're, they're like excited when you can keep it up for a week. And then when it's up all the time and has one blip a quarter, you get the same reaction as though we're down all the time because people are so used to the improvement you've made that the incident that you experience is an anomaly. And so you can see this in systems that you work in as they become healthier. Sometimes the reaction from outside of the engineering team does not change, even though they're living in a much better life. People very quickly adapt to the new level of delivery or the new level of quality or whatever, as long as it's higher than it was. I'd like to remind them periodically how much better life has gotten. Yeah. We've talked a lot about system health and that is one of the reasons why, right? Like, remember when it wasn't healthy? Remember what that was like? Yeah. So in the Red Queen, there's a lot of false assumptions about evolution that are uncovered and discussed. And I think that they have analogies in software development as well. Well, one of them is that evolution equals progress. And that's a fallacy. Like, you don't evolve toward anything. Evolution is away from unsuccessful mutations or combinations or environmental changes or whatever you are evolving away. So in software, not all new features are progress. If you add enough features to a product, you eventually ruin it. And the settings page becomes unusable or unstable.

[00:42:26] Allan Stewart: Yeah, absolutely. I also think about progress in the terms of vestigial organs and vestigial code. I have found dead code in so many code bases, and some of it is just truly dead. This is just debris. It is decaying here and causing problems. We trip over it periodically and don't realize that it does not do a lick of good for us. But there's also code that's not quite dead, like it can be invoked, but it's not doing anything that adds any value, and we see that in things like, you've got a tailbone, I mean, I don't, I don't have a tail, but I've still got a tailbone that, it's this vestigial representation from this

[00:43:13] Dave Adsit: evolutionary product. The good news is that unlike code, a tailbone will never hurt you if you fall on it really hard. Right? Like, if you have dead code, you should remove it so that you don't fall on it really hard at some point when it's going to be painful.

[00:43:30] Allan Stewart: Yeah. And so sometimes I just worry, it's like, "which part of this code is the appendix and is it okay?" Right? Because we have learned, and some of us more than others have learned what happens when your appendix decides it wants to kill you.

[00:43:46] Dave Adsit: Yes. My family gave me a mug after my appendix ruptured that said, "I probably won't kill you unless, or will I?" So another assumption about evolution is that it's zero sum. And it's actually quite a bit worse than that. Because if you succeed, you now have a target on your back. And that is definitely the case at the company or product level. The better you do, the more you're going to attract copycats and competition. And so this is something I think about a lot. How do you stay ahead of those parasites that are just copying your features every release? This is something that we discuss a lot in a leadership or product management level is making sure that we are the most fit for purpose and the most fit for the environment, which which, again, for me, goes back to some of the concepts of keeping it as lean and clean as possible and not having an unnecessary bloat so that we can go fast without impeding ourselves.

[00:44:51] Allan Stewart: Right. And we often think about survival of the fittest as kind of like, "oh, well, this is obviously it always happens this way." The most fit thing always is going to be what goes forward. But that itself is a fallacy that we have to watch out for.

[00:45:08] Dave Adsit: That's right. In biological terms, survival doesn't mean old age. Survival means reproduction, or perhaps that you created offspring that successfully reproduce, depending on, you know, the species. And it's not that you make it to old age, it's that you managed to spin out some derivative products that are also successful in their own right.

[00:45:34] Allan Stewart: Right. Yeah. I think about this in terms of companies making money, right? Like, that's the thing that the company is there to do, but oftentimes companies will get confused about what they're about and they'll forget about their customers to do some other mad dash for some other reason, or somebody will get it in their heads that the sound like, you know, political activism thing is what was more important to them, or they just get really big and they say, "oh, well, well, you know, this is how we do things, right? We have an institutionalized certain behaviors and they forget that the thing that mattered was making the money that gives them more chances to keep playing." Right. That's kind of the core concept of business in the first place.

[00:46:22] Dave Adsit: And making money by satisfying customer needs, creating win-win scenarios from an economic perspective. One of the other interesting ones for me is, because you hear it a lot, is that current organisms are adapted to current conditions. And the fallacy is that nothing is adapted to the environment that it lives in right now. Everything is adapted to the way things were before when you become offspring, like when you were created. And so if the environment is changing slowly, great. Too bad all the environments are always changing changing because otherwise it'd be really easy to get very well adapted to your current environment. Change in the technology sector.

[00:47:07] Allan Stewart: It's a given. The last six months have been wild. Yeah. The last, even the last couple of years have been more wild than we had been accustomed to. And some of us had worked with JavaScript. And so we knew that the rate of change was incredible already. Everything

[00:47:30] Dave Adsit: So pulling an analogy from business, they're in retail. They say that you're supposed to measure your retail success by how many inventory turns you have per year. And there were thresholds of how you could be doing very well. And Kmart was exceeding those thresholds year after year after year. And so obviously they're the winner. Except that Walmart came along and changed the environment that Kmart played in. And Walmart had almost an order magnitude more inventory turns per year than Kmart did. And now there are no Kmarts because while they were a very effective apex predator, they were defeated by someone who came out of the blue.

[00:48:10] Allan Stewart: Yeah. And the success that companies have, right? Like, you know, Kmart in its heyday, the success makes it difficult to change. They don't, they don't want to change. They're like, "this, this is working where we have money. Why would we want to change? Because that might risk our ability to have more money." And Wardley mapping talks about this as inertia, right? And it biases your view of new conditions. It, it makes it harder for companies to make the changes that they need, especially when there are significant kind of sea change events going on.

[00:48:47] Dave Adsit: Yeah. So the next fallacy from the book is that between species competition is more important than within species competition. Like, if we're running and a bear comes up on us in the woods, I don't have to outrun the bear. I just have to outrun you. Unfortunately, in this case, I'm pretty sure Allan's going to outrun me and I am going to have to outrun the bear somehow. But the thing is, is that we can be our own greatest enemy if we are not continuously improving and evolving the way we operate. And so we need to be on the lookout for the scenario where we are our own worst enemy, where we are the competition that we have to overcome, come, where we are preventing ourselves from taking opportunities. Because often in many of the businesses that I've worked in, it's not the competitor that we put on the marketing slide that's the problem. It's our own inability to effectively understand our customer, effectively evolve and deliver our software systems. It's our inability to make concise and good decisions or or even commit to a decision, you know, if we waffle too much on every decision that could be made. And so we, we in fact are the problem versus the competitors that we are looking at, you know, through the lens of the, you know, the SWOT analysis or the marketing material.

[00:50:15] Allan Stewart: Right. And going along with that, there's also the fallacy that predators are the main threat, that you assume that somebody else is going to come to eat your lunch. And especially in in startup land, there's a lot of worry about that. Sometimes big institutions also worry about it and they try and buy up little companies that they're worried about because they think that that's the main threat, but that's not necessarily the truth, right?

[00:50:43] Dave Adsit: Yeah. Typically it's going to be your parasites that are a bigger threat to you. Meaning, in terms of technology, you get disrupted disrupted more by change in the technology environment than you do, then you have competitors who corner the whole market, right? If you're looking at, like, "what's our market share and what's their market share? Oh, they have a lot more market share than us." They are less likely to disrupt you than somebody who comes out of the blue or some new technology that, you know, changes everything. The, uh, the big one, and this is one that I've, I've held this fallacy. See, I've thought this my whole life because I feel like I was kind of taught this in elementary school erroneously. But the big one is that evolution is slow. And there's a counterexample of evolution being slow because evolution, remember, is moving away from bad mutations, bad combinations. One of the examples is a guy who studies crickets went to Hawaii, a very sealed ecosystem, right? The islands of Hawaii are very isolated from the rest of the world. So you can't, you have lower outside influence, which is why you're not supposed to take any biological things with you when you go. Anyway, he was studying the crickets on one of the islands and crickets sing to attract mates, right? And someone had introduced a frog or toad, probably a toad. And that toad liked to eat crickets. And the toad, much like a female male cricket, was attracted to the sound of the cricket. And so if a cricket starts singing, the toad will come over and eat him. And so in a very short period of time, actually, I think it was five years is the story from the book. The prevalence of crickets who are unable to sing, male crickets who are unable to sing went from like one in a hundred or two in a hundred to to roughly 80% of the population. And so basically the, what would happen is the cricket would sing the, the female cricket would come in, the toad would come in. And because of, you know, having, I don't know how they learn this, but something in the male crickets that can't sing, if they can't sing, they'll go to where they think the females are going to be, which is near a cricket who is singing. So basically you get like a little cricket concert that would attract the toad that it would eat the singing cricket and it would attract the mute males and the females. And the mute males would reproduce with the females. Meanwhile, the singing male gets eaten. And in a five-year period, the entire balance of this mutation changed on this island. And it kind of blew everybody away how fast that could happen. We've seen other examples of like the moths in London during the time of the industrial revolution.

[00:53:33] Allan Stewart: All the coal burning.

[00:53:34] Dave Adsit: White moths were predominant because they could hide on the wall or on the trees and the walls. And then when everything was covered with soot from burning so much coal, black moths became more common. And then when England, when London cleaned up their soot producing industry, it went back to being predominantly white moths. And so it can change. And who's winning at any given time depends on how quickly you can evolve to changing conditions. And that for us in software is the critical thing. We need to build good architectures with strong practices like CICD and unit testing that allow us to quickly change when the conditions change around us. So that we can support our products and support our companies through an ever-changing, ever-evolving ecosystem or marketplace, and continuously bring about better software and better products that meet customer needs.

[00:54:37] Allan Stewart: Absolutely. I've definitely worked in a lot of places where we've made change to a system. And when you look at the system as a whole, it can get overwhelming. I mean, and you think, "oh, there's no way that we can change all of this." But not everything needs to change in order to make a difference. You just have to make sure that you are using the techniques, the practices, the architectures that allow you to change the things that matter. So there are undoubtedly a large number of other ways that we could compare software to biology and these different life systems that we can learn a lot from. I think that there are many different domains that we can draw from. And one of the things that I have enjoyed is finding these correlations, finding these ways where I can take something that seems completely unrelated to software, or at least at first glance feels unrelated, whether it's biology, whether it's economics, or some other science, some other social science, you know, that we can look at to give us insight into what works well, what is useful. And biology is definitely one that has been high on the list for me as somebody who does do a lot of systems thinking, who does want to think about kind of an overarching whole of the software system and not get too lost down in the weeds. It's a great place to look for inspiration and find new ways, better ways to work.

~/podcast/episodes/073-software-imitates-life $ cat published.txt

~/podcast/episodes/073-software-imitates-life $ cat ../../copyright.txt

Copyright © 2026 - Crafting Code Podcast