Grokking Simplicity, Stratified Design & Functional Programming
In this episode of Does Not Compute, I talk about my new book Grokking Simplicity: Taming complex software with functional thinking.
Transcript
Hey everybody and welcome back to another episode of Does Not Compute. And this week we have guests with us, Eric Normand. And so Eric is an author, a podcaster, a YouTuber. And yeah, he recently has authored a book called Grocking Simplicity, which I've been really enjoying. We're happy to have them on the show and talk about all things functional programming. So welcome, Eric. Cool. I am very excited to be here. It's going to be an awesome show. Yeah, we're excited to have you. I think like we were talking a little bit earlier before we started recording about how the examples that you used in this book, well, I guess I should back up like in a nutshell, the book is sort of like using functional programming concepts in order to simplify your code. It gives you some approaches you can take, it gives you some design patterns you can follow. As I was reading through the book, all of the examples that you were giving hit really close to home. So I was saying that like the example that kind of goes throughout the whole book is sort of a team, a marketing team and a dev team making e-commerce platform. And that's my life. That life for five years. And as you went through the book and we're adding features and adding complexity to the application, I was just thinking to myself, I've had their conversation and I've built that feature. And it really makes me feel good to hear that because I'm making them up from my own experience. But you got to fictionalize it. I wonder sometimes if I went too far or if it was just me that had that experience, so it's great to hear. I haven't had that kind of feedback yet. I think e-commerce thing is, I think it's applicable to a lot of people doing similar things. Like just such a common use case for web apps and the kind of things that would benefit from a lot of these design patterns. And of course, you know, there's any number of, you know, you can get as complex or as simple about it as you want, right? That's right. That's right. I was surprised that I maintained that I was able to maintain the same like scenario throughout the whole book. You know, I thought, okay, maybe I'll have to change after a couple chapters because it'll be too, you know, we will have exhausted like how, you know, how unfunctional this code is. But no, I just kept tacking on. Oh, yeah. Now marketing's doing coupons and, you know, I just, I could find something about e-commerce that would work. Yeah. So I mean, Rockwell, like the whole, the whole time I was working at that other job, Rockwell, it was a very small team. It was me and, and maybe one or two other devs at a time. And so Rockwell was sort of my, my rubber duck for most of it. And so, and explaining like building a coupon system because the, the e-commerce system that we built was from Scraps. It was sort of tailored to a specific industry. Okay. And so a lot of like the business stuff on the back end was sort of specific to that industry. And so like building a coupon system, building, I think one of the examples you had was, oh, the marketing or whatever team needs to be able to edit the individual price on a line at them for like a specific order. And I was like, yeah, I've built that. Yeah. Yeah. So it was just oddly like hit, hit home. Yeah. I could have used the book five years ago. Sorry. I wrote it as quick as I could. It's all right. So I guess my first question would be, you know, like what, what kind of led you to, to writing this book or authoring this book? Yeah, good question. Back in 2017, I wrote a blog post. So it started very modestly. I just had this idea that we didn't have a good idea of what functional programming was, especially like compared to different paradigms. And I thought about it for a little bit. And then I kind of got this idea of, let me write a post where I show procedural object-oriented and functional and just kind of try to boil them down to their essences and like answer some, some mysteries that I had about them like, why is it that procedural works so well? I mean, it really does until it gets too complicated and big and messy, right? But it works really well for a while. And what is it about functional that I really like? So I wrote that post and I thought, wow, I really, I really found something. And it basically was like procedural is basically saying you have a series of steps that you're going to perform and some of those steps are going to be procedures that have their own steps, right? And so you just break everything down and you keep breaking it down and smaller and smaller steps and you can kind of name groups of steps and call them procedures and stuff. And the thing is, that's what the computer does. And it's also what we do, you know, if you list the steps that you're going to take to do something. And so that works really well. Then object-oriented was you have these, these objects and they communicate with messages and the message gets interpreted by a method, right? It's something like that. It's like there's three principles in each one. And then functional was we separate everything out into actions, calculations and data. I didn't use those terms that time, but that's, you know, that's the idea. And I thought, wow, I really found something here with this, this category scheme. And then I was invited to give a conference talk and they said talk about whatever you want. And so I said, I really want to dig deeper into this, this idea of actions, calculations and data, so I gave that talk. And then someone watched my talk and said, wow, that's really great. You should turn this into a book. And I thought, oh man, a book, that's a, that's a, that's too big. But I, you know, I kind of started, you know, thinking maybe, maybe this should be. And so I started a podcast. You're really procrastinating at this point. Well, it wasn't the procrastinating. So the idea was, my mom has written like eight books and she told me the hardest part is getting the words down on the page. Once you have them out, you can edit them. That's much easier. And so she suggested talk into your phone and then have it transcribed and you will start with something. It's much easier to talk than it is to type. And so that's what I started doing. You like, but the first few episodes of my podcast, then I said, well, if I'm going to record it, I might as well just publish it, right? It's a podcast. And so that's what it was just me in my backyard, like talking about this idea and like as much as I had already elaborated on it. And I was, I transcribed them. And then I was just collecting them and I was when I was, my plan was when I feel like I've reached the end, I'm going to start organizing it. But then I think because of the podcast, I was contacted by Manning and they were like, Hey, you want to write a book about this? You know, you're talking about writing a book like you could do it with us. And so, you know, we talked and I liked the editor who was there, who he's the one who does the Grocking series, name of Bert Bates. And so I said, okay, I'll do it. And then that was 2018, I think July 2018, I signed the contract. And I thought, you know, I've written so much, I got so much material in a few months, it'll be done. And I, I didn't calculate the quality that I would need, you know, so you started just writing blog posts and so it took a year and a half, a two and a half years, sorry, not a year and a half, two and a half years to finish it took a whole half a year just to figure out the format that it was going to be in. Yeah. And the format is pretty fun, by the way, like the, you know, the examples we talked about were we're going to have this as little characters that reappear and I just found it very easy to, to read the writing styles pretty laid back and I know it's kind of hard to do with the technical book because it gets so dry. If you're not careful. Yeah. And that's how, I mean, at least one of the early drafts before I figured out the format was it was just, it was just like three chapters of let's define complexity. And then four pages later, it's like, okay, we've done complexity now. But you know, like just too much too didactic and I mean, to be honest, it was good for me because I felt like I really organized like this fundamental layer of my understanding about what's going on, but not fun to read and no one cares like the silly little distinctions you make between two words and like why this one is, you know, no one cares about that. So I'm interested in kind of following up on the categorization thing you mentioned. But also on this point to talking about sort of the format of this book, I really appreciate it because there are a lot of sort of diagrams. And that's how my mind works is just sort of visually. So even when I'm, when I'm working, I have a split keyboard and I keep a notepad in the middle. I'm always drawing and sketching diagrams and in my mind, when I'm looking, if I'm looking at a long file full of code, a lot of times I actually just minimize all the functions in it. And it kind of like lets me zoom away from the details and stuff. And so the concept that you talked about in the book of, I think there are call graphs. Like I do that, I didn't really know what they were called, but I do that a lot myself. Just trying to help myself piece things together. So I appreciated that. But yeah, I found, I found like the, the way you approached it sort of like really easy for me to like skim quickly and pull things out of really quickly. Nice. I mean, that's, those, so there's two like big kinds of diagrams I have in there. Like the ones that I use over and over, there's the call graphs. And there's the timeline diagrams. Have you gotten to that in like chapter, I don't know, 15 or so, 16, maybe? It's probably 15. I skimmed over. I remember the timeline diagrams from the first chapter I want to say where you're kind of just introducing the concept. Yeah. Yeah. So, an example of it. Yeah. And I guess we can explain that a little bit more. But yeah, I really appreciated that approach. But also the idea of, you know, taking, you're basically taking the contents of your functions or your application really in a greater sense and you're putting them in a box. It's doing one of these three things mostly and especially in the functional programming lens having, you know, calculations are pure functions, actions or functions with side effects and your data, like you kind of boil things down to that. And one thing that always helped me in the past was, I forget where I first saw this, but someone described like testing code, like it's usually like set up arrange and assert. And so for me having patterns that I can apply, like that quickly helped me a ton. But I've never really had a pattern to apply that to non testing code. I've kind of like gotten small, you know, bits of it here or there, but never like a here's kind of like what you can boil most things down to and you can kind of put them in boxes. So in my mind, when I'm looking at code, it's almost like the mini map in VS code or something where it's like zoomed out and you see blocks almost. Yeah. Yeah. I feel like that's how I'm just like the shape of it. Yeah. That's kind of how my brain works. So maybe I should be a designer not a programmer, but I think putting things in the boxes like that is really helpful for me personally. So that was probably what caught me first when I started reading the book was you're like, okay, well, your program is probably doing one of these three things. And then you walk through a number of examples of like, here's how you can identify which is which. So I really appreciated that approach, but maybe do you want to expand a little bit more on like the the ACD stuff or like actions, calculations and data and how that came about and et cetera. So so actions and calculation actions, calculations and data are the three types of code you'll find in a functional program. And this is sort of the fundamental distinction that functional programmers make when they're reading code or writing code. And okay, I'll explain what they are. So actions are pieces of code that will have an effect on the outside world. Usually they depend on when they're called. So that means like, if I'm reading from a mutable variable, a global mutable variable, if I read before another piece of code writes to it, I'll get a different answer from if I read after that other code writes to it. So that's the when, right? But sometimes it also depends how many times you call it. So if I want to send an email, if I send it zero times, it's a lot different from sending it once and it's a lot different from sending it a hundred times, right? So these that's kind of the rule of thumb is I I don't know if I put this in the book, but I like to think of it as time or times. So what time and then how many times? That's like the rule of thumb for determining if it's an action. Okay, now that's actions. There's calculations which are like Sean said, they're pure functions. So these are computations from inputs to outputs and they will give you the same answer no matter when you call them or how many times you call them, as long as you pass in the same arguments, you'll get the same answer. So these are totally timeless. It doesn't matter when you call them. And the nice thing about calculations is that they're very easy to reason about. They're easy to test. You know, if you're running tests, they're usually running on maybe even like you're on your development machine or on a test server, a build server or something like that. So they're not even in the same environment, right? They're not on the same machine as the production code is going to run. And then you're going to want to run them like thousands of times, right? How many times do you run your tests like all the time? So they need to work the same every time, right? And then there's data, which is all the stuff that doesn't actually run. I call it inert. It's like strings and numbers and lists and arrays and stuff like that. And the cool thing about those is that they can't break, they just are what they are. And because they're inert, but they require interpretation. But you can interpret them in multiple ways, which is a cool thing. So all that is to say is that in functional programming, when we make this distinction between these three things, functional programming, functional programmers prefer calculations and data because they are easier to work with. They're easier to test, easier to know if they're going to give you the right answer. But actions, we need them. You need to send that email, right? Like your software's purpose is to run these actions. But because they're so hard, you know, the idea is like, get as much as you can into the calculations so that we can pay more attention to when they run and how many times they run, which is the hard part. That's where all your bugs are or your bad bugs. The thing that comes to mind immediately is all of my, any code that I have that's time related, that's on a scheduling system, right? I always end up having to just create a variable called now, right? And just pass it in all the way through the whole thing because like you said, it's not testable otherwise, right, you need to be able to simulate different points of time. And yeah, in production now is now, but like that, you know, that definitely corresponds to a when and that's, that's the case where I always, I always, always, always, you know, do the action up front and then try to, you know, pass it in the calculation. So it's deterministic. In groggings simplicity, I have a section where we generate emails to send to customers, right? And like the traditional procedural way is you have these customers and you like loop through them all and you like determine which email to send to them and you send it and then you go to the next customer and you go to the next customer and you just like sending emails or not, some people won't get an email. But in a functional world, you know, you think, well, how do you turn that into, you know, a computation because you're either sending emails or you're not like, what do you do? Well, what you can do is you can turn that list of customers. You can make a new list of this is all the emails we need to send, right? So you're moving all the hard, okay, I'm saying hard. It's actually, it's actually the important stuff and it's not hard. You're moving all the decisions of which emails to send, who gets which email, how do you generate it from their data so that it's, you know, personalized emails. You're moving all that into very easily testable code. So you know, you could have a function that takes a customer and returns an email, right? And now you map that function over all your customers and now you have a list of all the emails you need to send. And then you can have a very simple loop that just one at a time sends those emails. It doesn't make any decisions except, you know, increment to, you know, increment I. It's not a hard decision. And you just loop through all those emails and send them. And so you've minimized the amount of code that has to go right. That's very hard to test. One of the things that you mentioned, this really, really hit home for me was near the end, you're talking about MVC and active record and rails, right? And how active record, I mean, it's, it's this whole magical black box, right? It's amazing what it can do. But how quickly that like any time we touch an active record object, it's, it's an action. Like you're touching the database. There's some side effect like when you call like dot count, who knows, are you, is it a right? Is it some reference? Like, who knows what you're actually, you know, calling through all the duck typing. So like that's so easy for that to just creep into your code. Cause that's just the quote unquote rails way of doing things. Right. And what happens, like you said, is in the book is that that kind of pollutes everything above it, everything that calls into it. Now as an action by, by like transitive property, right? You're called it. You might have something really, really simple. But if it calls an action, that things an action too, because it depends on the outside world. When I was writing that chapter and, you know, sometimes you write something that you maybe knew deep down, but like you never, you never looked at it yourself, you know, so I wrote that. I was like, Oh man, this is why, um, you know, I hear so many people talk about, Oh, let me just put another layer on top to like make this mutable thing, like easier to work with or like, and in like they think the more layers, like eventually it'll go away, right? Like eventually I won't have to think about that mutability, but it's impossible. Like it's always going to be down there. And the more you put on top of it, the harder it's going to be to use it. You know, what you're referring to at the end of the book, we're talking about onion architecture and how it kind of reverses it. The only way to get rid of not, you don't get rid of it, but the only way to really manage that mutable thing is to put it on the outside and have your functional stuff in the core. And then you have your database on the side, right? And you, you, you, you keep them separate so that you don't like, you know, you know, the typical web stack is you put the database at the bottom and then you try to like layer and stuff on the top and if you just put the database on the side and you just had your, your, your service is like a pure thing that accepts stuff from the database, it makes it a lot easier. So in Elixir, you can use the exclamation mark, the bang for function names you can put at the end. I had this crazy idea, like, could I just, should all my functions that are actions just have a bang on the end and that way, like, it really hits home that this is an external thing. Have that be a really big red signal if that became that too much of a problem? So I don't think it's a, it's a terrible idea. I think I've had that idea too, but I also feel like when you get to know a code base, you kind of know, you know, like, it does help to have all these signals, like conventions in your, in your code to, to let you know, like, this is an action. So don't call it like thinking that, you know, like, what you want is I've got this thing that I think is a calculation, but then I look at the code and there's a bang inside there, like, whoa, that's wrong, like, that can't happen. That's what you want. But I don't know, I find that, that I don't have that problem, you know, but I think it's also the same kind of thing where like, if it doesn't feel like I need types, you know, like, I don't, I don't make those mistakes thinking I have a string, but it's really a number something that it feels like I don't, you know, I wonder what my compiler thinks. Well, that's one thing I missed a lot going from writing Elixir full time to more writing JS full time. And now, you know, I'm in TypeScript land. So I kind of have some compiler errors, which is nice, but that was having a Elixir sort of like, tell me, Hey, dummy, you did this thing wrong. Or this doesn't make sense. That was, that was something that I missed. Yeah. Yeah. Yeah. I mean, I used to work in Haskell. And when I, I mean, when I was in Haskell, I missed closure. And then as soon as I started working in closure, full time, and wasn't doing Haskell anymore, I missed the types. That's like, Oh, it would be really nice right here to know that I have the right type. But I don't know, you just learn, you're, you just adapt, that's, that's what I think. So we, we mentioned onion architecture a little bit, which is kind of towards the end of the book. But I also kind of wanted to ask you about stratified design. So in, you know, in, I learned a lot about domain driven design actually through Elixir and Phoenix, because I picked up Phoenix and you had mentioned earlier that you are familiar with Elixir. And I picked up Phoenix, like when it was 1.2. So before they started with the idea of context. And, and 1.2 Phoenix was very much, it was, it looked a lot like rails and, and 1.3 Phoenix, it was all about context or domains, like boundary contexts. And, and so when Phoenix made that change, they're like, Hey, listen, this is what we're doing. And you have to learn about this. You have to think a little bit more now before you actually build your software. You have to plan it out. And that kind of like pushed me into the domain driven design path. But I haven't, I hadn't actually heard of stratified design before. So yeah, I, through the book, you know, I, I skimmed it. I haven't like, you know, internalized a lot of this stuff yet. But it seems, it seemed similar, but a little bit different. Yeah, it's definitely different. So domain driven design is kind of a, a way to model a domain. Right. So it's like, let's go talk to stakeholders and domain experts and really try to figure out, with their help, how we can model this in software, right? Which is really great. I think it's a, it's a needed, we can talk more about this, about my opinions about the software design in the industry. But I, this idea of, let's, let's actually try to take the domain and encode it into some software. Like, to me, that sounds great. And you know, so they've got a bunch of concepts like you were talking about, bounded contexts and you bake it, you bake with this language and all these concepts that, that really help kind of navigate that process. Stratified design is something different. It's more about how you, it's, it's about layering your software. So that into, into kind of discrete semantic layers. Right. So like every layer you add is adding some level of meaning that you can now express. The main layers that I talk about in the, in the book are the language layer, business layer, and then the interaction layer, like the application layer. I also like to, you know, for myself, I don't, I didn't go into it too much in the book, but the business layer is actually two layers. It's the domain layer and then the business layer. But my editor was like, it's too, like people aren't going to know the difference. Maybe I'll talk about it here. The domain layer, if you're an e-commerce business and you're building a shopping cart, every e-commerce business has a shopping cart. So you could imagine if you did a good job writing your shopping cart, it could go on GitHub as an open source library that thousands of businesses would use. However, you're going to have some business rules that are like, we run sales every Thursday, right? Or, you know, some, some crazy deal, like, oh, if you put these four items in your shopping cart, then we're going to give you a 10% discount. Like no other business has that, right? So that is a business rule. It is not a domain rule, it's not a domain concept. But the concept of a discount is a domain concept because a lot of shops have discounts. So the idea is that you're, when you write software, you're trying to figure out at what layer of meaning of generality, are you writing? Am I writing a routine that works on, let's say, every array, right? Like this is concat, I'm writing a version of concat. This is not a domain concept, even. This is a language level concept, right? It works. It doesn't matter what domain you're programming it. But maybe I'm writing something super high level, which is the meaning of a high level of meaning, like run Friday's sale, you know? You have to know what that is. And that's going to be built on top of stuff in the domain of sales, discounts and products and stuff like that. So that's the idea is that you've got to figure out the layer of meaning. And what's cool is that you can look at the call graph, that diagram you were talking about before and actually see the layers. And you can identify problems like, hey, I'm calling this run Friday sale, but it's implemented in terms of JavaScript objects and arrays. It's skipping a layer. It's skipping the domain layers, it should be about sales and discounts and prices and stuff like that. So you've skipped layers there. And you can see that when you draw the arrows, like, well, this is just skipping all these intermediate layers. So that's the idea. Yeah. And so you were mentioning call graph diagrams as well. And as you were outlining stratified design, you kind of outlined, all right, here's what we have. Here are our layers. If the business team now asks us to do this, where do you think which layer should we implement this? And which was really, really awesome. And in the point that you're talking about, like, if you're looking at something that's sort of on the business side and it's implemented in language level primitives, we're skipping a step, right? But I think like with pattern one of stratified design being like straightforward implementation, the implementation, when you look at it, it's not going to be straightforward. You're going to have to read through it. You're going to have to parse it mentally to figure out kind of what's going on, whereas if you properly have it spread out in the proper layers, the implementation will probably be more straightforward. It's going to be more specific to the domain that the business needs to operate on top of. And so, like, shy riding the chat is saying that they've tried bounded contexts before and it always sort of went sideways. I kind of felt the same way, like, I, like, with Phoenix, like I'd get into context and I would hit this wall once things got sufficiently complex and I didn't know to solve the problem. And I think this is sort of one of the things I was missing because I was being introduced to this idea of the business domain and the language and I was trying to separate my services based around that. But I wasn't separating them around technical complexity or even, like, their role in the layers, right? So, like you're saying, when I said stratified design sounds similar but different to DDD, you were like, "No, it's different because it's more focused on this other thing." And DDD is primarily focused on, like, these business concepts or language between teams. I think it's one of the things that I have to preface this because I'm going to say some things that might trigger some people. Let's go. We're ready. [laughs] Nothing, like, sex or violence or anything like that. But there's been a lot of flame wars over the years about these ideas. Okay. So, I think object-oriented programming is really cool. It's got a cool way of breaking the world down, breaking the model down into objects and putting an interface around those so that you have a cool API to access that state and stuff. It's a cool model. But I think that in the practice, what people do is they try to make stuff that's too big. So they'll look at something like a person and they're like, "Well, that obviously is a class because it's a noun, so we're going to make a class." And then all this stuff that has to do with people, we're going to put it as either fields or methods on the person class. And so then you look at those methods and they're these giant, they get bigger and bigger over time and they're skipping layers. There's no other concepts in there. It's just about, it's just for loops and directly accessing the database and everything. And what stratified design is trying to say is that person might be easily implemented in terms of five lower-level concepts. And you should just make five classes for those lower-level concepts and then the person is just a composition of those. Now, that's in the object-oriented world. In the functional world, you have this function and it's all complicated and it's doing all this stuff and it's iterating through arrays and grabbing fields and stuff. Oh, really? Maybe you shouldn't be doing that. You should have a function called search by name. Instead of doing the loop in that function, you should have a lower-level concept that can do that work for you. And then once you implement it, it's like, oh, it's just these three things put together in the right way. One of the things I always struggle with when trying to build layers is first of all, identifying them, which I think you did a pretty good job of covering in the book, but also just naming them. You know, in functional languages, generally, you don't have a big global namespace with all your functions in it. You never really just have modules, bags of functions, and you have to get the module name and I really, really struggle with sort of the nesting and the naming of those kinds of, you know, of the layers. Because they're so abstract, right? They're, yeah, they're often like, I don't know, just ideas and like, they don't really correspond to anything in the real world I do, I do some of that. Yeah, that's the thing. Do you have any like, sort of maybe guidance or tricks you can use to like, I, so, yes, um, the, and the, the guidance is the same stuff I talk about in the book. It's make sure that a layer is actually adding some meaning, right? So if you're, if, if it, if a function is implemented in terms of, let's say it's just mapping and filtering and just doing a lot of array operations, um, then you need to, in the name of that function, just give it a little meaning, like, what is it doing that for? Like, just a tiny bit more, like more of the why as opposed to the how kind of? Yes. Yes. And then why, you know, you got to give it a name that, that kind of proves it's necessity. Like, proves it's worth, like, I need some of that. I know, I know it's really hard because it, it's sort of like if someone, you know, back in the day, there were no, uh, people didn't think zero was a number, you know, there's no name for that. It was just, well, numbers started one, like, why would you even need a number to represent nothing? Right? And like someone had to say, damn it, I, I need to, I need a zero. I'm going to call it zero and it's going to be a little round thing. And that's it where, you know, I don't, I, and I know it's hard. It's a new concept. You're going to have to come up, you know, if you start trusting this and learn its properties and stuff, but it, it makes the math better, even though there's no, you know, it seems like there's no need for it. And I often feel like that, like, I'll be, I'll do something on, like, let's say I'm working on trees, right? And I'm refactoring, refactoring. I'm like, this, this little piece of code keeps getting repeated over and over. I'm going to pull it out into a function. Oh, what do I call it? It like rotates a tree in this certain way, like two branches, like, what does that call that? I don't know. It's, it's, it's hard. I'm making up zero and making up, like imaginary numbers, you know, he, I just imagine the guy who invented imaginary numbers is like, is, you know, he's telling, he's telling his friend. And his friend is like, that is the dumbest name I've ever heard of, imaginary numbers. Like, are they real? No, they're imaginary. Like, okay, like, so is this just, it sounds really complex. Yes. Exactly. That's perfect. Perfect name. Let me write that down. I had one more question about the stratified design thing. I guess I'll just get right to it. If you're, if you're building something, building a feature, building an application, maybe it's just small, maybe it's large, whatever the scale would is, you want to use a stratified design. Where do you start? You know, because, you know, the, you could be arguments could be made for starting at the top, you know, define my sort of public API, I know kind of the, what I want this thing to do, and then sort of like a red, green, uh, testing, you know, test driven development thing, right? The test. Then write all the code that does the thing until it turns green, right? Or argue we could be made for, you know, starting at the bottom where you build up the fundamentals and, you know, the foundation. So, uh, I don't know, what are your thoughts? Yeah. I mean, they're only thoughts. I think this is a really fundamental issue with any kind of creative activity. Like, sure, you know, where do you start? You have a blank page like how do you write a novel, you know, um, uh, but my thoughts are I like to see stuff working. So I prioritize, uh, the, the speed to first pixel or first visible output, you know, so I don't focus as much on design when I'm first writing it. Um, now that, that is to say, like, I, I will do it sometimes and I catch myself over designing stuff ahead of time. Uh, it's such, such an easy trap. But there is sometimes, there are sometimes where I'm like writing something that I've written before, you know, like this is the third time I know what I, what I want, uh, or if I'm writing something in a piece of software that I use all the time, like I know I'm re-implementing a feature and I've thought about it enough. I kind of know why the software doesn't do what it should and I, I know what it needs to do. So yeah, I mean, start anywhere. I just like to get it working. You know, it, it sounds like what you're describing is pattern four of stratified design, which is comfortable layers, comfortable layers and what that means is if you're comfortable working with it, just keep it like it's, it's kind of the, the valve to like, you don't need to have perfect design like that's not the point. The point is to make it nice to, to, to live in and, um, you can overdo it and you don't have to have it and everything perfect. I think that was a big stressor for me with, with the, uh, the Phoenix stuff to her. I was kind of always stressing about how should this be designed what's, what's like perfect endgame here? What does that look like? And it doesn't exist. It just doesn't exist. And, and I was putting a lot of pressure in myself, a lot of, um, I don't know, guilt doesn't maybe the right word, but just like this should be better when I, when I always look at it. When I'm reading through stratified design, I get to pattern for comfortable layers and you were like, it's fine. If you're comfortable, like extract until you're comfortable and then move on because there are other things you could be doing. And I was like, this makes a lot of sense. Again, I could have used this book five years ago. I, so, you know, as an author, I have this fear that I'm going to say something like, hey, you should do, you should have layers, you know, and in, in a year after my book comes out, so I was going to be like, look at this and it's got like thousands of layers in it. And I'm like, what are you doing? And you're like, you said to do that. You told me to write layers like, no, that's, that's not what I meant. You're just taking away too far. I think that would be a fun, uh, experiment to try, like see how many layers you could comfortably fit in a side product. Just just to see, like at what point does it become too ridiculous and unwieldy? Yeah. Yeah. I mean, it's cool to push the limits if you're just trying to, you're, you're experimenting, right? Like that's, that's cool. It was a great way to learn. I just, I just wonder if like the design pattern people, the gang of four are like, oh, that's not what we meant. What did it mean to put factories everywhere? It was just an idea, singleton's, you don't need so many. I love design patterns, by the way, just don't, don't email me. Yeah. Well, they, they already put the pitch forks down. So. Oh, good. Good. Yeah. They picked them up. I had a trigger warning. They picked them up when you said trigger warning and they put them down after after. After. No, the chat literally said they're putting the torches down after the, after the, uh, sometimes these, these discussions should come with like a bomb. You know, just like, oh, I'll just rub this on me while they talk. Yeah. Yeah. So I think like overall, you know, thinking about, again, I, I want to go back and read through the book and sort of absorb it more, like we were talking before we started recording about how I've been trying out space repetition and making my own note cards and things. And so as I was reading through this book, I kept on thinking to myself, like, I need to get through it so I can talk about not just the first part of the book. But I kept on finding myself like, Oh, this is good. Let me put it in a card so I can remember it later. Uh, and, and so I think like overall, even in just skimming it, like, I've already learned things that I'm applying at my day job. So, so I was, I was telling you about this example, which was wild. Uh, so I was talking, a coworker was sharing me, sharing with me, uh, some outside contractors work in a PR and, and, uh, so stratified, uh, it's not, uh, which was, I think it was part of stratified design. But anyway, you, you're kind of like outlined some code smells and one of the code smells was implicit, uh, implicit argument in the function name. So, um, essentially you have like, get name of thing, get price of thing, get status of thing, right? And so you might have like a bucket, bucket of functions that could be simplified to one. And so a coworker was showing me this, uh, this code that exactly was that it was like a 2000 line ad and one of the files had 25 functions that could essentially be one function with like an object lookup. And, and so later than night I was reading and you're like, here's a code, here's a fix and I was like, oh man. So I sent it over to the coworker and he was just laughing about it because it was so, so timely. Uh, that's cool. But on top of that too, like even in my code reviews today that I was working on, I was able to like call back to things I was reading about and try to apply them and I'm applying them to react. Nice. Uh, which is probably even, you know, maybe a different, um, target then, then, you know, system design and things like that, but it's still like the, the principles were still the same. They still worked. Yeah. For sure. So many different threads in my mind. It's cool that you say that, that I, uh, you know, hit something on the head because I, I kind of felt like sometimes I write what seems like, no, this is too obvious. Like no one does that. It's too easy. Um, but that's what, that's what an editor is for, you know, is to say like, no, actually I was just talking to someone who needs this, uh, so yeah, that's, you should have that in the book, um, uh, the other thing it makes me think of is that this whole, I really tried to do something different with this book from most functional programming books. Um, most books I find, um, teach, what I think is the least important stuff. Which is like when you're, when you're deep in functional programming, let's say you've studied it for years and you're doing something that only a handful of people in the world can even understand because it's just so advanced. That stuff is the least important because it's only applicable in like a small area and no one else is going to understand it. You're referring to like the pure mathematical functional aspect. Sure. Sure. I'll say, I'll say the M word. You know, if you get to Monads, like it's only applicable. I mean, it's useful, but not, it's not like, let's start with Monads because it's not the most useful thing and, um, my approach was like, let's spend way more time, like most books will say they'll have a line or two about pure functions, right? They'll say, well, functional program is like pure functions and this is what it is. And now let's get to Monads. So let's, let's skip all that stuff and get as fast to Monads as possible. And, um, still don't know Monads really are well, my idea was like, let's spend seven chapters on pure functions because that's, that's the important stuff. If you don't know how to make a pure function or how to look at some existing code and realize, oh, there's all these possible things I could pull out as pure functions and like reduce the size of my actions. If you don't know how to do that, then just, you know, this definition of pure functions isn't going to help you. That was something that I've heard a lot of people say with their like, oh, wow. Thank you for showing me how to extract this stuff out. Thanks for showing how to actually identify what's an action and not just, you know, give a definition and move on. Yeah, I think for me, having sort of the visual aids really helped or I think there was a line in the book to like, Hey, isn't, uh, isn't like drawing these call graphs all the time? Just a lot. And you're like, well, we don't always draw them. We imagine them. It's like, that's how my brain works. I have to draw them because I'm the author. Right. Right. Right. Uh, yeah. It just was, I don't know. It just really struck a chord with me and you're right. Like I've read again, like going into the elixir world and learning about functional stuff being dropped into the defense sometimes. I think elixir, uh, does maybe a better job at this because maybe a lot of the resources being written and this is maybe this is just my feeling. I don't have any like facts to back this up, but like I, I kind of picked up elixir when a lot of Ruby is picked up elixir. And so there was a lot of material like here's elixir from a Ruby is perspective. And so that kind of like put training wheels in a sense on it for me. Uh, but yeah, like I will, a lot of what I, I understand today from elixir and its libraries, like I learned SQL through Ecto. I did rails for a little while and I use active record, but I didn't really understand what was going on. And when I started using Ecto, uh, which is more of a data mapper than an ORM tool, it's the DSL is almost like SQL. And so I had to learn SQL to use it. Gotcha. I really appreciated that you have in the back of the book, you have a list of examples of functional languages, languages, functional language of the most jobs, functional languages by platform by learning opportunity. But what I love about it is that you order them roughly from easiest to hardest to get started with, which I thought was great because I'm looking through this, I'm like, oh, this is cool. I kind of want to push my boundaries and try something new maybe. And uh, the rough ordering is like, yeah, okay, maybe I feel like I could tackle the next thing in the list and just to try it. I know it's, I know it's purely a subjective list, but it's something. I mean, that's kind of the, the difficulty of, of writing is like, how do I toe the line where I want to make it useful, but I don't want to say like everyone else is wrong, like their lists are wrong because that's not my intent. Some people want to say that. Well, but I, I don't want people to like email me like you got it wrong, you know, like it's rough. But there's no list. There's no way to actually say what's harder to learn than another depends on your background. So yeah, no, but I, I did, I had, I, at first all I had was a list of functional languages. And of course my editor was like, can you add more to it? And I was like, you're right. People have all these use cases. They're like, I just need to learn something to get a job. Oh, I just need to, I just want to do types. Oh, I just want to like, okay, okay, let's make different lists, sub lists of these lists. Thomas says, luckily the functional program community is not deeply opinionated. So you're, you're in the clear every, every programming community somehow is deeply opinionated. Some I don't know why yes, it feels like religion sometimes in the pitchforks have come back out. Yeah. People had them at the ready. Uh, well, I mean, we're rolling up on an hour here and we don't want to take up too much of your time. So. Well, I'm having a great time. I hope this has been useful and it's covering ground that I haven't covered in other discussions. So. So that's, that's really what I wanted to get to because I listened to some of the other podcasts that you were on and I didn't want to do that again. And I think ours was a little bit different, like with us having coming from Elixir in, you know, different, different places, like not only JS, I enjoyed the JS discussions because I am now writing type of full time as I mentioned, but we bash on JavaScript all day anyway. So it's low hanging fruit. Yeah. Here's my feelings. Well, just to, just to let the audience know, uh, the book is, is rocking simplicity. I got to say the name. Sure. Um, it's, it's, uh, the examples are in JavaScript. And it's not a functional programming in JavaScript book. I have to say that over and over because it doesn't get through. Um, it's not about like, how do I do functional programming in JavaScript? It's just using JavaScript is kind of a lingua franca as a pseudo code that everyone can understand, but that's still real enough that, you know, you can do, um, you can get into problems because if you just make pseudo code that's like, oh, and then it does this. And then like, well, that's the hard part. You just skipped over. Um, and it turns out that JavaScript is a pretty good language for teaching functional programming, uh, precisely because it doesn't give you everything. So you kind of have to do it yourself. Yeah. It was kind of interesting to read because a whole class of problems, uh, like copy on write was the example that Sean mentioned, uh, when we were talking about earlier that, like, they, they just go away if you don't use JavaScript, which is, you know, if you use a more functional language, but that doesn't, doesn't mean it's not instructive because, you know, most people don't have the freedom to, you know, actually use a functional language, right? They just want to sort of adopt the patterns and say something that they already know or have to use or whatever. So. Yeah. And, you know, I, I have this other fear that people think that you can't do functional programming, like functional programming needs all these features that languages give you. And it's not about the features. Um, I mean, obviously there's going to be something, some things that are necessary, but, um, it's not like, oh, I don't have, you know, type the static types. So I can't do functional programming, something like that, or I don't have immutable data structure. So I can't do functional programming. It's not true. The thing that always confused me, I came from an object oriented background, uh, doing a lot of dot net before, and like Ruby stuff before I came into Lixar. And, uh, I think that always never made sense to me is if it's functional, like all you have is functions. How do you do anything? Like, there's, there's a state. Right. I get it now, but it just from the outside with having done zero, zero, you know, research who's really confusing to me, like, how are people, like, is this, is it a weird mathematical thing? And that people are just like, again, how do you do anything? If you don't have data or state seems so weird. Well, and that's, that's the thing that, that like led me to write this book, because I feel like so many functional programmers couldn't answer that question. You know, like, if you look at what functional programmers actually do, they do have state, they do manage state. And they actually have a lot of great ways to do it, that object-oriented programmers could learn from that was they were just missing it because they, because it didn't, it didn't jive with their, their definition of functional programming, which is like no state, right? No side effects. And you know, I've read, I've read so many books about functional programming that just do like lambda calculus gymnastics, and I wanted something where it's like, no, we actually do manage state and we do it pretty well because we have separated the actions and the calculations and the data. And so we know that those, that state has to be well managed and we've figured out that it's about the ordering, it's about the timing of what happens when and how many times it happens. And so we control those things. And those are the things that, you know, don't get controlled if you're just using a procedural or an object-oriented language, just like, oh, anybody can call this method and change this thing. Like, oh, you actually need to make sure, you know, put a queue in front of it or, you know, what have you to make sure it works correctly. One of the things I liked about Python, I've just been starting to pick up Python, is that when you define, I guess they call methods on classes, the, the first argument, it looks like a, just a plain old function, because the first argument is self. And so that, like, there's, there's no implicit, I mean, there's, you can have variables and scope in your module or whatever that are sort of implicitly passed in there. There's some implicitness there, but, but the self, that's, it's in there. It's right in the, in the argument to the function. So it's really, it's really clear, like where your state is. Yeah. Yeah. Yeah. It's cool that it reveals itself like that, like it doesn't, like, you know, like, you know, sometimes languages can feel like magic because it's like, where does this come from? Like, what is this? Is it some magic thing that compiler writers know how to do and I don't? But yeah, and Python, it's right there. I always really liked how Elixir encouraged, I forget what they call it now, but the subject is always the first argument. So you can pipe things through and you kind of, you kind of got to that in, in one of the examples, I think actually it was refactoring out the implicit, implicit argument in the function name because one solution A was take that argument and make it the subject, make it the first argument or like take it out of the name of the function and make it the first argument of that function instead. And the second, the second way being, I think, like refactoring to call back so you can pass in a function to deal with it if you need to, but that was, that reminded me a lot of Elixir because that's sort of a thing that Elixirists do is they kind of keep the subject as the first argument so they can keep piping things through a pipeline. Right. Right. Yeah, I think that it all depends on your language, you know, like, Haskellers are proud to say that they put their arguments in order of least likely to change to most likely to change so that the ones that are the most likely are the last ones because they have automatic currying in the language. And so you're more likely to curry the thing that doesn't change as much, right? So that makes sense in that language the way the features are set up, but in something like closure, it's more like Elixir where we're threading stuff through in the, as kind of the first argument position, we want the thing that's more likely to be operated on as in the first position. And so that's how we arrange stuff because we have the threading macro that will put the return value of one line into the next, it's the first argument of the next line. Yeah, that sounds exactly like Elixir's pipes. Yeah. Yeah. And we also have one that's thread last. But it does the last one, yeah. And so then there's some functions that work really well for doing the last one, you know? That's cool. I didn't know that. I've never really looked at it. I looked at the closure's website like a couple times, but it's about my experience with closure this far. Yeah, it's cool. I actually, you know, I've played a little bit with Elixir and I've read the book. Is it Elixir in action? It's a really good book. And I really like the concurrency model. And then I have some friends here in New Orleans that run a conference that was the big Elixir. Oh, no way. Yeah. Mutual of friends. Yeah. Brian and Joe. Yeah. Yeah. Yeah. That's cool. So I went to the conference. I was very impressed. It's a good crowd. Yeah. So we'll bring the show down a little bit, but a little teaser for the people that just listened to the podcast. We usually have a bit of an after-show on Twitch where the hot takes come out without any risk of pitchforks being raised. Okay. I'm going to take my Kevlar jacket off now. That's right. But yeah. Yeah. I just started to wrap things up a little bit. You know, I wanted to ask, like, ask you, like, if there's anything you wanted to shout out, obviously, the book, Gracking Simplicity on Manning. But also, like you mentioned, you have a podcast, you have a YouTube, you do speaking as well. So I wanted to give you a chance to just kind of chat a little bit about that and let people know where they can find you. Yeah. So I've got my personal opinion pieces and stuff on programming and functional programming is lispcast.com. If you add a slash podcast, you'll get to my podcast. That podcast was, like I said, it started with me, like, just talking about these ideas that I would put in my book, let me hash them out. It was very raw and like, you know, just whatever I was thinking about and very opinionated. And I started recently doing stuff where I read a paper and I put some excerpts in and I comment on them. So people have been liking those too. There are a lot of prep so I can't do them as often as I like because I have to read the paper a few times and, you know, do some background research and stuff. But anyway, if you're into that, into that, look for that. I also teach closure at purelyfunctional.tv. So if you're into closure, you like video courses, you can look there. And then my book, Grocking Simplicity, you can get it at Manning soon to be on Amazon. It's functional programming and, you know, language agnostic. And I think we have some promo stuff shown, right? Yeah. Yeah. So I'll make sure to put all the link in the show notes and we'll also put a link as well that gives you a promo code for the book on Manning. Sweet. Cool. Now, the book is still in meat, I forget what that stands for, Manning Early Access Program. So I, you know, I'm not going to be the guy that asks for, you know, when it's going to be done. But I can't tell you, even if you did ask me. So I've completely written it, like all the content is there. It's in what's called production now, which is where they work some, some magic on it. I think there is some potions and incantations and rooms and stuff that they do that they're like, you know, I went through a copy editing phase with them where they had a professional copy editor go through and, you know, cross out misspellings and stuff like that. And then they're doing the layout. So they're making sure all the spacing looks pretty on the page and stuff and that it will look the same when they print it as on the Kindle and stuff like that. And doing the index, you know, putting all those like title page and the, what's it called, the copyright page, all that stuff there. That's what they're doing right now. All the phone, colophone, I never know how to pronounce that. Yeah. Right. All that stuff. And, you know, designing the back cover and figuring out how to fit all the great stuff that everyone's saying about. Yeah, I was going to say we're going to get a poll quote on the back. Maybe. I don't know where they get their poll quotes. Like, you know, that's the, that's the thing. There's, there's like a very well-defined traditional line between what, what's the author's purview and what's the publisher's purview. And the cover is the publisher. That's what they, that's like part of their marketing and everything. So what, you didn't draw those bunnies? I did not, I did not choose the bunnies. Those were, you know, that's what the publisher does. And he does it, they do it for, you know, marketing and making sure it's sellable and all that stuff. Quite the process. Yes. There's lots of runes and crystal balls and, you know, tarot cards and stuff. And that's writing nonfiction. Can you imagine? I know. Imagine the fiction ones, you got entrails that you have to read, it's, it goes crazy. Well, again, thanks for, thanks for being on the show and, and I really enjoyed the conversation. And if you ever want to come back and talk about whatever you want to talk about, we'd always love to, to have you. Yeah, that would be totally cool and fun. Maybe we'll give you a little more warning for the harder, the harder questions. So we don't pull in too many threads. Well, luckily I dodged it. I wrote down this question and it never came up. So that's the after show, I guess. We haven't stopped recording yet, my friend. All right. I shouldn't have showed you. But, but, but yeah, so, so as always, we're going to have links to everything we mentioned. The book is, is websites and things in, in the show notes, but also I'm making sure to link to things like architecture and stratified design and domain driven design and some of the other concepts we talked about, I'll be linking to resources where you can read more about them in the show notes. And if that's something you're interested in, of course, you can find it in the podcast listener of your choice, but you can also head on over to DNC that show and find them there. You can always reach us on Twitter, DNC cast, Sean, Sean Washbot, I'm Shrockwell. Uh, did you have a Twitter, Eric? Yep. Eric Normand, at Eric Normand. All one word. All one word. Sweet. And, uh, yeah, we're recording on Twitch every Thursday night, six Pacific nine Eastern twitch.tv/dnccast Yeah, you know the deal. Yep, and we also have a pretty awesome discord community that's been growing and we're really excited about that. But if you're looking for a place that, that's welcoming and friendly and, and, and it's full of people that just want to learn and help other people learn, uh, then we've got a discord for you. So again, I keep mentioning the show notes, but we'll have a discord invite that, uh, should work there. So that's when you're looking forward to conversations, uh, you should join it. We've got book clubs going on, we've got, uh, hackathons being discussed, uh, in like the chat is saying right now, we're not dogmatic. Uh, you can believe whatever you want to believe. There's a channel for you in the discord. So if that sounds, sounds like something you're into, then look at the show notes and there'll be an invite code there. I think that's it. I think we got it. Thanks again, Eric. This has been really fun. Likewise. Thank you for having me. Bye.