First returning guest Eric Normand explains how to Grok Simplicity

I was a guest on the defn podcast for the second time! Ray and Vijay were great hosts.

Transcript

(upbeat music) So, welcome to Duffin. I think the final episode of this year, and amazingly enough, we have a repeat guest on this episode, episode number 56, all the way from episode number 27. Eric, welcome back. - Hello, I'm happy to be back. This is awesome. - You have the first repeat guest. How does it feel? Like, you know, this is like an achievement, or achievement unlocked. (laughs) - Yeah, maybe like a broken record, I guess? No. (laughs) - No, no, no. - No, it's really cool. I listen to the podcast, so it's cool to come back on. - I mean, I'm in achievement for Duffin podcast itself, because we never thought we were going to be long enough to have somebody come back. (laughs) It's not an achievement for you. It's just for us. (laughs) Like, wait, wait, wait. - We have you on every week. - Yeah, thank you for having me on, because I know there's a lot of great people that talk to. You didn't have to repeat. You're finding cool guests all the time, so. - Yeah, but you're still cool, so that's good, you know? And also you've been doing a lot of stuff, so it's nice to catch up, you know? - Yeah, although you and I, Ray, we talk. - We talk down again, we talk down again, yeah. - Yes, so how is it going, by the way? I mean, I never pay attention to anything other than Duffin, you know, obviously Duffin is there. - It takes up all your time, we know. - Exactly. - Well, 90 hours a day, you know? - Come on, VJ is actually going to another language podcast. You're doing a Rust language podcast, so. - We had one of these. - So, like, no, you've had two of them, yeah. - Yeah, two, yeah. - The person is more like. - I know more about his podcast than he does. (laughing) - You're running Rust, VJ? - Yeah, yeah, I'm trying to. It's another one of those things, like, trying to get to the non-GC languages from the history. I tried Visual C++ C++ long time ago. C C++, that's how I started, so. I forgot how cozy it is with the GC stuff, so. I'm like, oh, let's try this shit, and then it's a different world completely, and so it's fun. It's kind of a functional, but non-GC stuff. - Yeah, so he had a weird Rust podcast, which, like you say, it's done two episodes. Maybe he'll do more next year, but yeah, me and Eric, we do something proper, you know? We do. (laughing) - It has a prop in it. (laughing) - Well, actually, I mean, the nice thing about our propore, which is the YouTube channel, is that we've been doing that. I don't know actually, is that about a year now? Is it even longer? - Yeah, a little over a year. - Yeah, and that's really nice, you know? I think it's, we'd never have any guests on there, so we can please ourselves. - I think we had a guest one time. - Oh yeah, we've had one. - Yeah, we had to do it all the way, yeah. So we do have, we have royalty on. They're not really in a study, you know. - That's a nice way to insult our guests, yeah. - But you don't know. - But luckily on YouTube, but luckily, exactly. So Eric should know. So whatever we've been up to, Eric, we've done in the last two years and what not, eight months, nine months. - Where do I begin? Well, the big thing I'm working on is my book. I started that maybe a year and a half ago, you know, all rounded up to a year and a half. Yeah, it's a lot of work and it's way longer, taking way longer than I thought. But it's coming along and it's gonna be a really great book. It's all about functional programming and it's not enclosure. Everyone ask me that 'cause I'm like a closure. - Why do you hit closure, Eric? Can I ask you a question? - Can I ask you a question on the deaf and closure podcast? Why do you hit closure? - Come on. (laughing) - Where do I begin? - Yeah, I know, I have a blog post ready for, I mean, like almost published about all the things that are wrong with closure. - Bring the holiday cheer, yes. (laughing) - No, I mean, specifically I think that the ideas, I mean, but it's shortly. My goal for the book is to make functional programming accessible to a wide audience and starting with closure and having to teach closure, it's just not what, it wouldn't fulfill the goal. Plus it would be kind of preaching to the choir, like we already believe in immutable data and stuff like that. So there's no, you know, it would just be kind of, I don't know, master, but don't worry. (laughing) Let's just talk about all the good news. (laughing) - Mental masturbation, you mean? - Yeah, like an intellectual, yeah, yeah. - That's an interesting starting point, though, isn't it? 'Cause if you're not gonna, I mean, obviously, what I'm interested in is like the precepts of functional programming, you know, and listen to your podcast as well. 'Cause I think that's a really interesting one. 'Cause you talk about functional programming on your podcast, but you talk about Haskell and closure and JavaScript and all these various things, you know. You identify yourself in that podcast as a closure programmer. So, but why, is that something you do in the book? You identify yourself as a closure programmer and that's your influence, or is it like, is it like a hidden hand of functional programming? - It's the big revealer than it could be. (laughing) By the way, you just learned closure. - Yeah, exactly. (laughing) - Let's put a few parenthesis at the beginning. You know, the parenthesis at the end of the middle. (laughing) - Yeah, that's a really good question. I don't think I'd talk that much about closure in the book, except where it's like, oh, you know, this is how closure does it. This is how, you know, you're learning the real thing. You know, this is how other languages do it, including Haskell. But I don't ever say like, I'm a closure programmer and I'm teaching this stuff. I do think the closure gives a very useful perspective to functional programming. Let me just contrast it with another, I think very well-designed language, Haskell. It focuses much more on the types. It's sort of like, let's get this language out of the way. We have immutable data and pure functions and first class functions, you know. And now let's get to the types because that's where the interesting stuff is. And as closure programmers, I don't think we believe that so much. And so a lot of what the book is doing is taking those closure approaches to functional programming and bringing them to a wider audience. - Yeah, because one sort of corner. - Like, yeah. Well, I was gonna say that just to give a little bit more context in the book about the book, the examples, I need to give code examples. And so I use JavaScript for that, just to make it have as wide an appeal as possible. So you don't have to learn the language before you start doing the functional programming stuff. I chose JavaScript because, I mean, it is a very popular language. But it's also readable by people who know Java or C, or, you know, you can, you can, I mean, it's readable. Like it says function, you know, when you create a function. You don't have to learn. - You don't use the ES7 syntax then, with the arrow. - I don't use any of these stuff. It's all the old school. - It's the OG JavaScript. - Yeah. - I mean, and, you know, I've had people in comments say like, oh, you use some of those new features and use let instead of const. And I'm like, like, I don't want to go into a discussion about let versus const. You know, that's not the point of the book. I'm just using var everywhere. Like, just, you know, I know that some people are going to be like, oh, but you got to teach new, it's not teaching JavaScript. That's not what I'm doing. I'm, I don't want a Java programmer to come in and be like, what is the difference between let and const? Sometimes you use that, sometimes you use that. I don't want that to be on their mind. - But it is, it is, if you, if you see, like, teaching functional programming, what I felt is like these days, every type of programming methodology that you want to learn is attached to a language, right? It's, it's very difficult to abstract it away and then explain, only I'm going to explain functional programming to you. And then you can implement that in any language you like. Some languages are more flexible to implement this. Some languages look horrible when you implement this. So, I don't think it's an easy, because, like, (laughing) Adagogi or, I don't know, the English word, like the teaching method for the functional programming is tricky, but I understand your approach because you're not going to take, you're not teaching JavaScript. I think you said it, you know, very, very, in a very nice way that you're not teaching JavaScript, you're just teaching functional programming fundamentals. - Right. - That's how you can write in version one of JavaScript and then whatever, and then later you can pick it up. - Exactly. Yeah, I mean, what you said is, is really true. It is hard and that was one of my complaints and one of the reasons I started the book is, is because so many, so many books about functional programming are either like super academic and, you know, they don't really start with the basics. You kind of have to be, I don't know, have a PhD advisor like guide you into it, or they're just about a particular language and one language is approach to functional programming. But completely, I feel like doing a disservice to the beginner who just, like, would benefit from just identifying pure functions. Like, that is a huge thing. And I think it's the start. And everyone has a little footnote somewhere, like one sentence, like, okay, and these should be pure functions. Like, what? No, that's it, like, that's the meat of it. That's where you should start. Like, talk about pure functions, why they're better, how do you identify the impure functions, and how do you refactor it so that you have less code in your impure function, more code in your pure functions? And so, my book spends the whole first seven chapters just on this idea. - One thing that I've said this many times, but I will say it again to you, and I'm interested in what your take on it is, is that I think, as a branding exercise, functional programming's got an absolute huge problem, because functional is a completely stupid name for a programming style. Object orientation is, there's something behind that. Sort of imperative, there's something behind that. Functional is just sort of a lord these days. And I also don't think it properly describes what FP really is. So I think, what's your kind of manner, I know that your book title doesn't use functional programming. It uses, you talk about simplicity. So how do you feel about that, like the branding issue is around functional programming? - Right, so I'll say the book just for the audience. Grocking Simplicity is the name of the book. But that's a really good question. - I didn't give you the questions beforehand, so sorry about that. - No, no, no, but it's a really, it's a good question, and it's a problem that, in one of my drafts, I like tackled it head on, like why am I, I kind of redefine everything, like give it everything new terms, because I feel like the terms are very confusing. Functional programming, it makes you think that it has something to do with functions. And a lot of the definitions, including the one on Wikipedia, make it all about functions. And they'll say it's programming with mathematical functions, otherwise known as pure functions. And I think that that just does such a disservice to what we do day to day, I mean, for instance, as closure programmers, we use side effects, we use a state, mutable state, but we're still doing functional programming, and I feel like we have a lot to say about state and side effects. - I'm kind of like going a bit higher level in that, because I think the notion of something that is functional means that it's something that works. In the English language, it's overloaded in that sense, that of course, programs should be functional. It feels like it's kind of like a philosophical debate, rather than a kind of a paragmatic debate. That's why I mean-- - Right, haven't we already moved multiple levels from that by introducing things calling a variables, which are not actually variables, but we already overload them. - We use so many mathematical terms in like totally different ways, right? - But not variables, non variables, they are variables. One way or the not variables. - Well, a variable in math doesn't change. - Alex is wrong there, because-- (laughing) - No, a variable in math doesn't change, it varies. - It varies. - If it's variable, then it must be subject to change. So, okay, this is a common confusion, especially among programmers. Like when you have a variable in a formula or something, mathematical formula, it varies with each use of that formula. So in this time, we'll say x equals one. Well, let's try it with x equals 10, right? Within the run, it doesn't change. - It is immutable. - When you think of a variable as programmers, we think of a place to store a value that will take different values throughout the course of it. And so then we think, but how is it a constant variable? It's like, well, it's the original variables were constant for that run, right? - But it's not the thing, though, it's not one of these, it's like where we are fighting these languages, you know? Like you said-- - Yeah, and then function, it's like, well, it's a function. It says function in JavaScript, the type function. - Yeah, exactly, function, you know? So that's why I throw away all the terms. So I don't use, I mean, I explain the terms, but they're not what I use in the book. I use actions, calculations, and data. So distinguishing these three things is like what I consider the gateway. The first paradigm shift requires being able to distinguish these things. - So what, how do you, I mean, I get data, I mean, data is definitely different from actions and calculations. So, but it's not very, you know, on first blush. I mean, I've listened to your podcast, I do know the difference, but when I first hear those two things, actions and calculations, I'm not exactly sure what the difference is. So maybe it's, that could be worth going over. - Isn't calculating an action? Well, there, so, okay, I mean, in this context, because it, you know, it's closure people, I feel like we can go kind of deep on this. It's true, calculations are actions. They're subsets. The calculation is a subset, calculations, the set of calculations is a subset of actions. And data is a subset of calculations, because we know that to, like, if you wanted to make a touring machine, it would be actions, right? It'd be like moving the head, the read head, reading a mutable value from underneath, wherever you are. So it's all actions, but you can simulate calculations using that touring complete system. And then we know by lambda calculus that you can represent data using functions, using mathematical functions. So they are subsets. The thing is, you, like, you don't want to be working on that, like, subset hierarchy all the time. You want, you want to get the benefits of the calculations and the benefits of the data. So you just kind of stick, you use the compiler's features to stick within that domain, the calculations, the data, the actions. Does that explain it? - I understand it. What you're doing, though, is you're saying actions are side-effecting, and that's a different stream, calculations, and actions in your vocabulary. - Yeah, yeah. Actions are what you might call an impure function, except the problem is function sounds like a feature of a language, right, like a JavaScript function, because a lot of actions are not functions. The action might be an assignment statement, right, or the action might be, you know, it could be a method, which is kind of like a function, but it could be an operator. It could be the plus-plus operator. So it's really, I'm trying to just, like, totally use new terms that are outside that don't have features attached to them. - Yeah, so you're using JavaScript to explain this concept in the book? - Yeah. - Why JavaScript? - Because it is very popular. - I think it broke by the beginning question, like why do you hit closure, right? (laughing) - I'm tired of all the parentheses, that's what it is. (laughing) I have to excuse Keene's broke off of my keyboard, and now I'm just tired of it. - Yeah. (laughing) Sorry. (laughing) - No, why JavaScript? - Too many. Why JavaScript? I like semicolons. - You don't need JavaScript. (laughing) - But you don't need them, but you can use it. - I love the JavaScript people get really upset. You know, some people really don't like JavaScript and semicolons either, you know, so. - I think it's like splicing up your pizza, you know. - But you're using semicolons. 'Cause if you are, then you'll get a bunch of hair from people who like, hey, you don't need them. And if you don't use them, then it'll be even worse. So what's your-- - Well, I think you can, you can have two versions of the book, one of the semicolons, one of the other ones. So you can buy one of what you like, you know? - And none of that, you can sell to both markets, yeah. - Yeah, exactly. No, it includes witty. That's so important. - Wow. (laughing) - All right, so. - Well, I mean, I do insert unnecessary parentheses in my JavaScript as well. I just surround every value in parentheses just to get a feel. I don't wanna lose my closure, my closure. - You're looking in there, you need to open up. (laughing) - I need my rainbow parens to get some rainbow. - Exactly. (laughing) - I'll end up fun. We all have funny language. (laughing) - Why JavaScript? It's really popular. So, you know, there's an automatic reach there. And then, like I said before, the syntax is readable. Even if they don't know the ins and outs of JavaScript, they can read an if statement, they can read a for loop. It's, you know, it's just something that they don't have to spend too much energy on. - Yeah. - And of course, where it is something that they wouldn't know if they weren't a JavaScript programmer, I do explain it, but it's still readable. They can still read it, and if you name the functions, you know, and clear names, they'll get it. - And who's the target audience? Because if you explain all these concepts, actions, calculations, and data, and then eventually, you need to use these techniques in whatever the language that you pick up, right? - Yeah. - So, how do you drive that home to the people who read in the book, or what is your plan? - So, the publisher has pegged it at two to three years of experience, programmers for two to three years, who already know a language. They already, you know, they've gotten into some weeds, you know, made a mess, and they need some techniques to help them through. The way to make it stick, to make it practical to them, is I have a lot of exercises, step through refactorings of the code to make, you know, some JavaScript function more, I wanna say functional, but, you know, just separate out, look, these are the side effects, these are the not, like, you don't really need to use a global variable here, you could use a local and-- - So, that's kind of like in the weeds of the area, I mean, at a high level, what is your kind of pitch around, like, functional programming, what are you kind of trying to sell to these developers, you know, when they've got there, they've got themselves, like, a few years of experience, and, you know, why should they bother with functional programming? Are you answering, you must be answering that question as well. - Yeah, so I'm attacking it from three vectors, I'm saying it helps you do reuse, testing, and maintenance, maintainability. So those are the, like, practical things I can sell about it. I think that there's also a group of people who want to do functional programming, but they can't find inroads into the current literature, and so there's a little bit of that too, but, you know, that's not something you can really sell, it's hard to find those people and target them. So really, I focus on those three, that, like, one of the reasons you're having, you know, a ton of bugs, it's hard to maintain, is you're just doing mutation everywhere, right? And it's much more maintainable if you, like, segregate that off into a little piece of code that you can spend extra time on, pay extra attention to. The other stuff is really testable, you just might test for it, and just you can leave it alone. And then the reuse also is, I mean, this is going back to the closure stuff, it's like pulling things apart. Like, we have a tendency to think that the bigger the thing is, the more it does, the more reusable it'll be. Like, you think of some kitchen gadget that can do, like, 17 different things, you think, oh, it's so reusable, I can reuse it in 17 different ways. But really, the most reusable thing you have in your kitchen is, like, the knife, the pan. You know, like, you know, just the basics, the, like, one function tools are being used for, you know, almost everything. So, that's the approach I'm taking. Like, you can actually make things more reusable by splitting them apart. Instead of having it do everything, like, make it, you know, at least you get to reuse apart, 'cause you might get part of it wrong, right? And so if there is in two separate parts, you don't have to rewrite both. - Yeah. So I think one of the, a long time ago, maybe two years ago or something, I read a blog post calling, like, programming has these three tribes. Like, first tribe is programming as a mathematical thing. Like, applied mathematics, and then it basically has to have even closure, list piece stuff into that one. And then the second one is, like, programming is hacking the hardware to CC++. So, you know, you have this, I think that's the first time I read this mechanical sympathy. Like, you need to know what the machine does or something. - Right, right, right, right. - And then there is a, so CC++ fall into that category, that tribe of programming. And the third tribe is, I just wanted to get shit done, so I'm gonna hack something in Python and JavaScript and go home. So, it's like, to make things work. - Right. - For me, I think those three seem to be valid. And do you agree with this, with this kind of classification? And if so, then how do you see this functional thing supplying to three different areas? - That is a really insightful triad there. And I'd love to read it. - I'd speak, finally. (laughing) I finally peeked by regurgitating some blog posts that I read like three years ago. - Sorry. (laughing) - So, I'm thinking about it though. Like, you need all three, right? You need all three, because like, sure, you need to get stuff done, but that kind of development is gonna make a mess. - But maybe it's what he's doing, is that the first one is kind of got already. Second one might be difficult to reach because of the kind of performance issues or whatever. And it's more like the third one, maybe, is that's the interesting target for your book. I don't know. - They get things done. Yeah, 'cause this is, I mean, I really start from in the book, I really start from, and thanks for all these like challenging questions, by the way. - Ooh, we improved from compost and PHP. (laughing) - Well, it's a lot of compost, you know, is it gradually kind of, you know, improves, you know? (laughing) - This is a, this is, all the crap that we have been collecting, finally being useful, after two years. - Decomposed rich human. - The rich little me soil in which your, your weeds can grow and flower. (laughing) - Come on. - Finally. - What was the question? (laughing) - What was the question again? Yeah, it was about-- - The getting things done, people. - Yeah, the getting things done, people, I think they'll make a mess, right? So my book, I mean, just that's, if that's the only attitude you have, I think that that's clear. The book approaches, like the first part of the, first code you see is here's an existing system, and here's how we would just like, simply get the next thing done. And then it starts to say, okay, but this is what we would do to clean it up using functional principles. And it's just a lot of refactoring. And like, I don't know, I code that way, I code something like, what's the easiest thing to get this thing working? And then I come back later and I'm like, oh, this is a mess, I don't even know what's going on, I cleaned it up. I don't know, the mechanical sympathy only comes in if I need to optimize it or something. - Yeah, yeah. - I feel. So this is something that I've been thinking a lot lately, thinking about all the, of course, in enclosure and Python, I do a lot of Python day to day, working with the data related stuff. And I see when I, when I, when I paired with somebody who's doing Python, we just do something, oh, you know, let's, let's just take it straight through happy path. If it works, we are done. Let's go home. And then on the other hand, when I'm trying to use Scala, or Rust, for example, or Haskell there, that you have to think about how to, how this is going to fail and capture that thing, you know, all the, the result types or the option types or whatnot. And then, so that's a kind of a different thinking. And closure seems to be falling in between somewhere. It's super productive because of all the rattle and this kind of things. And also somehow because of immutability and all these things being available, I think my life becomes slightly easier. So I could see moving between these three, but as you said, I can totally agree, like, you know, if I'm writing something in Python, I'm like always waiting for when it is going to fail at some point, and then, and then try to fix that bug. - Right. - And so especially dealing with data, you know, it's, it's a pretty tricky situation to deal with. - There's no problem, essentially, like, I mean, I know, yeah, I know, I agree with the JavaScript choice in the sense that it has got broad reach and it's got a kind of interesting, what do we say? It's got an interesting functional nature, you know, because, you know, there is an argument that he was going to write it as a kind of version of scheme. - A scheme. - But then he was like, yeah, you gotta put this, you gotta put these, make it look like C because we want to attract Java developers, blah, blah, blah. Who knows what that, you know, I don't think that story is fully told yet, but certainly the concept of, you know, F.P. was in there from the beginning, that's for sure. But my question is, and this is one of the things that when I'm like trying to not evict closure script people towards closure script rather than JavaScript, is that, you know, I talk about kind of defaults rather than possibilities because with JavaScript, like most during complete languages, like you said earlier on, you can do everything. But the question is, what is idiomatic? What does the language help you to do? What does it make straightforward and simple? And those are the kind, that's why functional programming languages are functional programming languages. And that's why object-oriented programming languages are all languages. You can do everything you want to do in C, knock yourself out. You can B.F.P. and B.O. or you can be a clarity if you can do everything you want, new logic there. So the question is, you know, assuming you're going with JavaScript, do you ever allude to the fact that, you know, there are other languages that could make this more idiomatic, make it more supportive? - Yes, that's, that's all I learned. (laughing) - By the way, after 20 chapters, this is the only chapter you need, you know, you're not close to move on, right? - Right. It's sort of like in that book about Java concurrency, the joke that Rich Hickey read it and wrote closure so that he wouldn't have to do all the stuff in the book. - Exactly, yeah. - Because it's really true, you read it and you're like, "Oh my God, I have to do that." Like it's so hard. Okay, so it's a really good question. So I look at it like this. If you really want to learn functional programming, you need to do immersion. You need to get into a functional language and, you know, try to solve problems with the constraints it's putting on you because that's what functional languages do. They constrain you, they make you use immutable data, they, you know, if it's typed language, they're making you use the type system, you're gonna, you know, you're going to be forced to do it. And that is the best way to develop the thought patterns and the mindset that you need. However, as a pedagogical tool to teach the concepts, I actually think JavaScript is a good language for it. It might be better ones, I don't know, but JavaScript was good because for instance, when I, if I were to introduce immutability in closure, it would be like, okay, it's just a language feature. I don't need to know how it works. I'm just gonna use it. Whereas in JavaScript, it's a discipline. You don't get it by default. You have to do it. So you get to see all the work that it takes to use immutable data. You know, basically you do a copy on write or a copy on read and you have immutability. And so now you understand it. You understand the cost of the discipline and the difficulty of doing it. Okay, now you're gonna appreciate when you go to closure and have to use it. - Is that how it works? And is that the feedback you're getting because I'm interested whether people, 'cause like you say, if people are having a suffer pain, people don't like that, you know? But I guess what you're saying is you can see it from first principles maybe, you know? So yeah, there are libraries that help you out here and there are other languages that can help you out even more. But actually this is like a first principles kind of model. - It is a first principles model. And it's also like, you know, I say it's like getting back to basics in functional programming. I would be happy if people just could identify mutation, right? Like, oh, this is unsafe to call because it's gonna change the, you know, JavaScript array, I pass it. Like if they could know that, right? Or like, oh, I can't hold onto this thing because I don't trust that something else that doesn't have a reference that's gonna mutate it. Like if they could do that, that would be a huge win. So if people still put any bangs at the end of their function names, that's already a stop, basically. - Yes, exactly, exactly. Just be careful. You can do it, here's the rope, you wanna hang yourself, you know? Go ahead. But it's that kind of thing that I really think that other books don't talk about. They don't, they just do not spend any time. They don't spend enough time. Like I said, they might be a sentence, a paragraph, but they don't spend enough time for beginners to realize, like for instance, that the plus plus operator actually does three things. It reads the value out, it adds one to it, and it stores it back. And so that's three things happening. One of them is a calculation, the adding, right? But the other two are actions, and you can interleave another plus plus operator in another thread between those, and it, you know, gives you weird mistakes that only happen sometimes. - The funny thing is, I remember, I remember reading that Swift does not allow plus plus. And they had a very long like discussion about this because they were saying, yeah, exactly to your point, you know, is that it has all these magical properties that cause a lot of unknown bugs. And so yes, it's convenient. Yes, it is sort of, you know, expressive. But actually, it's just too dangerous and too buggy. And you know, the things are not, what's going on is not obvious enough. So they actually disallow it, which... - I mean, you could disallow it, or you could make it an atomic operation. You know, you could say, well, if you're gonna do it, we're gonna put a transaction around this, and nothing else can look at this variable in the meantime, and you know, it'll slow everything down. But 'cause it does look like it's a single thing. - Coming back to the, so the book is called Grokking Functional Programming. - Grokking Simplicity. - Simplicity, sorry, it's called Grok. My brain already linked Simplicity with functional programming. - Another interesting point about that actually is like, what was being, where does the simplicity come in? How do you, I know, sorry. (laughing) - Very common. - So that's the thing. I probably need to go through and just use the word Simplicity a lot more in the book. It's kind of just like a historical accident that it's called Grokking Simplicity. It probably would have been called Grokking Functional Programming, except they already have, look, by that title. - I like Simplicity, by the way. I mean, I think it's a great, for me, I think it's actually a good re-branding of functional programming, you know, because I think functional programming is terrible, like I said at the beginning, and I think Simplicity is much better, because that's really what you're trying to aim for, you know, clarity, simplicity. - Yeah, and it's another aspect of the closure influence that I was talking about. - Call back to closure, yeah. (mumbles) (laughing) - So yeah, yeah, the Simplicity is all about, you know, pulling functions apart into more reusable pieces. It's about the complexity of having so many actions and they can interleave, right? And so the complexity is like, how many ways can they interleave? So, you know, it's a quantitative thing. If you have two actions in each thread, there's, you know, I think six ways they can interleave, something like that. But if you have 12 actions in-- - But what about JavaScript single threading? You know, 'cause that's what people will say about JavaScript as well, don't worry about the threading 'cause it's all fine, yeah? - And they do say that, don't they? The problem is once you have Ajax, you have any kind of asynchronous call, then you're back to, I mean, they're not threads, but they're different timelines because you will chain an Ajax call after another one and after another one. And that's, there's multiple of these chains happening at the same time. And you don't know when each one is gonna be called. The callbacks are gonna be called. And then you also have this other problem of stuff is happening on the server, right? So you read a value and you think it's current and you add 10 to it and send it back. Well, what if someone has already changed it, right? So you need to be thinking about this in a distributed systems world. I mean, I think that, so functional programming has been sold as like, we're gonna need it because of multiple cores on our machines, right? - Yeah, yeah, yeah. - And I mean, it certainly helps with multiple cores. That's not untrue, but we were also promised like thousands of cores by now, like 10 years ago. It's gonna double every year and it hasn't. We have like, what, 16 on like-- - 16, yeah. - Yeah, like we are though facing all these distributed programming problems that we weren't facing or we weren't maybe aware that we were facing them 10 years ago. We didn't have so much Ajax. You would even have just like one database. And like, now we realize, oh, we've got a client running on every browser and we've distributed our application to all these microservices and each one has its own database and they have to sync up somehow. And this is where functional programming and this is why it's actually being used right now. - It's not going to, that the scope of functional programming is not going to go across these boundaries of systems. - Right, no. - But how do you see that then? Because within the system it makes sense. - Yeah, functional programming does not give us a model for programming the cloud, right? - Yeah, exactly. - What it does is it gets us to ask the right questions. It gives, it says, oh, this is an action. Even though it seemed like I was just writing something or reading something from the database. Like, oh, that was actually a message that got passed to a different machine and the database interpreted it and sent back an answer. So it's actually two messages. You know, object-oriented programmers don't think about that. I mean, they do, they do. When they get to a certain maturity, they know this, but they're not thinking of it as part of their paradigm, right? They are having to learn it, but it's not part of the paradigm. And in fact, a lot of object-oriented programmers, if I could generalize, they try to bury it, right? So they'll take the ORM, right? And they'll wrap it around the database and then maybe add another layer on top and think that that's going to make the difficulties of dealing with mutable state go away. It's gonna like, oh, it's gonna give it a nice interface. But like, no, what you need is to pull it out. You need to not wrap it up. You need to separate out the stuff that is dangerous, you know, the mutation, and you still have it. You need the database, but then separately, you have like all the business logic and stuff to keep it pure. - So just, I mean, I think you do talk about this on your podcast that you saw, I'm guessing it's gonna come up in your book. Things like idempotency, for example. That seems to me to be a kind of answer, if you like, to the distributed database problem, because you need to know that actions can be repeated essentially, or in your case, calculations can be repeated. Actually, which do you think? - Actions, actions, you need to be able to, you know, I mean, the example I give is you wanna send an email exactly once. - Right. - You don't want it to send it zero times and you don't wanna send it twice. And so if you don't get, if you don't hear back, you make some HTTP post and it gave you a 500 error. Like, did it send the email though? That's what I really care about. And you can't know, like maybe it timed out and you never received it, but maybe the server crashed after it sent the email, right? Or the network got moved down before the request came, like, you don't know. And so the answer, you know, for robustness, that you need in a distributed system, is to be able to send it again, send the same request again, and assume that they will remember, oh, we already sent this one and we won't send it again. And so that means you need the action to be idempotent. So, yes, that's an action being idempotent. - What about transactionality? Where does that fit into your scheme? - So in the book, we are going to develop transactional, like, it's sort of like a closure atom, but that works over asynchronous changes, right? So, you know, you might do a read and then do some Ajax request and then use the value from that to do a write back into it. And so you need, it's gotta be transactional across that whole thing. So basically, you have to queue them up. - Right. - You have to, you just have to, you know, wait for everybody. We're gonna do the regular atom, but that's easy in JavaScript 'cause there's no threads. - So the order is like straightforward 'cause it's just single threaded ordering, so you don't have to worry about the ordering problem. - Yeah, yeah, exactly. Exactly. The ordering happens automatically, as long as you don't have any synchrony. So you pass a pure function to the atom, it's gonna take the current value, run it on the function on it, the return value is gonna be the new value. - So, is this a groking simplicity? Is it now available as like a beta book or something that people can take a look at? - Before we get into it, you know, let's just let him pimp it out a bit later, okay? Let's carry on with some of the technical discussions, okay? Hold on a second. - That's an insult to this podcast. - No, I mean, the thing I was gonna ask you about was another thing to do with like functional programming, groking simplicity, whereas maybe it's kind of at odds, but I'm interested in your thoughts about this, is high order functions, because to me, high order functions are, I don't know if they're undersold or oversold, to be honest, I don't, I do use them most days by some of enclosure, but obviously with mapping all kinds of stuff, but I mean, also I will write programs that take functions, but I rarely return functions, to be honest, but I'm just wondering, you know, what your take on like the higher order of higher, because obviously it's important when you're talking about functional programming, or is that something that you allied, or is, you know, are you focused on this concept? - Oh, good question. So higher order functions, I think, are really important. They're the focus of the second part of the book. So the, you know, the first part, the idea is just let's just identify actions, calculations, and data. That's where, it's sort of like what's the biggest bang at the level that they're at? Like, biggest bang is like, know that that is unsafe. We can't do that really nearly. We have to put some boundaries around it. And then the second big bang is, well, you got these first class functions. And so what can you do with them? And so that's an introduction to like map filter and reduce. It's also an introduction to higher order actions. So this is stuff like being able to pass an action to a queue to make sure that only one gets run at a time in the right order, right? - So you want to introduce the declarativeness of action so you can declare and then execute them. - Right, exactly. That's, you know, I think that's a hard concept for people to know that like, you don't have to send the email. You can have a function that will send the email and you can call it when you're ready. That is exactly the kind of mindset shift that has to happen to get your first order functions. - But in day to day life, we are used to this one, right? If I make a list of things to do, like, you know, go to the market, buy milk, then go and get a tram, right? And it doesn't mean that you immediately second by reading the second one, I'm going to get the tram first. - But you see what happens is when you write the program, you are already at one level of running removed, right? So I'm writing the program, do X, do Y, do Z, that's, you know, and I'm main, right? And so people think, well, that's it. Like, I've already made that. And so every time I run this program, it's going to run everything. - Yeah. - What they don't realize is they can do it again inside the program and make it so that this thing is going to write the list and return it. And this other thing is going to run the list. - Exactly, so that's the shift that I think you need to, that people will need to make. And it's going to be like, you know, a lot of, a lot of people get map filter and reduce. They understand, you know, how to use it practically. I'll have a list and I want a different list. You know, I'm just going to run a map over it. But what they don't understand is how much can be done as a total pipeline, like all your work is done as like chaining map, map, filter, filter. You know, you can, you can do the whole, almost the whole program, is that. And so that we're going to focus a lot on that. We're going to focus a lot on the actions side. So that's kind of just the calculation stuff. The action side, these chapters are actually mostly written. I feel, so this is a thing I have about functional programming. Like everyone talks about pure functions and how great they are. But I think we have, as functional programmers, we have a lot more to say about actions and immutable state and like, like you were talking about idempotence, Ray. Like, I don't know, object-oriented people saying this, right? They're talking about stuff like that. We have a whole array of things that we know are important transactionality. Like, we discredit ourselves, right? We don't give ourselves enough credit that actions are a first-class part of our paradigm. In pure functions are part of the paradigm. It's not just pure functions. We're not just avoiding actions. No, we are treating them in a special way because they are so volatile, so dangerous to the source of bugs. And so we have all these things that we do to maintain the order between two actions like in different threads. At least make sure that they don't happen at the same time. One has to go first. We discredit ourselves. There's a lot of good stuff in functional programming languages that help you deal with actions. - So one of the things that, I mean, this is like, let's say in the closure world at least, it's caused a bit of controversy recently with spec. Is this speech by Rich about speculative? I think, maybe, I don't remember them with the, I don't remember the talk actually, but it's where he says that the optionality is a problem. And that's why we need spec two. - We were joking earlier, by the way, that spec started at the same time as defen. So with spec about the same time that we're experimenting with podcasting, and they've got spec two and we've got Eric two. So maybe it's, it's kind of- - Yeah, I'm out of alpha then. - We've got him back. - Right, yes. - We make it better. We know what functional programming is now. But what I meant was that, so is something like, 'cause you say, it's like the optionality, how do you know if things have worked on it? You know, 'cause that's the classic functional thing, it's like, you know, it's the option thing, the more nothing, you know, it's like, it's something, it's nothing. So how do you tackle that kind of thing in the book, or is that sort of version two, or chapter three, or whatever it is? - So I am gonna get to that in part three, some form of data modeling. The problem is, you know, to answer your question, the reason is hard to answer your question, is that that is the furthest part of the book. That's the last part, and I haven't-- - It's optional, is it? - Yeah, it's maybe gonna happen. No, but I don't know what I'm gonna say. Well, I don't know the specifics. The thing that, to bring it back to simplicity, the thing about data modeling, is that it makes your program simpler. When you get the data model right. So if you have a correct data model, you have fewer if statements. And if statements are multiplicative of complexity. So if you have two if statements in a row, if you count the number of paths through those two if statements, it's two times two, 'cause it's two branches in the first if times two, in the second if. And if you get your data model wrong, that means that you have to kind of reassemble, like figure out what you really have. So the example that you can give all the time is like, well, what if you have two booleans? But you only have three possible states. Two booleans can represent four states, and you only have three. So here's an example. I used to work for a company, and we had a workflow engine, and something needed to be signed off by two people. So we would have a boolean for the first person signed off, and a boolean for the second person signed off. But that doesn't really make sense, because how you could, in your code with a bug, put the second person has checked off, and the first person hasn't checked off yet. And that doesn't make sense, like it shouldn't be representable. And so a better model would have been, nobody has signed off, or one person has signed off, or two people have signed off. And that way, there was no fourth option that's not representable. Because if you have this, now you have to check. And so that's another statement, and it just multiplies you, I mean, about-- - I think the exact Talman street, or somebody retweeted Zach's street, like every boolean eventually becomes an enumeration. - Right, exactly, yes. And they say the same thing in the Haskell world. You know, they say, you're using a boolean, but you might need three, and so what are you gonna do, wrap it in a maybe? - Yeah, it's worth it. - You know, and it's like, no, you need a new type, right? - Yeah, yeah. - You know, a common complaint in Haskell is like everything you do requires a new type. - Yeah. - About optionality, just for context, Rachiki was talking about the maybe type, and how it didn't solve the problem that he wanted to solve, which was a program that will evolve over time, and if it evolves to where an argument is not needed, but still acceptable, so it's optional now. In a language that if you used Haskell, you would need to now wrap that in a maybe, but that's a type change, and so that requires all the clients of your API to change. And there's various workarounds, you know, and I've talked to Haskell people and they say it's unfair, and I think that it's not unfair. He was complaining about this one type, and that is a limitation of the type, and we as an industry need to learn to accept limitations like that. It is a true statement. Whether there's workarounds in the language or not, it wasn't, he wasn't talking about like, Haskell is bad or anything like that. He was just saying, this one type has this limitation, and we should recognize that, which I agree with completely. I don't know what else to say about it. I think that maybe is a good thing for modeling. If you do know who, what I wanna say, like you have a fixed domain that you're modeling and things don't evolve, but it has to be where the optionality is baked into the domain. Do you know what I'm saying? It's not where you're like discovering whether it's optional or this thing might evolve, and so you don't know whether you're gonna return it or not. It shouldn't be used for stuff like that. - I think one of the problems, I think that maybe it's Haskell, the people I've got a point about, is that like a lot of closure programs are not monadic in the sort of Haskell-y sense. They're not optional. You've got these, like you were talking about earlier on about these data pipelines, and you can map this, filter that, do the other, and it's all gray until, suddenly you get an old pointer exception in the middle, and then you're fucked, excuse my French. Well, it might as well get a fuck out in the, you know. - I know it's been like over an hour. I don't know what happened. Usually it's like the first 30 seconds. - Yeah, I think we were recording at that point when Vee just got out. - I heard the magical words to open this podcast. - Yes. (laughs) - Yeah, so what I was gonna say was that, you know, that's kind of, like that, you know, and I think people do get upset about that, you know, when they sometimes leave closure because of this, even if they get so upset that if they get these no pointer exceptions, and they're just like, they're going to fuck it more, you know, if you get it, I just can't take it anymore. I can't take tracking down no pointer exceptions. And I, if I'm honest, I think closure is annoying in that respect as well, that it doesn't give you more context. You know, I think this is a solvable problem by the compiler. But, you know, we always joke this about April 4th, you know, is that, you know, I think they once said that a closure is optimized for correct programs, but it's not okay. (laughs) - Yeah, it's not optimized at all, in my opinion. - I know the emails you're gonna get. - Fuck 'em, yeah. - Anyway. - It's not enough to rain. - Oh, but we don't listen to people's feedback at all. I think that's what we're trying to say, actually. - If we listen to people's feedback, we wouldn't have said we're doing this, you know, come on. - Exactly. I think they would have, they told us all, like, for our first episode, what the fuck is this? Stop it. But now we're here after three years, 56 episodes, so, you know, we might as well get on with it. - We will take guest requests, that's all. You know, that's... (laughs) - That's what we do. Anyway, so coming back to optionality, you know, I mean, I think one of the nice things about this show is that we are able to just, you know, voice, you know, in real talk, if you like, you know, then it's a problem with closure, in my opinion, and it's... - It is. - Region might as well just put it on the table there. It's fixable, you know, with, and I think they've acknowledged this, it's fixable with the development version of the compiler or some, you know, some sub-optimal performance. You could fix this problem. But they don't do it for every, that's up to them. You know, there are engineering efforts and costs and trade-offs and, you know, what gets first in the Q, et cetera, blah, blah, blah. But the point is it's not done, whereas, you know, in other programming languages, it is done. So you don't get this kind of, like, this random little point is in the middle of a pipeline. - Sure, sure, or if it's in a language like Java, where you still have a lot of null pointer exceptions, you're not doing some, like, super high-order operation, where you're, like, looking at the stack trace, like, I don't know where my code is and where the compiler's, or not the compiler, but the built-in, you know, the map. You're doing a map, except it's lazy. So it doesn't, it doesn't, null doesn't get you until later in your code, like, and the function that you passed was an anonymous function. So it's like, doesn't have a name, which is a number, and you're like, I don't know what function that is. - But this is a problem in Haskell as well, right? It's anywhere, the laziness adds additional complexity to this problem. - Yeah, I mean, you don't have this exact problem because there's no null in the language. - Yeah, exactly, yeah. - And I think that that's another thing to, like, tease apart, I had to do this myself. I was very confused. Haskell, it's not the type system that is protecting you from null, pointer, exceptions. There just is no null. There's no value called null. And so they, because they don't have a null, but they wanna represent optionality, they have maybe another stuff. So then the problem is that maybe brings back a lot of the issues with null. Like you might not have a null pointer exception, but if you have a nothing, you don't know where it came from. - Yeah. - You know, if they're chained together and you're doing some, you know, you're using maybe as a monad, like somewhere in that chain, it became a nothing and then the rest was just skipped. And so it do have like these similar problems. You know, people will say, yeah, but at least you knew that that was a puzzle. Like I don't buy that, I knew every line of code I have could have a null pointer exception, you know? - Exactly. - I sympathize with closure programmers because like, especially new people, like I don't get them that much. And so it's one of these things like, I've developed all these disciplines that I'm not even aware of anymore. Like just always, it's always in the back of my mind, what happens if this returns null? Is it gonna fall through? Is it gonna do something like, is it gonna do the right thing basically if a null happens? And often I find that the closure built-ins do the right thing, sometimes they don't, right? So you, you know, you can't always just check, you know, the classic is I'm gonna filter for identity, right? But what if there's booleans in there and there's gonna be some falses? So now you're mixing the nills and the falses, you're throwing them all out. So now you need to think, oh no, I need to filter nills out. So nil question mark. Or I guess you would remove nil question mark. So there's things like that, these little habits that I have that I don't even, I don't even have them conscious enough to just list them. But I do have to say over time, you don't get them as much. - You've got a null symbol. (laughing) I mean, for me, it is not that much of a problem. I know you're just. But for me, it is not a problem that requires like, oh, maybe I should go to another language. Like it's just not that level. - Yeah, yeah. I mean, it's a trade-offs, right? Because the other advantages that you get with the mutability and the way that you can fluidly write code, I think it makes sense to have some, I mean, we are saying that closure has its flaws, but they are completely manageable. - I think the difficulty with Eric's point of view though, and I agree with it that you can develop certain habits. I think the difficulty of it is when you're in a team and you've got like five or six people all committing code and they have got those habits. And maybe you're not very disciplined in your PR process. And then you've got issues, you know, 'cause then other people are like, they're not exactly breaking your code, but they're putting the possibility of nulls in there that you don't know about. And that's, you know, I mean, I know that you do a lot of work on your own Eric for books and for podcasts and stuff like that, but you also do consulting. So, you know, I think a lot of us do work in teams of like, you know, three, four, five people. And then, you know, it has to be named. You have to be able to do things in a certain way. - That's true. I totally agree with that. Like, and you want to be able to have, let's say, a junior, you know, like new hire, fresh to closure, contribute. And if you're just always worried that they're going to be introducing null pointer exceptions because it's so hard, they don't have all the disciplines yet. - It's nice that our conclusion is that it's other people, that it's possible. - Well, I'm paraphrasing, of course, but you know, like, you know, what is the other people mostly? I'm fine, fuck it, you know. - Yeah, I mean, who was it? It was, what's his name? The guy from id Software was giving that talk on functional programming for a while. He was learning Haskell and Scheme. And he said he really liked Scheme, but the reason he would do Haskell is-- - John Carmack. - Yeah, John Carmack. Thanks. He was saying that, you know, with a sufficiently big team of developers, like every bad habit is going to come out. - Exactly. - And so you want as much, you know, help, you know, this is the kind of company they're writing in CNC++. They buy those million dollar like bug finder packages, you know, that like, two static analysis on your code and tell you, oh, this for loop, like it might, it has this one case where it might skip a, you know, and like go into an infinite loop. Like they, they are investing in that. And so something like Haskell, it to, you know, to them is much more like, well, let's, let's give the programmers a little, like let's put this closer to the programmer so they can solve their own problems, not catch it later. I have also heard really smart Haskellers say that what the reason they like the type system is because they can be like, you know, a Kung Fu black belts level Haskell person and develop a type. So they invent a new type that's like a monad with stack. And like they make the type that they know is correct. And then at least they know that no one else can do harm, right? So it's a way of multiplying their knowledge out because now it's, it's in the code and the compiler is checking it. And so even if they can't, they might not be able to figure out how to get their code to compile, at least they're not thinking they got something right and pushing it to production. I have to sympathize that in a very, in the practical sense because I have been on teams like that where, you know, most people were working at a very high level and then the juniors were not able to contribute because the stuff was just over their head. I mean, the stuff we were doing was like high level closure stuff and every time we would like, they would contribute something, you know, pull request, the comments would be like, oh, like, like, oh, this is gonna crash in this case, in this case. And it was just too much. It was too much that we weren't getting anything good out of them. And, you know, it makes you think like, well, that's why everyone wants senior closure programmers. It's like. - Yeah. Everybody, I think Closure has seen a people's code or seen a people's programming language. And it almost sounds like, you know, you get to use after your 65 and you got some discounts and shit from all that. - I mean, even the stuff like, you know, are an atom, a simple atom. The contract is, you know, pass swap, a pure function, and it'll be fine. That's it. It's like, it's not much to think about. Except, you know, what if you don't? I don't even know what happens if you don't. How is it a pure function, you know? What if it does a def inside that function? Like, what is gonna happen? It's gonna be called, I don't know. And that's the kind of thing that people do when they're first learning closure. And that's totally fine. It's just, you know, nothing's checking. - But I think, I think that in this case, I think, you know, there are sort of levels of checking that you can do, like, I think like the CLJ condo stuff and the other bits and pieces that, you know, the linters, they're definitely pretty good, you know, but like you said, there are certain, the interoperability things where nulls can creep in or certain use cases where a certain function will produce a null, but other variants will not. They're very slippery. They're very difficult to encode, necessarily. 'Cause one isn't necessarily wrong. It's just wrong in a certain context, you know? - Yep. - People are used to languages that, well, okay, I'll have to say, it's similar to JavaScript, where there are parts of the language that are like, no, no, no's, don't use that. And there's a lot of stuff that you kind of have to use 'cause there's no other option. So you have to like become an expert at this. Like, what are all the ways that, you know, this can go wrong. What are all the ways that you can abuse like the plus operator and get weird values out? You have to know this. - Oh, what? - You know, there's stuff like-- - Equals and equals and equals equals equals. - Right, you have to use equals equals equals everywhere. Not the double, double, double equals. And it's, I think that what we have and that I like have internalized and don't think it's that big a deal, but it probably is, is very similar to in JavaScript. - Yeah, so we still need discipline. - Yes, whereas in Haskell, I mean, you know, I guess you could say, at least you don't have that. I would love to see a bridge between the untyped and the typed. I would love to see more experimentation in type systems. You know, when Rachiki gave that talk, it was called maybe not, if you want to look it up. One thing that I think got overlooked was, he actually showed an example of a type system that did what he expected. So it was in Kotlin. That in Kotlin, you put a question mark after the type and it makes it an optional, which means it allows nulls. Okay, but it's checked by the compiler. So if you don't check for the null, then it'll complain to you. It won't compile and what's that? - It won't break the clients. - And then right, if you add a question mark, it doesn't change the clients. They don't have to change any of their code because they were already passing it. It's optional, but it's accepted and so they're fine. And I think that, what I want to say, like that kind of statement, even though he made it and it was very clear and there were slides about him, it just like people just totally overlook it, right? They want to focus on like, why are you bashing on Haskell? You know, Haskell is this and Haskell is that and it's good. - It's good, it's so annoying. - I know the level of discourse we have is just so bad. And I want to see more of that. I want to see more, I guess, developing type systems with practical use cases in mind. And I think that that Kotlin example is, it's a great example of what I'm trying to say. It's like, these people are writing a language for Java Interop. They know that there's going to be nulls everywhere. It's just the nature of Java and they need them. They need nulls sometimes. And so they, they developed a type system that had a very practical, like the type system itself has a notion of null. Whereas in Haskell, like I said, there's no null. And so they used, you could write maybe. You could write it yourself in Haskell. So it's not built in. It's like not, anyway, I'm rambling now, but I think I would like to see a bridge, like, you know, I want Haskellers or type theorists to work in an untyped language and see, oh, I see it, it gives me this freedom that I didn't have in my type system that is actually really useful. How can I take this back? How can I make this safe? I think it's always the kind of, I mean, you know, we have like functional programming meetups. And you know, we always, we look at Haskell talks and elements, stuff like this, but it always ends up boiling down to productivity versus correctness. Or like, you just want to be able to experiment with something, you want to be able to explore something. You know, you can do that in closure very easily in JavaScript as well, but in other languages, more type languages like Scala and Haskell, there's a lot more formality around getting things right before you start programming, before you start playing with things or experimenting with things. And it's, I think it's, that's a very difficult, what do we say, a bridge to cross, you know? - Yeah, I agree. I think that, so like Haskell, I mean, what if you had an unsafe Haskell? Like, what if you had an untyped Haskell? So you defined a semantics for what it's supposed to do without the types, right? So like, you know, just made it a dynamically typed language similar to closure, right? - It's meant to be an experimental ground for compilers, so why not? - Right, yeah, exactly. And so you just define, like, this is what it would do. And so now we don't have to, we could run it without checking the types. Now I know that Haskell does have a thing where you can run it without checking this, that's how I'm talking about. I'm talking about, like, actually being at a REPL, being able to construct Haskell, you know, expressions, get some JSON from some random API that you know very little about and start working with it. And it's without knowing the types. You don't know the types yet, you know? You know, one thing that people bring up when I wrote an article a couple of years ago about how Haskell is difficult to work, it makes it hard to work with JSON because you need to, like, fully type it before you can, and like, it's not, people will say, well, how do you work with JSON where you don't know anything about it? And that's not the point, you do know a lot about it. It's just how difficult is that to express in the type system, right? Like, I know that I work with, say, the WordPress API and it gives you JSON and it gives you sometimes, like if there's a, like, what we might call a null, well, sometimes it gives you false. And sometimes it gives you an empty array, right? So it gives you null, false, or empty array, and these are all kind of equivalent. Well, how do you express that in Haskell? Like, this is the kind of thing that, you know, or it'll say, well, if we have this key, then this other thing is gonna be of this type. But if we have this key and it's a number, well, then this other thing is like, okay, we know a lot about it, we could express it in English, but how do we express that in the Haskell types system? That's the kind of thing that I think the bridge needs to happen on. Like, I mean, I just, I will say it like this, it's probably wrong, it's probably a generalization, but the people working on Haskell compiler, you know, extending the type system are academics. They're probably not hitting WordPress API and stuff like that. So, yeah. - I think the solution is that don't use WordPress API. - Right. - Right. - We just... - Oh, look, look, look, look, we can talk to you forever. You're gonna have to come back in the third time, you know? - Yeah, when the book is published, maybe, you know what I mean? I hope not in two and a half years. - Well, yeah, like one zero, and it's out of alpha. We'll have you back. - Right. - And like, we can take that bet. I'm pretty sure you want me back next week, that's for sure. - Yeah, for sure. - So, maybe I think it's a nice time to tell people where you can actually find the book. - Oh, yeah, and we finally get there, yeah. So, yeah, exactly. - Yeah, so, the book is called "Grocking Simplicity." It's published at Manning. So, if you're, you know, buying from, it's only available on Manning.com right now. But if you go to lispcast.com/gs for "Grocking Simplicity," that'll take you right to the page. If you want 50% off, I have a code. It's TS Simplicity. One word, just when you check out, you can put that in, it'll give you 50% off. I think it'll also give you 50% off of everything. So, if you want to buy a couple of other books too, just from it's-- - Is that a special, deaf and offer? - No, it's not a special offer. I mean, even if it was a special offer, like, it would just be a different code. (laughing) 50% off, it seems to be pretty common. (laughing) - So, it is on the meet them. - It's on the meet. Yeah, so the first five chapters are out. I'm actually a little ahead. - What's happening, early access program? - Yeah, man, early access program. So, you, if you buy it now, you'll get an email every time the new edition comes out. And so, yeah, you'll get the, you'll get it all. And then, you can even buy the print book now. And you'll get the e-book. So, you'll get the updates as they come out. And then, when it's finally printed, you know, just like-- - I'll get an email one day. - Like, oh, look, I remember this. - Mm, you're like getting Christmas for somebody, but you don't know when Christmas, 2020. (laughing) - I think it's when you get the book, it's Christmas. - Oh, there you go. - Yeah, you see, I'm getting better at marketing. (laughing) Better salesperson than me. - Yeah. So, go to lispcast.com/g. - Yes. - For good. - Sorry, for growing up. - Not getting simplicity, yeah. - So, that's where you can get the book. I think it's, wow, it's one and a half hour. I mean, time is just flying. I mean, we could, as Ray said, we could, we could talk for hours. - I know Ray had all these topics built up, all these tough questions. - Yeah, I think that's what we ask here. Tough question is hard, just off these. (laughing) - Only with these two. - So, those leads. - I know exactly. (laughing) - And just a quick shout out to other things. So, you do apropos every now and then. So, that's on apropos YouTube channel. - That's right. - We'll put the link somewhere where you can see and where Ray tries to solve computer programs. - You can, yeah, you can actually see it and then see how Eric and Mike and who else are already? - Me, yeah, sorry, yeah. So, they can try to solve the problems. They try to solve the problems and then show you better closure code. And, Eric, what is your podcast? - Lispcast.com/podcast. It's called Thoughts on Functional Programming. Yeah, so go and check out Thoughts on Functional Programming. I think eventually it'll be really branded to Thoughts on Simplicity as it's gonna be there pretty soon. (laughing) I hope. So, that's it from us for this year and it's been, I think, almost three years and it's a nice fantastic episode to wrap up our year with with a repeat guest, Eric. Thank you for sharing all your time and all these amazing discussions and hopefully somebody will pick up the idea of, you know, making closure more Haskell-like or making Haskell more closure-like. - I've had that idea type system for closure. - Who? - But, yeah, so who has the time? (laughing) - There is a type system for closure, but, you know. (laughing) - Yeah, I've changed on the PhD in it. I mean, these things are, these things have been trodden. The ground has been hard before, so, you know. - Show that to him. - Yeah. - Yeah. So, that's it from us for episode number 56 and we'll be back in the new year, 2020. - You can have flying cars in definite on 2020, for sure. (laughing) - Exactly. - You can cheer. - Yeah, it's a challenge flying car set. Flying cybertrex and shit and whatnot. And, yeah, and a big thank you for all our patrons and we've been helping us in covering the costs. And, we look forward to your suggestions. If you have any complaints, just redirect to dev know, and we'll be there. - Can you hang it around and avoid it, yes. - In the know. (laughing) Thank you, thank you, Eric. - You're welcome, thank you. - Merry Christmas and Happy New Year to everyone. (upbeat music) (upbeat music) - Happy New Year and Merry Christmas.