Rob Pike says, “Simplicity is the art of hiding complexity.” If that’s true, what is simplicity in the context of writing software in Go? Is it even something we should strive for? Can software be too simple? Ian & Kris discuss with return guest sam boyer.
Featuring
Sponsors
Changelog News – A podcast+newsletter combo that’s brief, entertaining & always on-point. Subscribe today.
Fastly – Our bandwidth partner. Fastly powers fast, secure, and scalable digital experiences. Move beyond your content delivery network to their powerful edge cloud platform. Learn more at fastly.com
Fly.io – The home of Changelog.com — Deploy your apps and databases close to your users. In minutes you can run your Ruby, Go, Node, Deno, Python, or Elixir app (and databases!) all over the world. No ops required. Learn more at fly.io/changelog and check out the speedrun in their docs.
Notes & Links
Chapters
Chapter Number | Chapter Start Time | Chapter Title | Chapter Duration |
1 | 00:00 | Welcome to Go Time! | 00:44 |
2 | 00:44 | sam boyer | 00:32 |
3 | 01:16 | What is simplicity | 10:38 |
4 | 11:54 | Easy and uncomplicated | 01:25 |
5 | 13:19 | Pushing towards simplicity | 09:45 |
6 | 23:04 | Sponsor: Changelog News | 01:13 |
7 | 24:17 | Go Files | 02:20 |
8 | 26:37 | Rich Hickey | 07:14 |
9 | 33:51 | Where to put the simplicity | 09:23 |
10 | 43:14 | Simplicoty is in the disign | 10:38 |
11 | 53:49 | Heuristics you can follow | 02:11 |
12 | 55:58 | Pulling out the pin | 08:46 |
13 | 1:04:42 | "You shoulda built a train!" | 02:30 |
14 | 1:07:12 | Unpopular opinions! | 00:28 |
15 | 1:07:41 | Kris' unpop | 06:36 |
16 | 1:14:14 | Sam's unpop | 04:54 |
17 | 1:19:07 | Sam's 2nd unpop | 01:57 |
18 | 1:21:04 | Ian's unpop | 05:14 |
19 | 1:26:18 | Outro | 01:20 |
Transcript
Play the audio to listen along while you enjoy the transcript. 🎧
Welcome to Go Time. Today we’re talking about simplicity, what it is, how it applies to writing software in Go, and hopefully finishing up with some practical principles to help you write simpler software. With me today is Kris, who really needs no introduction. How are you doing today?
I’m doing great. It’s a sunny, but cold day. It’s nice though.
It was brisk out this morning. We also have Sam Boyer, a longtime guest of the podcast. How have you been doing?
I’ve been doing pretty well. Glad to be back.
Alright, let’s just dig right in. So what is simplicity? Rob Pike had this great talk, “Simplicity is complicated”, where he says “Simplicity is the art of hiding complexity.” He goes on to give garbage collection as an example, where under the hood, the garbage collector is extremely complex, but to the users it’s really simple. It doesn’t even have an API. So do you agree with Rob? Is simplicity the art of hiding complexity? Or is there more to it? What do you all think?
I think there’s more to it… But I can happily say “Not wrong.”
Not wrong. Okay.
That’s a good starting place.
Yeah. So to me, simplicity is kind of like a straight line, right? …versus hopping through hoops, and that sort of thing. Does anyone have a better definition?
I mean, I feel like Sam just has… There’s a whole spiel that Sam has.
[laughs]
I feel like some Rich Hickey is gonna get brought up here…
Oh, that’s the first thing I’m doing. Yeah.
Okay. Okay. Go for it. Go for it. Let’s hear it.
Yeah. Well, I mean – so that’s the first question I want to ask… I mean, Rich Hickey gave this talk 17 lifetimes ago in software terms, called “Simple made easy.” And it feels like the first thing to talk about is just what the difference is. What are the differences between those things, simple and easy. I have a theory… I could go, or not.
I mean, I guess I could give my perspective on this… Oh God, yeah, this is hard for me to articulate… But like, simple can be hard. So getting to something that is simple can sometimes take a lot of energy and effort, and sometimes things that are simple are not, say, beginner-friendly. It can be confusing and difficult and challenging to interact with something simple. Whereas easy, it’s just kind of like the – yeah, I don’t know if I can define them, but not in terms of each other. And I’m sure you have something, Sam. You definitely have something, so… Just go for it. That was a bad attempt. Go, go. Just go.
No, no, no, not at all. Because it is hard. So I think one thing we can note about the difference between simple and easy - and that talk starts by talking about words, which I love talking about too, and it’s part of the reason I love the talk… The history of words. But simple is something which, at least arguably, can be just like a property of a system. Something is simple, whether or not there is someone there experiencing it. Easy is saying, inevitably, something about a person, a user of a system and their experience of interacting with it. Did they have an easy time doing it? That’s one of the few clear things we can say.
And I actually do think it ends up being pretty difficult to talk directly about simplicity without getting back to some agent experiencing it… But I do think it’s worth at least sort of starting from separating out these concepts. Because – I mean, some of the other stuff that we can say about this… If we’re going to talk – it’s the art of hiding away complexity, right? Well, the question is how leaky is that abstraction that you made, usually. If you’re gonna hide away that complexity, is that something that somebody else needs to unhide later, because you made choices in the way that you hid away that complexity that wasn’t great? Let’s start there. I could say more, but… Yeah.
Yeah, I feel like for the simple versus easy component - I like that comparison of like a property of a system, versus a property of an entity experiencing that system… Because I feel like that puts it kind of on a not purely objective, but like objective versus objective spectrum, where it’s like what is easy for one person might not be easy for another… But that doesn’t necessarily mean that just because it’s not easy for someone, that the system isn’t simple.
And similarly, you can have very complex systems that some people find easy, even if they are still very complex. And maybe that’s kind of – there’s an element here of like group sizing as well. So perhaps we get more towards something that is simple the larger number of people that find it to be easy… I feel like there’s probably some relation there as well.
But yeah, I like Rob Pike’s definition of simplicity kind of being about hiding some of this complexity, because I think there is inherent complexity in the world, and you can’t always just reduce it down; you can’t turn all of the complexity into simplex things. I think attempts of doing that wind you up with very noisy APIs and things like that, where you’re like “Well, everything is its own little world, own little piece, you’ve gotta assemble all the pieces together…”
[00:06:02.21] So I think part of it is about taking complexity and putting simplicity around it… But that is – I think part of it is doing it in a way that isn’t leaky. I feel like if you make a simple, say interface for something, and it leaks the complexity out, I feel like then it’s not simple. You failed at your goal of making it simple.
I feel like the garbage collector is a good example of the trade-offs here. You can’t tune it, you can’t do a lot with it. It’s what you’ve got; you don’t really get to tell it what to do, for the most part. I think there’s like a knob, or maybe like two knobs to adjust what it will do. And they could have made it, they could have exposed more of that complexity to make it so you could get more closer to what you want, but that would have made it probably harder to use overall, and harder to use correctly. So I feel like that’s a place where they traded some amount of flexibility to make the whole overall system simpler, and also make it easier for people to use.
Do you think that in exposing some controls - because now, you know, certain environment variables tweak certain garbage collector behaviors, for example… Do you think the act of exposing controls can make the system intrinsically more complex, or things built around it?
Exposing more controls make the system…
Like, when there are more knobs – sorry, let me let me ask this in a less cryptic way. Sorry. If we expose no knobs, then certainly we can at least say it’s easy. We don’t know how much complexity we’re hiding away. Exposing more knobs can make it harder to choose the right knobs, in your case. So there we’re talking about the agent, the entity that interacts with the system, right? But do you think that the act of exposing knobs makes things potentially more complicated for the system itself, for the system designer, or for other systems that need to interact with that system?
I want to talk about the opposite of that. Do you think exposing too few knobs can make it harder to use, more complicated?
Yeah, sure.
It seems there has to be some middle ground there… So to me, making something simple and easy is exposing the right knobs, right?
Yeah. Which - wouldn’t we all like to do that?
So how do we choose those right knobs?
That’s the game, isn’t it?
Yeah. It feels like there’s not quite an orthogonal relationship, but it feels like these are two loosely-correlated things. So I feel like in my mind I’m like “Yes, you can add knobs to something, and it can make something more or less simple. And you can remove knobs from something and make it more or less simple”, and that in my mind means that these two things are perhaps related, but not directly related. Because if they were more directly related, then you could be like “Oh, removing knobs from something - that’ll make it simpler.” Or “Removing knobs from something makes it more complex”, and have it always hold that way. Since it doesn’t always hold, it feels like these are – like, you can make something simpler by adding or removing knobs, but it depends on the thing that it is, less on the simplicity itself.
That goes back to the objective/subjective thing. Right?
I think there are some objective things we could say about this. Like having two knobs that do the same thing is more complex, right?
Well, if you have two knobs that do the same thing, that’s just dumb.
If you think of like a command line utility, you often have like a log name flag and a short flag, and they do the same thing, and they are two different knobs, they are two different phrases you use… But I think that doesn’t necessarily add complexity to a command line utility, to have short and long options… But I don’t know, maybe it does. Maybe I’m wrong there. But it doesn’t feel like that inevitably does.
[00:09:53.29] That’s an interesting point. So let’s compare, if you have short and long form; that’s one way of sort of duplicating what’s being exposed. But if you have one flag, whatever, through setting the value of that flag on the command line actually implicitly changes the value that is passed or the set of values that are acceptable to pass to another flag. Now we are talking about a more complex interaction between separate parts of the system. And that can certainly make using a tool more difficult, like “Wait, why is it behaving differently now? Or why can’t I pass this value over here anymore, because I passed this value over there?” And that’s a bit different than – I mean, to me what’s complicated about that is that we can all learn the general rule of long and short flex; it’s something that I feel like is a sort of command line 102 type thing. You’ve got double dashes, and you’ve got single dashes. And yay! Not everybody follows that pattern, but once you learn that general rule, you have a bounding box that essentially all command line applications you interact with are going to fit into. But once you’re into a space where having – if you have a flag foo, and a flag bar, and you pass values to foo, and that ends up implicitly affecting the value that is used for bar, there’s no general rule that you can appeal to to understand the behavior of the system that you’re interacting with. You just have to tough it out. And that makes for a harder experience. But I’m not sure it actually – I’m not sure if that’s revealing something about the complexity of the underlying system, or if that’s even necessary or not… Yeah, I run in circles a lot on that, if you can’t tell… [laughter]
There’s a lot of semantics involved in like trying to nail down a precise meaning… Because I feel like there’s these three separate things of like you have like this domain of simple and complex, or like simplex and complex, and then you have easy and hard… And then you have complicated, and - I don’t know what the opposite of complicated is. But it feels like there’s these three different…
Straightforward.
I guess, yeah… And I feel like often people conflate these three different domains together. And I feel like that’s what makes it hard to disentangle them. And I feel like most of the time what people want is for things to be easy, and uncomplicated. And what they wind up trying to do is – or yeah, I think they want things easy and uncomplicated, and they think that making things simplistic will get them to that. And I think that usually, the way you get toward things that wind up being easy, uncomplicated, and simple is actually very challenging. And it doesn’t look like what people think simple looks like. So they go in having this conception of “Oh, something that is simple, easy and uncomplicated looks like X.” And it rarely looks like it. Or at least the process of producing it doesn’t look like X.
So bringing this back around to actually writing software… [laughter] So is simplicity not the thing we should be pushing for? Is it straightforwardness?
Simplicity is absolutely the thing we should be pushing for. I just think we have to help people better understand what simplicity means. Because I think when people think of simple, they think of easy, and they think of easy for them. They don’t think of easy for a broader audience of people. And when they think about simple, they think about uncomplicated for them, and not uncomplicated in general.
[00:13:50.14] I tend to say that people tend to want simplicity, but what they wind up building is simplistic. So it kind of looks and feels like it should be simple, but it’s not. It’s like inherently complicated and complex, and difficult to use for most people, but it’s easy for them. So they think it’s easy. Or it just like doesn’t do enough. If you do something in a simplistic way… It’s kind of like – I would equate it to kind of the broader sense of… Like when people say “Oh, a common sense solution to a problem.” It’s like, if you actually sit down and think about the common sense solution to problems, they don’t actually make much sense… It’s just like a nice talking point of like “Oh, you can just solve this thing.” And it’s like, well, there’s all of this nuance that you have to understand if you really want to solve this problem. And in software, it’s the same thing, where there’s all of this extra nuance, all these other things that you have to take into consideration to arrive at a simple solution. And people don’t really want to do that, so they go with the simplistic thing that appears to have done that without doing the work.
As far as its application to software, usually I think this comes up when people really – like the hype cycle things, when people are like “Oh, just use this one thing, and it’ll solve your problems.” Or “Just go download this library and it’ll solve your problems.” I think especially in the kind of dependency space, this is where it gets kind of a little overdrive, where people are just like “This is a solved problem. Someone’s already fixed this, someone’s already built this thing before. Just go use the thing they built.” And it’s like, someone has solved a similar problem to yours… But is that your problem? And if it’s not, then you’re going to have a solution that doesn’t really work well for you, and doesn’t wind up being simple; it winds up being simplistic, which just is not great for anybody.
So this is making me think about – I mostly agree. It’s making me think about a – you know what, I’m gonna put a cap on that. I’m gonna come back to that, because that’s a whole thing, and it’s more tangenty. Let me start with like a direct answer to your actual question, Ian, which is - on the one hand, yes, we should be striving for simplicity, because don’t artists want to make good art? And I picked those terms on purpose. The real question is “How much art versus dirty machine do you need to make in the moment that you are in?” It is really easy to fall down the rabbit hole of chasing simplicity, and recognizing what’s merited for the problem you are solving is the meta skill here that is key, I think.
Yeah, it does seem like there should be different standards for different things, right?
Yeah.
Like, something meant to be consumed widely should arguably strive for more simplicity than –
Probably, right. And of course, the difficulty is that even if it’s meant to be consumed widely, it doesn’t mean it will be. And at what point is it mature enough and consumed widely enough that it becomes worth investing the effort? And then you have the whole pile of crap you’ve made up to that point to get it consumed widely enough.
Yeah, I feel like that’s a place – because I’m going through this right now as I’m trying to actively build a web application server. And I guess this is – I have an unpopular opinion about this, so I won’t say too much about it… But it’s this desire I have to actually make this thing simple, and make it understandable… And one of the things I keep coming across is I keep asking myself this question; I always thought the answer would be never… Because I asked the question “If not now, then when?” When I have something I need to do? It’s like, okay, if I defer this thing, when am I actually going to do it? When am I actually gonna clean it up? Like, if I’m gonna stop chasing after simplicity, and stop trying to make this thing simple, when am I gonna come back and finish making it simple? And I guess there’s a precursor question of like “Do I need to make it more simple?” Is it simple enough as it is? Is it worth the effort to make it more simple? Because if it’s good, that’s cool. But I think that rarely we have that feeling of like “Ah, this is simple, this is good.” If we do have it, it’s for a fleeting moment, and then you start seeing all of the weird seams around things and you’re like “Yikes.” But that’s the thing I come back to, is I always ask myself “If not now, then when?” Because I think that helps with what you’re saying, Sam, with like “Well, if you do build something, and it does become popular, and you’re like “I’ll fix it later”, and then it’s popular, and you’re at later, and you have this giant pile of crap, and you’re like “Uhh, I’ve gotta fix this now”, then it just becomes like – I mean, that’s where we get to I think the last episode you were on, where you were just like “No, we’re just gonna greenfield it and throw the whole thing away and try again.” But if you haven’t tuned yourself to understand at what point you should push for simplicity, I think you’ll run into the same problem.
[00:18:35.19] So I think as far as a software application is concerned, I feel like there’s never a perfect point of simplicity, but I feel like it’s one of those gut things you have to develop, that intuition thing you have to develop, of being like “I have done, I’ve pushed this simplicity enough that we can move on to the other thing.” It’s not perfect; nothing will ever be perfect. There’s some edges that aren’t quite as softened as I’d like them to be. They’re still a little rough, but it works. So we can move forward.
So then, again, Ian - yes, we should be striving for simplicity. But how much in the moment that we’re in, is the question. And I agree, Kris, this is a – I mean, at the end of the day, simplicity isn’t a framework that you use; it isn’t a number of lines of code metric, and per function that you can follow. It’s not reducible to something, because I think when we talk about – when software engineer-ish folks talk about simplicity, what we’re really talking about is the criteria by which we evaluate our art. And those are never going to be finished things. So from each project that you do, as you make your dirty little machine, like we all do, how much can you learn? How much can you impove the craft, as you’re moving towards simplicity?
I kind of feel like perhaps simplicity lives in that realm of infinite things… Because - I think I brought this book up before, but there’s a book by Simon Sinek called Infinite Games, and it talks about infinite games and finite games. And there’s a lot of games that we play that are infinite games. Business is an example of one. There’s no such thing as winning at business. You either are in business and playing the game of business, or you are out of business, and you’re no longer playing. You cannot win business; you can snapshot it at a period of time, and be like “For this year, we were winning”, but there’s no such thing as winning business overall. And I feel like simplicity fits into that same category of things. Something is never simple. It’s a goal that we can never achieve, but it’s a goal we push ourselves toward, because it makes what we do better. And I think understanding that kind of helps with it. It’s not a finite thing. There’s not like “Okay, we can spend two more months and the thing will be simple, and it’ll be good. It’ll be simple, it will be great. It’s fine.” It’s like, it’ll have a snapshot of simplicity, sure, but there will be more things…
Because also, simplicity is fighting against complexity. And complexity is just – you know, time adds complexity to things. Things change, and that makes things complex. So you’re always going to be fighting against this deluge of complexity that’s trying to inject itself into your system. And so simplicity is like a fight that you have to fight forever, but you shouldn’t always be fighting that fight. Yeah, you’ve gotta like sleep, and eat, and do other things. You’ve got to build other parts of your system. You’ve got to ship something.
And ship. Also ship.
Yeah. You’ve gotta ship something. Right? That’s like the – one of the things I learned as a writer in school is your work is never done, but you have to publish at some point. It’s not going to be complete, it’s not going to feel complete, but at some point you’ve got to publish it, you’ve got to get it out there. You’ve got to get the words out there. And I think sometimes we as software people just don’t – we think that there’s a point at which it will look pristine, it’ll be perfect, “This is excellent.”
[00:22:01.29] I also think as a side effect of this, when we do find stopping points, we as an industry don’t know how to deal with that yet. Like, if you go to GitHub and look for a dependency, and it hasn’t had a commit in two years, are you going to use that dependency? [laughs] Even if it’s good, it’s fine, it’s working, there’s no bugs with it, it’s not going to be a problem for you - we have this discomfort with using things that haven’t been touched in a while. It’s like “I don’t know, there’s been no commits. It looks like it’s abandoned”, and it’s like, maybe that reached a level of simplicity where it’s fine how it is. It just doesn’t need anything more. It’s working, it’s good, it’s fine… But we have a an apprehension to that idea, I think. And I think that is in conflict with simplicity, because that means we don’t ever leave things alone; we keep wanting to touch things. And every time you touch something, you have a risk of breaking that simplicity, and making the thing more complicated and complex.
Software is the art of adding bugs to an empty file, right? [laughter]
So Kris, earlier you mentioned this game of simplicity is almost an intuition, right? Can you think of examples of things that make things simpler, or less simple? I can give you an example, too…
I mean for Go one of the things that comes to mind about – it’s a weird thing, but the way that we lay out files in Go… The actual code in a file feels like something that has this property of like… There’s a balance. It’s like, how many types do you put in a file? How do you arrange them? And at some point, it feels like “Okay, this file is getting too complex. There’s too many things in it. I need to split this thing out into other files.” And then there’s a point at which “Okay, this package is too complex. I need to put this thing into other packages.” So I think just like the way we structure code is a good example of this simplicity and trying to find a good balance in there.
I agree. And I want to be clear too, because I was [unintelligible 00:25:13.15] on like number of lines per function earlier… These criteria aren’t wrong… But when we talk about package organization, when we talk about number of methods on a type class [unintelligible 00:25:25.20] we are talking about aspects of the system where grappling with the questions about how you organize the code, how many properties it should have, how you split it up, how you distribute responsibility - that’s the way that you exercise and build your intuition about making something simple. And it’s this sort of visible ways that’s sort of obvious, surface, visible ways that we end up expressing simplicity in the software that we create… But it is not itself simplicity. It’s this sort of hidden variable behind all of it.
[00:26:05.04] Yeah. I guess what you’re saying is that we need – these heuristics we have are inherently useful heuristics, but you can’t… Like, if we were to say 50 lines of code is the largest of functions to ever be, making every single function in your codebase 50 lines of code will not make it simple.
Right. None of them are useful or correct in isolation. All of them are contextual and dependent. Learning how to contextualize the different metrics is the game. That’s the thing you were learning to build your skills. There’s a thing here - I want to jump back to Rich Hickey for a second, if we could, because I realized… Actually, I think maybe just in the lead-up to talking about this and this topic, that I think I might hear the name of that talk “Simple made easy”, differently than most other people did. I think the conventional interpretation of it might be – it follows the idiom that is common in English… Like, I don’t know, “Gardening made easy” or “Flapjacks made easy”, whatever. Task made easy. But I don’t think that’s what it needs. I think what’s interesting about that talk - and I think it’s interesting here, and Kris, you just made the sound like I think you see what I’m going for… But I think what’s interesting about the way that the title of that talk is constructed and the whole argument made in it, and part of what we’re circling around here is that indeed, to have a system, and our software artifact of some kind that is intrinsically simple, it has nice orthogonal pieces, it has clearly-defined bounds of responsibility, you can reason about and predict its behavior, it composes well with other things, does not in any way guarantee that it’s going to be easy. You might need to have – you know, simply enough, interacting with it might require 10 lines of code, instead of the ideal one. So that talk is really about that [unintelligible 00:28:01.19] How do you take something that has the intrinsic properties of being simple - so we’re just kind of assuming that those exist and are definable - and make it into something that is easy? How do you span that gap? And I do think that’s a useful way of thinking about this, because as we think about trying to put simplicity in our software, I think a lot of what we’re thinking about is “How well do I understand the problem that I’m trying to solve? How well have I translated that into the software that I’ve made? And how crisp, orthogonal, elegant does it feel to me, and to what extent do I feel like this is just now something that’s solved?” Like, whatever I was setting out to do, it’s done. There’s that whole process. And that is almost entirely separate from how easy the interface is to using that thing.
You can go through this whole process of sorting out this problem you’re trying to solve, its relation to the logical or physical world, whatever, and still have a god-awful, absolutely not usable, absolutely not easy interface. And yeah, so part of the reason that in addition to the fact that sometimes it’s just not worth it, or what you’re doing, to spend a whole bunch of time trying to find that kernel of a simple system for the problem you’re working on. These are really to me kind of – well, they’re not totally separate, but semi-separate things. How do I understand the system, the thing that I’m trying to do well enough? And it’s interrelated parts, and tidy it up, its internals, and then how do I build the surface on top of that?
Right. So I’ve got two things on that. I think the first is – maybe I haven’t always, but for a very long time, I’ve always read that “Simple made easy” as “How do you make simple into something easy.” I didn’t realize there was the other interpretation of like “Oh, this thing made easy.” Like “Oh, we can just – this is how you do simplicity in an easy way”, not have you transform simplicity into something that’s easy.
Yeah. What’s weird is I think most people probably have the same interpretation, but the way that it gets talked about ends up mostly being the other one, that like “Oh, it’s easy to do simplicity. This is sort of the way that you think about it. [unintelligible 00:30:14.02] you’ve made a simple system.” No. [laughs] Sorry, go ahead.
[00:30:20.08] Yeah. And I guess the second thing, the thing that kind of popped in my head is that it sounds like a divide between kind of what we traditionally think of as the software building process, and the product management process… And then on the simple side you have like, okay, we’re trying to make the software, we’re focusing on the software itself, whereas kind of the focus of product management largely is like the users of the thing, and how will they be able to interact with this thing, and making it… I mean, I feel like most project managers will say “Yeah, I want my product to be easy for the user, whoever that user is, or whatever set of users I have.” That’s their goal. So I feel like in a way it’s kind of marrying these two things together, being like “Yes, we understand a lot of the heuristics of how to build simple software, but now we also need to use the heuristics of how to build easy software, and then bring those two things together, which is the challenging part… Because a lot of things that make software simple, make it harder to use, I think is what you kind of brought up there.
Yeah. It’s often verbose.
Yeah. I think this is what we get from like the – I think type systems are a good example of this, where people are really like “No, no, you have to have a static type system. This makes a system simpler, because everything is known.” But it’s like, sure, but it doesn’t make the system easier; it doesn’t make the language easier for people to use. I think that’s kind of the big debate happening in TypeScript land, and people being like –
[laughs] DHH is going to swoop in and sprinkle some middle fingers all over that perspective, yeah…
Yeah, yeah. He’s just kind of like “Oh, no…” People are like “Types! You have to have types to make things simple.” I think that’s a good example of perspective as well, in position; the thing I dislike about the whole ideology around like “Static typing is required and necessary!”, it’s like, we’ve been building humongous applications in JavaScript for decades. We’ve been building things in Erlang, and in Lisp, and in PHP, and all of these languages that are dynamically typed, and we’ve built amazing systems. The web still runs on PHP, right? It’s still a whole bunch of WordPress, and Drupal, and all of that stuff out there. And it works very well, and there aren’t any – there’s not static typing. And everything’s okay. And it’s like, yes, in some contexts static typing does make things simpler, but in other contexts it makes things more complex, or sometimes it makes things you want to build impossible, because of – and I think that’s how we wound up with most of the languages we have being hybrid. Go is statically-typed, but it’s also dynamically-typed. We can do reflection, we can use an empty interface, or any, we can use all of this stuff that like scoots around the typesystem when we need to. And I feel like that’s another place where it’s like the balance of like “Well, who are your users, and what are your users expecting?” If your users are expecting a statically-typed thing, and you give them a dynamically-typed language, it’s going to be very hard for them to use, regardless of how simple the language is. And the inverse is true as well. If you hand a statically-typed language to someone that’s expecting a dynamically-typed language, it’s going to be hard for them to use, regardless of the simplicity of the language itself.
I think this is one of the tough things about learning Rust, is that it’s like “No, no, Rust is a very elegant system, but it expects you to be a very specific type of human. And if you’re not that type of human, and you don’t want to become that type of human, Rust is probably not going to be the language for you.” No hate on these programming languages; I think they’re all wonderful, they’re all beautiful, they’re all useful for things… Clearly, none of them are as good as Go, because this is Go Time. However… [laughs]
[00:33:46.04] Talking through this all, I’m starting to realize, simplicity is not going to – it just can’t always happen. There’s always gonna be complexity. So the choices we’re making is where to put the simplicity, right? Like, where does it belong?
Yeah, you cannot eliminate complexity. You can’t get rid of all of the complexity. I suppose maybe if you build absolutely nothing, you can get rid of all the complexity, because then you have nothing, and nothing is pretty simple… But if you build something, you have complexity, and you inherently have more complexity over time. So it’s always this battle of really reducing the amount of complexity down to a level that we call simplicity.
I feel like that’s kind of the thing of like I don’t really know if – it’s either a scale of complexity, or a scale of simplicity. And it’s like, one end is enough where we would say “That thing is now simple”, or “That thing is now complex.” But I don’t think they’re kind of like static things, where it’s just like – there are simple things, there are complex things, and that’s it. It’s not a binary; it’s like a scale of some sort. And there’s a point at which we’re like “Okay, that thing’s not simple anymore.” But we don’t really know where that point is. We don’t really know where those things exist.
I feel like it’s kind of like temperature, where it’s like “I don’t know, is it hot out?” And like “I don’t know. it depends on who you are and where you are and what you consider hot to be.” I feel like that’s the same with like “Is it simple?” There’s a lot of subjectivity that goes into whether something is simple or not. It’s a different subjectivity than the easy/hard, but it is a subjectivity in and of itself.
I think that’s the thing from No Silver Bullet from up on 40 years ago… The No Silver Bullet paper, essential versus accidental complexity. What is necessary to the problem you’re trying to solve? What is an extraneous result of frameworks you’ve used, misunderstandings of the problem you were trying to solve, bad scopings, boundaries etc? And then yeah, how worth it is it to try to actually chase the essential complexity of any given problem? …which does suggest something practical, right? And it’s not groundbreaking, but understand your problems first, understand your users, make a reasonable guess based on what you know right now about what you think both the sort of essential nature of the problem you need to solve is, and what aspects of that are most likely to change. Do not get sucked into the rabbit hole, because you cannot predict the future, and don’t try. And then make an estimation about the quickest and dirtiest way that you can roughly approximate what you think that essential part of the problem is, that will fit inside of the time you have to solve it in… Times two, because - give yourself some buffer, because nobody can estimate. [unintelligible 00:36:35.08] And then go and make a thing, and get in the feedback loop.
Work through all of the different things we’ve talked about; look at the number of lines, try to organize things in a way that makes some sort of sense in your head, work on your instincts about why you would organize things together… Keep a notebook about why you chose to organize the things in the way you have. Or part of the documentation. Come back and check those assumptions later. As long as you take the outlook that achieving simplicity is an art, and not like a form of measurable engineering, I think it’s a lot easier, because then you accept that it’s something you’re going to work on, and improve, and hone your craft, and not this end outcome that has to be hit in every case.
I feel like there’s this interesting – I don’t know what it was you said, but something you said kind of reminded me that there’s this… Simplicity is a part of the design of the thing, and I think that we think it’s a part of the building process of the thing.
Yeah.
[00:37:46.21] Because I’ve been thinking a lot about engineering, and how engineering is really – and I think that it doesn’t get brought up enough when we talk about this, like, “Is software engineering engineering?” discussion… Is that engineering is a subfield of design; what engineers do is they design things. They don’t build things. And I think the fact that we in software forget that means that we expect both the thing that we are designing to wind up being simple, and we expect the way that we build it to be simple. And I think that the process of building the thing will almost never be simple. It’s always going to be pretty messy, and kind of just – as you were saying, that dirty machine at you’re building. Like, I’ve been watching a building be constructed, and one of my friends is a civil engineer, and I keep pinging him with questions, being like “Hey, why are they doing this thing this way? Why are they doing this in that way?” And most of the time his response is “I have no idea, because I don’t know how building – I design buildings for their final state. I design for the thing that’s going to be at the end. How that thing gets built is up to the construction people.” And the construction people use all sorts of weird tactics to actually build things, and actually put all the things together, and it looks like chaos. And then eventually, it just comes out, and it’s like this beautiful thing.
For a very long time I always wondered, how do they actually build a skyscraper that is just concrete? Concrete floors, with pillars… How do they get the concrete up there? And I was like “Oh, they have concrete pumps.” I’m like “Where does the floor come from?” It’s like “Oh, well, they just take a bunch of metal poles, and a bunch of like wood, and some plywood, or maybe something a little better than plywood; it’s probably something else… And they just build a floor of wood out of it. And then they pour concrete on top of it. And the concrete then cures, and it just holds itself up with like support columns, and all of that.” And then they take away all of the wood and all the poles, and all of that. And I’m like “Oh, so they just kind of like build a fake structure to build the thing, and then they take that fake structure away.” And I don’t feel like we do things like that in software. I feel like we just try and jump right to the “What is the final thing? Let’s go build that right now”, when maybe there’s this intermediate step where we have to build something that we’re gonna throw away… But we never really want to throw things away, so we never really want to do that step. And so we come up with really weird Rube Goldberg machines for like how we actually manage to pour a concrete floor. It’s like “Oh, we don’t want to build the structure we’ll tear down. We don’t want to build scaffolding”, as much as we love that word. We don’t want to actually build it, because that feels like a waste. So we’re going to find some other way to like lift slabs of concrete in the air or something, and make this work. And it’s like, there’s a simpler way, but you have to embrace the fact that it’s going to be like complex and messy. Or I guess there’s an easier way, but you’re going to embrace that it’s going to be complex and messy, and you will still get to the nice thing at the end; the beautiful building that you want to have… But the actual process of constructing that is going to be a bit gross.
I feel like we as software engineers, we want the entire process to look beautiful; we want the entire process to be simple and easy and straightforward. And I think our avoidance of that is what often leads to just like the absolute messes that we wind up with.
I mean, I’m also with you, except - I want to go back and say maybe you don’t get to that end structure. Maybe you do eff it up. And maybe you were right all along that the messy stuff that you were doing along the way was too messy… And it keeps you from getting to the end. that’s a real possibility.
There’s nuance. There’s that one saying that people have when they talk about other fields of engineering, and they’re like “Well, bridge builders, they never have to move bridges. Haha!” It’s like, there’s entire books about how to move bridges if you built them in the wrong place, or you built them incorrectly. This is a thing that happens and we have to like deal with… So it’s like yeah, sometimes the messy part is like “No, there’s something wrong here, and we need to go back and fix it.” But that’s also why you need to have engineers and designers in the process. It’s not like they give you a design and then they just walk away and go to something else. No, they’re involved in the entire construction; if they understand the construction process, they’re involved in it.
[00:41:58.05] Same thing with a lot of fields. Same thing with like television production, where the writers are usually involved in the entire process; they’re on set, they’re like rewriting parts of the script that don’t make sense when they’re actually trying to film the show… But in software, I feel like a lot of the times our designers, for as much as we have them, kind of don’t touch the actual building process. They’ve come with this elegant design, they handed us some team, and then that team builds the thing. Or we try and make designers that also build the thing themselves. There’s not like a very good separation between “Hey, you’ve designed the thing; you’re not actually building it, but you’re intimately involved with the people that are.” I feel like that line is not one we’ve figured out how to navigate very well. There are people in every company I’ve been in that do this, but it’s not like a thing we can train people to do. It’s not like a thing that’s written down, that’s just like “Hey, we have a good staff or senior staff or principal engineer that does that thing.” But you also usually have a pile of people who are very bad, and don’t do that thing, and it’s like “Okay, well, we need to figure this out as an industry.” Sorry, that was just a tangent I went on. I went somewhere… [laughter]
You said something earlier, before that little rant, that simplicity is in the design, maybe not in the implementation. Right?
Not in the implementation, in the building process specifically.
Well, yeah. Okay. That feels similar. But… I don’t know, that feels important.
Yeah.
I think it goes back to what Sam said earlier - avoiding non-essential complexity. So if you design your system in the simplest way possible, avoiding complexity without… That’s not necess– I don’t know, I feel like I’m just rambling here. But I don’t know, what I’m getting at is it feels like the design process and thinking through it upfront can almost automatically lead to simpler software, right?
Yeah. I mean, that’s – I wouldn’t even necessarily call it the design process. It’s like requirements gathering. What problem are we trying to solve? And then what other problems is it enmeshed in, [unintelligible 00:44:05.12] But especially if you are a relatively new software engineer, trying to figure out how to grow, and you somehow made it this far into this episode of people talking about handwavy complexity things, then the only part of this that I think you can really think your way through real super-hard, and have it actually be useful, is the part where you try to understand the problem really well. What is the actual problem that needs solving? Who needs to solve it, dare I say? …because the humans do matter. Why they need to solve it. What are they really trying to do? Because the betterer grasp you have on that, the more fixed the sense of what might be essential and might be accidental come after that. And those are the things that really affect stuff.
So spend your cogitating time on that, and then pick a framework for – if you’re doing HTTP things, pick a decent, popular one… I don’t know, if I were to give – like, pick things off the shelf, right? Limit your surface area. Don’t try to make everything perfect. But try to learn about how other people have designed things in ways that feel simple, and try to make that distinction between things that sort of are maybe just easy to get started, versus things that actually end up feeling simple, all at a time. Take notes, write down your hypotheses…
The things that I tend to look for are indeed – if I feel like the documentation is reasonably broken down so that “Here, we can talk about one concept over there, and one concept over there”, and the controls for them are relatively separate function calls that expose types, or whatever it is, that tends to be indicative of it. But form your hypothesis about whether the thing that you’re considering using is simple or just easy, and grab it, try it out in the context of your problem, see if it seemed right or not. You cannot think your way through implementation; you can think your way through understanding of the problem. So understand the problem very fast, and just get in the feedback loop.
[00:46:16.18] Yeah, I think – I mean, I definitely agree with that. I think the place where I – because once again, I’m literally trying to go through this right now, and I want to build a web application server. And I think the thing that I keep coming across is even in the process of trying to design something simple, the hard part is actually knowing things. I feel like understanding how – even just HTTP is mind-bogglingly complex when you want to sit down and actually learn how the thing works. An example of what I’m going through right now is I’m just kind of like “What does modern day SEO look like? What does Google care about? What does DuckDuckGo care about? What do all these web search crawlers care about? How should you represent just the HTML of your page? What tags should you have in the head?”
You have to sit down and think about those things and think about whether you care about them… But in order to know if you should care about them, you have to know what they are. So I feel like there’s this other precursor part of life a very useful part of designing things is acquiring knowledge that you can use later. Kind of what you’ve been saying all along, Sam, is you need to have these feedback cycles of “State your hypothesis, then go do something, then come back to it and see how right you were.” Because that’s the process of learning, is seeing yourself grow and feeling that, and making yourself be able to move forward. And I feel like people often rush to go grab stuff off the shelf and be like “I just need to build something.” And it’s extremely challenging to resist that temptation. But resisting that temptation I think is was what leads to you being able to design and build things that are simple. Because fundamentally, you have to know how things work if you want to build something simple, if you want to design something simple. If you don’t understand how the things work, you have a very low chance of designing or building something simple. And I feel like as an industry, we have pushed ourselves very far away from that. And I feel like Go as a language is a very good language to do this in, because there are so many of those basic pieces in the standard library… Building an HTTP server is a good example. You can just take the HTTP library and then build what you need with it. But it gives you very little. So you have to understand all of the stuff you need to build on top of it. And sure, maybe the stuff you build on top of it isn’t what you put into production, because it will not give you the levels of scalability or whatever that you need, and you need to pull something off the shelf. But by actually building the thing yourself and acquiring the knowledge, now you know what you need to go acquire, what the right off-the-shelf thing is. Because if you don’t understand it, and there’s this whole sea of options in front of you, maybe you’ll pick the one that actually solves your problem, but you’re probably not going to pick the right thing that solves your problem.
So yeah, I guess the kernel of that is when you’re in the design process, go build the stuff yourself. Don’t necessarily put that in production, don’t necessarily implement it with that stuff, but at least make sure that you understand how the thing that you’re trying to build works, to a low enough level that you can actually make this simple. Because if you don’t, then you’re gonna have complexity that you’re not dealing with, and it’s going to break through whatever abstraction or interface that you’ve created.
Yup, makes sense.
I’m supposed to be saying unpopular things. You’re supposed to push back and be like “No, Kris. That makes no sense. You should just go pull stuff off the shelf.”
I mean, I agree with you… I’m not sure what you’re saying is entirely practical… But I think while it might not be practical, it’s important to do some impractical things in your career, and learn from them. Doing that impractical thing now will gain for later, right?
[00:50:00.02] Yeah. Once again, it’s part of the infinite game. It’s part of this – we’ll never have simple software; that’s not a thing that will exist. We’ll have software that is more simple, or more better than it was before. And the same idea - the United States has the whole thing in the Declaration of Independence that’s like “All men are created equal”, and all of that, and that’s just a vision for the future. Will we ever get there? I don’t how practical is that to actually do that. That’s a very challenging and fraught proposition to push forward, and we’re gonna get it wrong a lot of the time, but we should still always be aiming to do that. And I think that same thing applies to like software design, where it’s like we should always be aiming to acquire more knowledge for ourselves and build something that’s simpler. And there’s limits. As you said in the beginning of the episode, Sam, you can’t go down the simplicity rabbit hole forever… But I think it’s important that people understand that you should be going down that rabbit hole a little bit each time you design something; learning something a little bit more, understanding how things work a little bit more, for practicality reasons. Sometimes you won’t be able to do that, but I feel like the place where we’ve wound up in Go and in most places in software is that we just don’t do it. Like, the number of times I had to fight with people to just get them to do really basic design, to just understand how something at a very simple level works with Go, dig in a little bit more to a problem instead of just saying “I think it’s all good.” It’s just, it’s been too much; like, I’ve had to push too much to get people to do these things. It’s like “No, keep pulling that thread.” It might unravel the sweater, but better unravel it now, than it unravel when it’s in production. You don’t want to unravel the whole sweater when you have terabytes of data and you’re serving tens of thousands of customers, or whatever. Do it when you have no customers, when you have nothing, and make sure that it’s not gonna just fall apart when you don’t have the resources or time to fix it. And that’s a difficult balance to make. It’s not something you can predict. The future, as I said I think two episodes ago, is an unknowable unknown; you cannot know what will happen in the future. But we can get pretty good at predicting what might happen. And I think at this point we need to start predicting – we need a better path for people learning about this stuff, about simplicity, about how to do simplicity, and it does require that we just sit down and do the work.
So it can’t be to some level that’s like “Oh, no, only do this if you have time.” It’s like, no. Make the time, but balance that with everything else. And yes, sometimes you can skip. It’s like working out. You have to work out, each and every – not every day, but you need to have a schedule. And sometimes you can skip, sometimes you can cheat, but you can’t cheat all of the time, because then you won’t be getting the thing that you want. And I feel like software design and simplicity is that as well. You have to fight for it. It’s not going to be something that, right now at least, your organization or your co-workers or whoever is likely to be completely on board with, so you have to balance it, but you need to start introducing it, and start having people see the benefits of it, and start, once again, tracking the “Well, what did we think it would take, and how is it actually?” and start building up that evidence to do it. Because that’s how I think we actually, as a whole, get ourselves towards simple software, and towards simplicity, is by taking these tiny steps.
So make sure that, as small as it is, you’re doing something on every project. You’re doing some design. You’re pushing back a little bit. Don’t risk your job, obviously, but…
Or do…?
Or do. I mean… Sam, we’re gonna get into unpopular opinions soon. I mean… [laughs]
On that note, we’ve done a lot of talking, we’ve done a lot of kind of debating back and forth… I’d love it if we could each just take a key point out of what we said… One heuristic you can follow on a project to make your software simpler. Just like a recap.
[00:54:09.17] I would say… This is gonna sound very typical for me, but document in comments what you’re doing. Like, I think if there’s one thing that has helped me write simpler software, especially simpler Go, is actually having to write out in prose what the thing I’m trying to do is doing. And I often have realized that I’m not building that thing, and that there’s some more thinking I have to do. So actually sitting down and writing the comments, even though you’re like “I know how this thing works. I understand how it works. I don’t need to–”, it’s like, just do it anyway. Write the comments and make sure that what you think you’re building is actually what you’re building.
What about you, Sam?
Can I expand it to two and a half, as long as they’re tight? Is that alright?
Go for it.
Yeah, that’s fine. Yeah, go for it.
It’s reiterating what I said, but… Spend your thinking time understanding requirements. Spend your writing time getting in a feedback loop. And in a scientific mindset, testing out those things that people say about what makes software simple, and seeing if it feels like it applies inside of your feedback.
I feel like I should throw that nice Richard Feynman quote in there, that “Science is the belief in the ignorance of experts.” It feels like it fits there as well.
I mean, how else are you gonna get to the point of having an unpopular opinion? [laughter]
Ian, what about you? What advice?
I think my biggest one would just be choose where to put the simplicity. Be thoughtful about where that simplicity goes… Whether it be at the edges, or - I think it probably should be at the edges, right? But yeah, be thoughtful about where the simplicity goes. Does that make sense?
Yeah, I think so.
I have a funny thing here… It’s a thing that I put a pin in earlier, which - I don’t know, you can cut the whole thing later if it doesn’t work, how about that? …but I’ve been staring at this chart, which is in a YouTube video called “You can’t get snakes from chicken eggs”, which is from one of my favorite anti [unintelligible 00:56:16.18] YouTubers. And he’s talking about in the case of “You can’t get snakes from chicken eggs” how arguments about evolution often go for those who do not believe in evolution. They will come up with these super-simple, tight little statements like “You can’t get snakes from chicken eggs.” And that’s tiny. It’s a pithy little sense. The explanation about how you get snakes from chicken eggs, or whatever, is actually a much longer, thicker explanation about intergenerational mutation, and selection pressures, and blah, blah, blah, blah. But the chart that he puts up – well, a chart that he puts up is the notion that accuracy decreases as we try to make something more pithy… Easier, shall we say? He uses the word simple, but I think what he’s actually saying conforms more to easy. It is easy to understand you can’t get snakes and chicken eggs; it feels right. But there’s a truth floor.
There is no limit to how simple an idea can be when it doesn’t have to conform to reality. There is no limit to the amount you can do in a single line of code when you don’t have to think about larger implications, or consequences, or whatever; how much should we reduce the complexity of that interface, to the point where it’s super-easy to do.
What I like about his construction of this - you’ve got side by side charts, which are like accuracy on one axis, and sort of ease on the other - is you don’t care about conforming to reality, about sort of dealing with the implications of making a super-easy interface, and you can crank that thing all the way down. Best of all, you can train an AI to just like do that thing just by firing text at it… And, you know, look how well it performed on that one little bit of text that you sent it for this particular task.
[00:58:14.16] If you do want to care about the conformance of the underlying system to the reality of the problem you’re trying to solve - well, it’s an awful lot harder. You have to deal with fundamental limits; you have to deal with the patience of trying to design a system to actually take care of that reality. You don’t have to pick one or the other all the time. Ian, like you said, where you put the simplicity, right?
To me, the difference between caring about whether or not you have an accurate understanding of how you get snakes from chicken eggs, or how evolution fundamentally works, versus having a pithy explanation that feels nice in the moment is analogous to the difference between “Did I fundamentally understand the problem correctly, model it correctly in the programming language that I’m working in, cut out all unnecessary pieces, do it in the fastest, most performant, or most efficient rather, way possible (performant is not a word), and then put the sort of easiest interface on top of that, that I reasonably could…” Versus “Did I slap together a thing that solves the one use case that the people with power care about seeing solved?”
The thing I thought when you kind of said the truth floor there… So I feel like that’s the point at which simplicity turns into simplistic, or something simple turns into something simplistic.
If you bust through it.
Yeah, if you go through it. And that is also a way, I think – what I mentioned earlier about common sense, that’s where those types of things live, where it’s just like, you have reduced the problem down to something that is wholly impractical. So you can’t just solve it. And I think there’s a little bit of irony in some of these things as well, because I think some of the pithy things would at least partially solve the problem. Homelessness is like the example that comes to my mind. It’s like, just give people homes. And it’s like, actually, it turns out that could probably fix a big chunk of the problem. Or it’s just like, I don’t know, maybe just giving people money will in fact make the economy run better. So people are like “It can’t possibly work.” And then you give people money, and then all of a sudden the economy does well, and…
It turns out the problem with being poor is just you don’t have money. Holy crap… Sometimes it’s simple. Yeah, sorry. Go ahead.
Yeah, well, that’s a nice, pithy, simple thing. And then you have these other things, these other pithy things that are just like “No, that’s simplistic.” You have to disconnect from the basis of reality in such a way that you can’t actually do that thing. And I think we, definitely as an industry, and maybe part of the reason why society is like this, is because of software people doing things, thinking the world is much more simplistic, and thinking the world is simplistic, and simplistic things will work… It’s very difficult for people to differentiate between those two categories of things, of like the pithy things that are simple, and the pithy things that are simplistic. And I feel like there’s a lot of thought in software engineering and in tech about just “We can solve things in very simplistic ways.” A lot of the takes on transportation I feel like fall into this bucket, of just like “Make the cars drive themselves. That’ll solve the problem.” And it’s kind of like “Do you understand how actually challenging that would be?” We can barely get elevators to drive themselves, and trains to drive themselves. And now you’re talking about this – and yeah, it sounds like a nice, easy thing. Or the same thing with the large language model explosion, where everybody’s like “This is going to take over everything.” And it’s just like “Well, not quite…”
[01:01:52.00] Oh, it will. I think it will. But yes, sorry. Go ahead. [laughs]
[unintelligible 01:01:52.11] Well, I mean, it does well at some things, but it’s a very nuanced thing. You have to understand a lot about how this thing is working, to understand where it’s applicable, and where it’s working. But I also think sometimes those simplistic things wind up – the fears around them wind up being things that already exist. AI is a good one, where people are like “AI is gonna take over the world, it’s gonna make life terrible.” And I’m like “It already has. We’ve been using algorithms for a very long time, and it’s made a lot of things very bad.” We’re here, so let’s solve this problem. And a whole bunch of people are like “No, no, no. Now that we have ChatGPT, that’s what’s gonna make everything bad with AI.” It’s like, “No, no, no, we’re already in a place where it’s bad. Let’s come up with technological solutions to fix this problem.”
But I think that kind of breaking through the truth floor and getting to that simplistic, common sense thing is like “Well, no, no, the way that AI will take over things in a common sense perspective is through something that can talk to us at a language level, and we’ll just be super-smart.” We can see it now, so that’s going to be the problem. And I feel like the roots of a lot of that stuff live in the software world, where we’re just – like, so many times I’ve heard the… I’m really gonna keep saying it - it’s a solved problem thing… Of like “Stop trying to build this thing, it’s a solved problem. We already have a solution.” I’m like, if it’s a solved problem, definitionally, it’s not a problem anymore, so we don’t have to do anything. So if we have a problem, it’s clearly not solved. So someone might have solved a similar problem, but they haven’t solved this problem. So we have to actually add that nuance back, to figure out what are the things that have been solved and what are the things that haven’t been solved, and come up with a solution that works for us.
But yeah, I feel like that truth floor… I don’t know, calling it a truth floor is weird. But that simplicity floor I think is something to be very mindful of in building software, of that if you do break through that floor, and you wind up in a land of simplistic solutions, the software you build will not be simple, it’ll likely be very complex and very confusing, and very complicated, and hard for your users to use.
If it needs to flex in ways that you didn’t anticipate when you [unintelligible 01:04:09.28]
Or even if it needs to flex in ways you did anticipate, it can still…. Just be very mindful of that floor that exists.
We can add that to our list of heuristics - build simple software, not simplistic software.
Oh, God, that sounds like a troll… [laughter] It just like assumes the whole thing. Developing your intuition - Kris, what you were saying… Can I tell if this thing is simple enough? That’s the whole problem here. It’s all aspirational. How can I tell if this thing is simple or not? How can I tell if it solves the right problem or not?
I do have one bit of good news though, one bit, which is at least when it comes to those transportation things that people are trying to solve - there is a good heuristic to tell if it’s BS or not. And if they mention pods anywhere… Anywhere in their promotional materials - no, it’s a bad idea, and you should build a train instead.
The car obsession. It’s like, how can we sneak a car into this thing? It’s like, how can we take a thing that works, how can we take the train and turn it into a bunch of cars?
The Tesla track in Vegas?
Yes, that’s a good example. There’s also a bunch of other ones… There’s another wonderful YouTuber on this, I’m completely stealing his this thing by saying “You should have just made a train.”
I think that’s Adam something… There’s a bunch of them. Because I think he’s the one that also was making fun of the Tesla truck, where… Or maybe I was just talking to someone, but I was just like “Well, what happens if some AI pulls over the truck and just takes all the stuff out?” It’s like, “Well, you have someone in the front that’s driving it. And then a bunch of AI trucks following behind that truck.” And I was like “So a train…”
[01:05:51.12] So a train. [laughter] I mean, he has more than a million subscribers, and built a whole lot of it out of just “You should have made a train. That’s a train. That’s a bad train that you’re describing right now. You took the good ideas from a train, did a cute 3D render, and then like rubbed some technology on it, and… No, it’s a bad idea. Just make a train. Stop what you’re doing.”
Yeah.
But it’s funny though, because the way that those often work is indeed “Wouldn’t it be easy if we just took this one thing that works super-well, and that we can tell a slick story about”, and then like “We made a system out of it that scales to millions of people living inside of a city.” And actually it doesn’t, of course. But you tell this crappy, but slick, easy-sounding story, and it disregards the fundamental complexities of the underlying system.
It does feel like that’s what a lot of software is. Especially, once again, dependencies. So I think dependencies are what tends to make software a little bit more complex than it needs to be. I feel like there’s this vision of dependencies of like “Oh yeah, you can just bring this one library in, and it’ll solve this problem.” And then you just hit up against reality, and it’s like “Oh. Oh, no. This is not going to work the way I thought it was gonna work.” We’re getting so close to my unpopular picking, though…
Alright, let’s do some unpopular opinions.
Jingle: [01:07:16.15]
Alright, who wants to go first? Kris, you’ve been itching at it the whole time…
Okay. Okay, I will go first. I guess the premise of this is I’ve been reading this book called “Recoding America.” It’s a fantastic book; it’s by someone that works in like the Obama White House, like within the CTO office… Basically, the premise of the book, the whole point of the book is that government has become very good at procuring technology, very bad at building technology. And I think that we as software engineers have essentially done the same things to ourselves, where we’ve become very good at procuring software in the sense of finding dependencies, and finding things that do the thing we want, and then kind of smashing them together into the larger thing that we want… And we’ve become pretty bad at just building the thing that we need, and using some of the stuff, some of the dependencies. I think we’ve become too dependency-heavy, and I think we should nope out of that, and go back to being builders… Because I think we are absolutely terrible at procurement.
So yeah, that’s it - we are spending too much time trying to buy, not necessarily with money, but buy our software, and we are very bad at doing assessment around how to buy software, and we should just be focusing on building it instead… Even if that means sometimes you are reinventing the wheel. Yeah. Because I think if you really sit down and you think about what it takes to properly procure any type of thing in a business… If you even mention Coupa to software engineers, if they know what it is, they likely have this fear that gets stuck into them, of like “I don’t want to have to do vendor management and vendor risk analysis.” But it’s like, if software is at the core of your business, then that supply chain of software should be validated. Like, every dependency you have, and likely some degree of the dependencies of your dependencies, you should have vendor records around it, you should have risk management done around it, you should have assessments done, to see if it’s going to be a viable, useful thing into the future.
There’s a lot of extra work we should be doing to secure the supply chain for organizations, and we just do not do it. We just go pull some random crap off GitHub and be like “Here, we’ll use this now.” And that is being very bad at doing procurement, because half the job of procurement is making sure that the thing you’ve procured is actually proper and fit for what you’re trying to use it for.
[01:10:06.09] But I think on the other side, because we’ve been so focused on this whole “probably found elsewhere” methodology, some communities definitely more excessive than others, we’ve also sort of forgotten how to build stuff ourselves, or at least we have an ethos now that like building stuff yourself is seen as like dirty, or you’re doing it wrong, or you’re just trying to play around instead of being serious. It’s like “Oh, why are you implementing that yourself? There’s a library that does it. You should just use this library instead.” And I think that’s just really bad.
Once again I’ve been coming up against this as I’m trying to actively build my own stuff, or at least build something without other people around to help me. It’s been a lot of like me sitting down and having to ask myself over and over again “Am I trading a building problem, a software construction problem, with a procurement problem?” Because what I want to be good at is building software; I don’t really care that much about procuring software, and that side of things.
I think that we don’t as an industry take it seriously enough to understand if we really want to be procurement specialists, we should actually go become good at procurement. I also don’t think most software engineers would like that proposition at all. If you’re like “You can continue using open source software, and dependencies, but for every single one you must go to this awful software called Coupa, you must enter all of the vendor information, you must perform a large risk assessment that includes conflict of interest resolution, and all of that, and then you must also periodically review that vendor to make sure they’re doing things properly. And then you must also review all the source code to make sure that it is up to snuff, and make sure to do all the proper licensing checks, and all of this stuff.” I think if we put that requirement in, which should be the requirement, there would be a very large drop in the usage of most open source software. There’d be vendors that you go to get specific open source software, and they would have all of the things in place to make it so that you could trust them, and you can do vendor management with just them, and then they do the rest of it. But I think it would fundamentally change the way that we do open source, and perhaps, just perhaps, make it economically sustainable to have open source run… Because I think that’s another part of it, is that because we aren’t doing procurement properly, we’re also not realizing all the work that goes into it, so we also don’t realize that we kind of actually do need to pay people for the software we consume, even if it’s freely available…
But yeah, that’s my long-winded, very long-winded, unpopular opinion, that we are becoming procurement people, and we should not be procurement people, because we were very bad at it, and we should go back to just being software people.
YAML slingers.
YAML – yes. I mean, I guess the Node.js community is a good example of what happens when you don’t do a lot of supply chain analysis, and vendor management, and all of that; you wind up with a lot of code that you’re kind of like “Where’s this all coming from? What is this all doing? What happens if someone nefarious sneaks in and changes something?” It’s like “Well, that just doesn’t happen.” It’s like, alright… If we just put that in terms of other stuff… Like if you’re a restaurant, you shouldn’t probably be picking chickens up off the street from random people; you should probably be having some sort of verified supply chain there.
I mean, a verified supply chain is pretty important.
Yeah. And I think there’s some efforts to get there. I think Go, the way we do things with dependency management is better. I think we have some – the sum database and all of that, of actually being able to say “Yes, this code I got is that code that was in fact shipped by the people”, that gives us the platform to build the actual vendor risk management system on top of… But we’re still missing that. Any engineer in most codebases could just pull on any random thing from GitHub, and it’d probably be fine.
There were a few things coming out recently. I think I just saw some stuff floating around about – this latest version of Go, it’s all… I can’t remember; there are good developments in this area.
[01:14:04.07] Yeah. We’re getting somewhere… But I think we should just get away from procurement. You don’t want to do procurement. I mean, if you do want to do procurement, you’re probably not a software engineer. Sam, what about you? What’s your unpopular opinion?
I will give you two the choice. I have one on LLMs, and one on simplicity.
Why not both?
I’m gonna vote LLMs.
I’m gonna vote both. Just fire them off. Just go.
I’ll start with LLMs. They are going to significantly displace a lot of the software work that’s done today. It’s going to happen. A lot of the lies that we tell ourselves about our jobs not being disrupted are things that we’re telling ourselves to feel more comfortable. It’s going to take a while, but I think that the basic reason for that is that it’s a hell of a lot faster to have an answer that’s mostly right, most of the time, for most software purposes, than it is have to engineer something precisely.
I feel like I don’t disagree, from a very specific perspective. I feel like perhaps if I look at LLMs through the lens of like it’s a new kind of compiler, I think I would agree. It’s kind of like when we first got compilers in general; it’s like, yeah, all the assembly programmers kind of – they don’t all disappear, but it fundamentally changed how we build software. And I think LLMs will likely do something similar, but I think it will, in fact, push us to actually do more of the design stuff we were talking about earlier in the episode. Because we just don’t do that right now; we just do a lot of the typey, typey typey, and then we just don’t do any design. So I think – yeah, I think it’ll push us to actually design things better, so that this thing that can get it right most of the time, we can give it, and it can spit out something, and then we can be like “Is it right?” by looking at the design.
Because right now, the problem is it spits out something and you’re like “Is it right?” and you’re like “Well, what is right?” And we have not defined what right is. So we have to be able to define right, and that feels like where – that feels like when we will actually get to the point of doing software engineering. Because I still hold that we are not really doing software engineering, because we are not doing design. We just build software. That’s it. We don’t really design it. Our design docs are mostly implementation docs. We don’t sit down, we don’t do the things that other engineering fields do to actually design the thing.
I have unpopular opinions about that, around – you know, if we just called it software design instead of software engineering, I think it would clear out a lot of the people that want to call themselves it, because they have an apprehension to thinking that they’re designers instead of engineers. Anyway, this is your unpopular opinion, not mine.
What do you think that’s gonna look like? Do you feed an LLM a design, or do you say “I need a tool that does this?”
The past few months I’ve been spending time in this area, and I think what we’re going to see is more and more broadly reusable – think of it in terms of more reusable components. Right now, you can have an HTTP router, because the task of receiving a well-formed HTTP request, and then multiplexing that to different handlers, [unintelligible 01:17:20.12] it’s all pretty well-defined. But the existence of HTTP routers is predicated on a well-defined problem space that you can engineer a precise thing around. If you think of an HTTP router as like a subsystem that you can write generic reusable software for, the span of things that we can make agents, LLM AI-based agents for, the things that they can potentially cover - it’s just a larger set. So we’re gonna see an engineering shift towards – and also the way that you power those, and the ways in which you configure those, the way in which you compose them into functioning applications… Software will look different when the unit of composition looks so different, and can cover so many other areas.
[01:18:08.18] I just wonder, if the current angle of the legal world, where they say “Things produced by LLMs are not copyrightable” - do you think that changes this trajectory? If the thing that it produces is like “You can produce it, but you do not own it, and anybody that has it can use it.”
So as long as there exists frameworks like Langchain, for example, which are the thing that a programmer writes, specifies, in order to stitch together an overall application that pulls together different agents, I don’t think it matters… Because the output of one agent uses the input to another. And it is the construction of the chain of relations between these that is actually the copyrightable thing.
Right. Okay. What’s your simplicity unpopular opinion?
Simplicity is a circle jerk. I’m not sure I believe this, but I’m tending towards it. I believe this at least as much as I sort of believe the things that we were just saying, about it is the sort of path that you are individually walking as you evolve as a programmer, but that should – ultimately, it’s a not reachable destination, and when it’s actually brought up in the context of trying to get a thing done, it’s a distraction. You almost never know enough about the problem, and I’ve only rarely encountered people who are not genuinely making their best effort to solve the problem as they understand it sufficiently well, sufficiently soon. So while it may be a true thing in an individual’s head, chasing simplicity as an organization, as a thing you bring up in a meeting - maybe you’re just *bleep*.
I think I kind of agree with that, yeah.
Yeah, I do feel like there are – it’s a different type… Yeah, I feel like if you try and bring up software simplicity at an organizational level, it’s probably not going to get you to the place that you actually want to be. I think that that’s where you cross from needing to do software simplicity to doing organizational-level simplicity. That’s a very different type of, for some reason, extremely difficult work to do. Well, not for some reason. There’s a very specific reason why it’s so difficult, but that’s a different podcast… [laughs]
But yeah, I see what you’re saying, and I don’t – I don’t know. I feel like I agree, with nuance. There’s a lot of extra stuff you’ve got to add in there, but yeah… Which makes for a good unpopular opinion. Ian, what about you? Do you have an unpopular opinion?
I can’t think of a topical one… But I do have an unpopular opinion.
It doesn’t have to be topical.
I think – there’s been a lot of like hoopla… And I hope I know what that word actually means. There’s been a lot of uproar about pre-release video games… About how they’re bad, and how you’re giving companies money for unfinished games… I think they are fine. Like, I am for pre-release games. If you don’t want to play an unfinished game, don’t buy the pre-release one. I don’t see the problem here. It’s not like they’re selling you a game and saying “This is complete. Go play it.” I don’t know, I think the uproar is silly, and sensational, and…
I feel like if you’re mad about a pre-release game, it’s not for you, and you should just, as you said, not buy it and move on.
Release early, release often, man…
I mean, it’s been like a more viable way to build video games though, so…
I don’t know if you’ve all heard of Star Citizen.
Heard of, yeah.
They’ve spent millions of dollars building this, and it’s been in pre-release for years, and people are still saying it’s like a Ponzi scheme…
A decade, right?
[01:22:10.17] Yeah. And it’s obviously not. I don’t know, I think it’s silly.
I mean, I think people underestimate how difficult it is to build a video game. Interesting, yeah.
I don’t know, Star Citizen, looking at it from the outside, [unintelligible 01:22:24.15] over the years… It doesn’t look like a Ponzi scheme to me. It looks like a cult.
That’s probably closer to the truth…
I can’t remember the name of the lead designer, but this was his white whale project, or whatever… And he had tried to do all these things at once, and told a really good story, and got a bunch of people sort of compelled to come along with, and… So it’s this sort of weird intersection of a Ponzi scheme and cult that I’m not –
I do think it’s an honest effort to build it, though. It’s not –
So it is different in that sense. Yeah, there’s a real effort to build it. But there is a degree of “Don’t believe your lying eyes” that’s required in order to buy in over a sustained period of time, that as aspects of… Maybe Ponzi scheme actually is better; it’s a better way of putting it. It reminds me of all of the grift that we see happening all over the internet. People selling courses about how to get ahead in business, that basically amount to a training for how to sell courses about how to get ahead in business… Because that’s what works for the person you bought the course from, because you bought the course from them.
Yeah.
I wonder if it’s – because I’ve heard of this, but I haven’t actually looked into it much… But I wonder if it’s like an example of the underdog syndrome, where it’s like, because it’s been in pre-release for so long, you kind of can’t release it, because then this whole community people supporting the pre-release will disappear. It’s kind of like when the underdog becomes the incumbent, and now it’s like “Well, now what?” This happened with House of Cards. The show was all about Frank Underwood being this underdog, and being denied what he wanted. And then he got what he wanted, and then it’s like “Okay, now what?” I feel like that happens in a lot of spaces, and I feel like people with good intentions, it happens to as well, where they’re like “Oh–” Yeah, you’re just stuck perpetually as the underdog. And if you become not the underdog, then the people that were supporting you will kind of turn against you, because now you’re the incumbent, you’re the big bad… You’re just another person that released a video game. I don’t know, that’s like my wild speculation about how this could be.
Because people can be good actors, but still kind of get stuck as underdogs. I see it a lot. I see it a lot, in a lot of places in tech, where it’s just like, you’re just so used to being the underdog, you just don’t know what to do when you’re number one, when you’re on top and you’ve done the thing. But yeah, in general, I would say pre-release video games seem like a cool idea, in moderation… Like most things.
Unless they turn into a Ponzi scheme.
Well, that’s true of lots of things, Sam…
It is! Such as the risk of life, right? …and the weird way that internet communities can form.
Yeah, there’s a lot of things that are Ponzi schemes, that are –
The easier it is to assemble a group of people around an idea, as the internet makes it basically frictionless, the easier it is to create these self-sustaining communities, which self-sustain by being an Ouroboros of their own bull***t. Sorry for swearing. But the thing is awesome, because I believe that it’s awesome, and then that feeds back in and it makes it a little bit more awesome. Again, it’s different when there’s an actual product in play… But there’s a common pattern here that has to do with the ability of humans to create collective delusions and hold to them over long periods of time.
I feel like this could be a very large subtweet on programming languages…
I would say it’s more a subtweet becoming a real tweet on cryptocurrency writ-large. Financial influencers, [unintelligible 01:26:10.22] But yeah…
Alright, before we get too deep, I think we’re gonna call it –
There you go, let’s just turn right away from that. There you go. [laughter] Yes. [unintelligible 01:26:21.25]
Let’s call it there…
There you go. [laughter]
Alright, let’s roll this outro.
Our transcripts are open source on GitHub. Improvements are welcome. 💚