 Welcome everyone to the session. FB is the new objective oriented programming by Michael Sleumann. And we're so glad you could join us today, Michael. And yeah, thank you so much for doing this. But without further ado, over to you, Michael. Okay. Thank you very much, everyone. Nice to virtually meet up with everyone. It's been a few years, I think, since functional conference since last time I was there. Glad to get to connect with everyone again. So hopefully everyone can see my slides. Just a confirmation from someone in the chat. Perfect. Okay, cool. So this is FB is the new key. I'm Michael Sleumann, and let's dive in. I've said things like this at many different talks I've given in the past and I don't think people really believe because I'm the Haskell guy Haskell guy. Obviously that means I'm a functional problem. I don't really consider myself much of a functional programmer. So that's, it's a funny thing to be saying at a functional programming conference, but we're going to start off that way anyway. So I've been working 12 plus years professionally with Haskell a few years before that, non professionally. I also use plenty of other languages that I would or I write code that I would consider functionally inspired in other languages. This includes recently I've been working with Rust and TypeScript in addition to Haskell. Years ago I'd even wrote some Java code that I would type in, I would write, like, I would download a passcode, but I used to do a few different types of stuff, like, I'm not using any of those things. I'm only using some of these, I'd use these code in here, in the US, but in the U.S. I'm not using anything similar to these. I'm not using anything new. I'm not using anything new. And I'm not using anything new. I'm not using any of these, I'm not using anything. I'm not using any advanced coding, to be giving this talk with a friend of mine, Adam McAuliffe, and he gave me an eye-opening analogy that I wanted to share for this. People may be familiar with Freud. Freud was a huge pioneer in the field of psychology. He basically created psychoanalysis, and that's based off of, you know, two minutes of reading Wikipedia about him. But these days, if you say Freud and you talk about Freud's theories, people don't bring up all of the incredible innovations he came up with. They don't ascribe these great things to Freud. Instead, you hear these relatively speaking corner cases of Freud's philosophy. You hear about things like the Oedipus complex, or Freudian slip, and I will avoid making some jokes here, even though they're very funny, because I'm being recorded, but maybe offline you can tell some Freudian jokes. Question is, why is this the case? And Adam had a great insight. The stuff that he got right, Freud, now these things are transparent to people because they become ubiquitous to our understanding of psych. Anything he got right, people just accept as part of mainstream psychology, and the things that maybe are a little weird, a little off the beaten track, those are the only things that stick around as being Freudian. So keep that idea in mind. I think it's a great analogy and a great framing device. And now we're going to jump back in and talk about what is functional programming. There's not really any, I mean, there are lists. You can, again, you can go to Wikipedia, you can go to other places, and you can get an idea of what makes something a functional programming language. And you get some of these ideas like higher order functions, immutability, declarative coding, which frankly, I think is a cop-out on the functional programming part. Everyone claims that they're doing some level of declarative coding. We like to claim it. Lazy generators are typically part of functional programming. I'm a Haskell primarily. And in Haskell, we obviously have lazy data structures, and we use lazy lists as our lazy generators. Many functional programming languages have rich type systems. And we'll get in type classes, those two really go together. This is a fair list to define functional programming, maybe. And if you come from a different language like closure or something, and you're upset about things like rich type systems, don't worry, the list is not intended to be authoritative. Let's go back in time a little bit further. Before Haskell came along, before the functional programming revolution that many of us are a part of, you had languages like C. And if you have a language like C, we can ask a basic question today. Is it a good language? And I think many people here are going to say, no, C is an absolutely horrifically terrible language. When you write C, everything you are doing is based on pointers. There are no generics. You have to write either void star, you have to coerce types all over the place, or you have to write multiple copies of functions in order to make things work. Us functional programmers love generics generally. Manual memory management, that's a thing of the past. That's something that silly people write because all of us use garbage collection these days, and that's obviously better. And C has relatively speaking very weak abstraction capabilities. Many of us would say that this is a fair assessment of the C programming language. But I'm going to tell you we're all wrong. Instead of asking to see a good language, let me ask a different question. Why was C invented? Where did it come from? Many people have used the phrase for C that it is a portable assembler. It's better than writing assembly because assembly is the thing that people were writing for that kind of code before it. C brought many innovations. C brought forward the idea of portability. Previously, if you wanted to have code that ran on multiple different architectures, you had to write it multiple times. Now with C, you could write the code once and have a compiler compile it down to multiple different architectures. That's a huge step forward. Instead of having to write jumps and comparisons and all these other things at the assembly level, C introduced control structures. It completely changed the way that you write code. C added in type safety, which seems to contradict what I was just saying, that C has weak types and not great abstraction capabilities and no generics. But when you compare C to what came before it, the type safety is amazing. C allowed you to have code reads. It became much easier to define functions, define libraries, and use them across multiple projects. And as much as we today beat up on C for this horrible, evil, manual memory management, memory management in C is leaps and bounds better than anything that came before it. So it's interesting in this way of looking at things is all of these points, these five points, every single one of them looks like a weakness of C compared to modern programming languages. But when C came out, every single one of them was a huge step forward from what came before us. Let's go on a little bit further in history. Talk about how much object oriented code sucks. We're at an FP conference, therefore we all agree that OOP is dead, OOP is evil. It's the worst thing that ever existed. And again, I did five minutes of research and I looked online and I wanted to see what are people complaining about OOP these days. One phrase I saw that came up is it's a big blob of global, beautiful state. Class hierarchies make no sense. I think we all, anyone, anyone of us who went through learning Java or C++ at some point, you remember learning about how an animal class has subclasses of cat and dog and you tell them to speak and they say, yeah, woof. But none of that actually makes any sense in real life code. It's a weird example that doesn't actually add up to real life. We also know that Java does ridiculous, funny things like abstract class being factory, factory, and OOP encourages really bad abstractions. And all of these are things that FP does way better than OOP. And that's why we hate OOP and why we've moved on to better paradigms like functional programming. Hopefully some people, especially Scholar people, some people are getting their blood boiling in the audience right now. Feel free to feel that way because we're going to take a U-turn. My claim and the whole point of this talk really is that there's a lot more to OOP than the things I just described. And you may be able to connect the dots with why I brought up Freud at the beginning, what I was saying about C, maybe you're going to see the pattern at this point. So let's dive into this. There is much more to OOP than these ugly points that I just picked up. OOP said we should combine data and code together, which you may like it, you may not like it, but it's actually a very common practice in many languages. As I mentioned, C, if you wanted to do something on multiple different data types, you had to define a function multiple different times. OOP really pushed the idea of name overloading, which theoretically at least reduces the cognitive overload, the cognitive load of running code. OOP was massive on encapsulation. You should be able to hide away complexity inside functions, inside classes, inside things, whatever the level of encapsulation is. OOP was really pushing the idea of good abstractions. We in the FP world often look at OOP and say, oh, those are stupid, bad abstractions. But really, if you look at what OOP was coming from, it was really innovating in a good direction. Generics became a big part of OOP. And in the functional programming world, we use that all the time. One of the jokes that I've heard repeatedly in the Haskell world is you can solve any problem in Haskell by adding another type variable. We love these things. And also programming to interfaces, a massive part of OOP. Don't write your code against some concrete type, write it against the interface. It's a common pattern in Java. When you hear people criticizing OOP, you don't see them pointed to any of these six points. Not usually at least. Why is that? That's because these concepts are the ones that won. And now we can finally, in a programming talk, I can actually show you some code. And I apologize in advance. Code is few and far between these slides. So enjoy it while you can. This is a idiomatic great implementation of the sum function in Haskell. And for those who aren't familiar with it, I'm going to just step through it very briefly. The sum function says that it works on a T of A. T has to implement some type class foldable, which for our purposes, we can look at that as a container of things. And num A means that A has to be something which is numeric in nature. And if you give some a container of A's, it gives you back an A. So for example, if you give it a list of ins, it'll give you back a single int. Or if you give it a vector of ins, or if you give it a map that contains ins in it, and so on and so forth. The point is it's going to take a whole bunch of ins and collapse them down. And our implementation is pretty interesting. We're going to leverage the fold map function, which is generic on anything that's foldable. It's actually also using the semi-group or actually monoid type class under the surface. We're going to use this new type wrapper called sum to say the way that I want to combine these things together is with addition. And then I'm going to use function composition to combine that concept together with get sum to unwrap the sum wrapper. Let's talk about what this code is doing. It is programming two interfaces. That sounds a lot like OOP, doesn't it? Num and foldable are both interfaces. Nowhere in here did I say anything about lists, ins, doubles, or anything else. We're dealing with abstractions. The concept of a monoid, the concept of sum, these are much more abstract. They're great abstractions. They work all over the place. You can write really interesting code as a result of these abstractions. This is a little bit tongue in cheek, but we've also encapsulated a lot of the complexity here. People who are really into OOP encapsulation will probably yell at me and say I'm misusing the term encapsulation, but I'm the one talking. I can say whatever I want. Sum is really hiding away some complexity of the idea of being able to add things together through combination. That's kind of cool. And of course, everything here is based off of name overloading. The sum function now works on any combination of num types and foldable types. The fold map in there works on any kind of combination of monoids and foldable. Sum works on any kind of monoid. So instead of having to define things multiple different times, we're able to define this one function based off of reusable components. So I would argue that this piece of code, which I think everyone would agree, most Haskellers, because you can't say all Haskellers for anything, most Haskellers would say this is really good idiomatic Haskell code, and I'd argue it is following object-oriented principles, which really means people are going to be pissed at me right now. Yes, I'm being very fast and loose with definitions on both the FP side and the OOP side. And my points here are not to argue about any of these specific definitions. Later on, I'm sharing some other forum people yell at me on Twitter about this, which is great. I love getting yelled at on Twitter. But let's go. The real question about this is not, what are the exact definitions? My question is, why do so many of us seem to despise OOP? Why is there an attack and a hatred of OOP in the functional programming world when we seemingly adhere to many of the principles, at least on some level? So let's review what I've said so far in this talk to review the history. We had a language called C, and it made significant improvements on the programming status quo, which was assembly at the time. It introduced new concepts, new abstractions, and it was great and made coding much better. Many, most, maybe all of those improvements were then adopted by languages that came later. You don't notice that because it became so common that every other language was doing those things. But some of those things that were left behind, some of those things were not adopted, some of the things that weren't great, things like having to manually manage memory. Those were left behind. You either got garbage collection, you got RAII, you got some other techniques. And all those things that got left behind, we modern programmers, people who grew up in a world already with object-oriented programming or functional programming in it, we look back at C, and all we see is the crappy parts of it that were left behind. OOP stands on the grave of C to some extent, even though C is live and kicking. And OOP followed exactly the same pattern. It went ahead and it made a bunch of improvements that really, I was actually just beginning to learn programming at the time that OOP was really taking off in industry. And OOP came along, it introduced these concepts that solved real-world problems that existed. The things that OOP nailed and got completely correct, all the future languages picked up on and continued to do. And now when we look back at OOP, especially us in the functional programming world, we don't see the cool great innovations that improved the status quo. We instead see the crappy parts that we don't like stuck behind the crazy design patterns, the weird abstractions. So I'm just going to read over some of the chat messages while I sip my coffee a little bit and see what people are going to say. Yep. Yeah, I agree. This is all about differences from what came before it. Yeah, that is the pattern that I'm getting at here. Okay. So now let's talk about FP. This is my personal favorite FP features and might look cherry picked, but this is actually it. I love the fact that when I'm writing Haskell code, I have strong types. I have ADTs, algebraic data types. That is such a huge step forward from every other thing that I use beforehand. I never want to use a language without those ever again. Cheap new type wrappers are another massive part of my Haskell and functional programming experience. I love them. I think they make code quality much better. Pattern matching is so much better than other kinds of ways of doing conditionals. Type classes are a smarter, easier to work with approach than interfaces or having to do extensions, see abstract classes, any of the other approaches that we approve. So I think these are great. And what's really interesting about this is the two other languages that I've been working with the most recently, Rust and TypeScript, both have, if not all, most of these features. I'm not sure if you can really argue that TypeScript has type classes, but it does have the other three. And if you just squint and change the names a little bit, Rust has all four of these, at least to some extent. And what's even more interesting, very few people would really make the claim that Rust or TypeScript are FP languages. So what we're seeing is, at least for me personally, what I consider the wonderful pieces of FP have already been adopted by new languages that have come out recently, relatively recently, and they don't consider themselves FP. We all know that imperative languages are evil. Let's look at how bad this C code is. Yay, we get some more code on the screen. So this is C. We have this mutable variable here called total. We have another mutable variable here called i. We have short circuiting, meaning we are not going to continue running this loop. That's another bad practice, according to most functional programming standards. We are mutating total. Again, we have to keep track of our loop explicitly, and we print things at the end. Now, everyone can probably stare at this for a little bit, and you can figure out what this code is doing. But it's not exactly intuitive. You can see here that we're looping from the number i is going to be the numbers 1 through 10. Not too difficult to see. You can squint here, and you can see, okay, well, let's see. i modulus 2, not equal to 0. Not equal to 0 means that it's going to be odd. Yeah, it's going to be odd. Then we're going to continue. That means we're going to short circuit. So we're not doing the odd numbers. We're doing the even numbers now. And here, we're going to take those even numbers, multiply them by 3, and add them to total. Okay. Not terribly complex, and it's obviously a contrived example. In fact, it's a contrived example I've used in many of my talks in the past to demonstrate FP principles. But it works. Let's compare this what I considered convoluted C code to beautiful FP master. And here, I believe that you could take a non programmer, show them the screen, and they could get a pretty good idea right off the bat about what this code is doing. We can see right here, we're iterating over the numbers one through 10, one dot dot 10. Someone who didn't know what that meant, I could explain it very easily. Filter even pull map times three, we're now going to apply times three, we're going to triple every single value that was even in the map. And then we are going to sum them up. This is this is the kind of code where FP really shines. It's a clean separation of all of the logical components of our code. Another thing that's nice. Every single bit of this is fully immutable. I never had to mutate a variable. Sure, under the surface, the computer is actually mutating things in memory. It's mutating registers. I don't have to worry about that. My code is cool, pure, immutable. I have sensible combinators. Instead of having to reinvent inside a for loop, the concept of mapping and summing, I'm able to reuse functions that already exist. And I'm lazily generating values. I don't have to worry about allocating an entire array. Instead, Haskell is going to lazily produce these values. And if you turn on optimizations, you're not even going to end up getting any allocation. All of this is going to run in a tight inner loop. And that's really beautiful. So that's functional programming. But let's go ahead and move over to a non-function programming language. Previously, we looked at C and we saw imperative languages are evil. Let's look at another imperative language, Rust. Rust, we are going to read the code backwards to the way that we did in Haskell. But it turns out we are functionally doing exactly the same thing. We are using one dot dot equals 10. So slightly different syntax, but basically the same thing. We use the filter function. Rust doesn't have a built-in even function. But that looks close enough. We're then going to map. Rust doesn't have partial function application or partial operator application or sections. So instead, we have to do an explicit closure. That's not too bad. And sum. So sure, it's a little bit more verbose than the Haskell code. But conceptually, it's identical. Right now, if you go to a Rust station and you bring up this code, they will probably refer to this as functional style, which is cool. They're still giving a nod in the direction of us cool FG people who came before them and came up with all of these great ideas of functional programming. But very quickly, this is simply being called idiomatic Rust code. And that's an important distinction. People aren't saying I'm writing FG and Rust. People are saying I'm writing Rust the correct way. By contrast, you could do this exact code from Rust the imperative way, the bad way. This is now functionally basically identical to what we had previously in the C code. I used a while loop instead of a for loop because for loops are slightly different than Rust. But it's still the same kind of concept of short circuiting, mutation, et cetera. If you write this code in Rust and you go and you share it with, say, the Rust subreddit, I put quite a bit of money down that someone is going to critique it and say you shouldn't write it that way. You're doing things the imperative way, the mutable way. It's not idiomatic Rust. It's not the right way to write Rust code. And that's very interesting. Just for the record, you can write the same kind of crappy mutating code in Haskell if you're really determined. One of the nice things about Haskell is that it makes it really difficult to write code in the wrong way like this. So what's my point? Functional programming has introduced amazing new concepts to the programming world. And I believe we are all much better off for the fact that FP has influenced what's going on in the world. However, the best parts have already been stolen by the languages. When I got started writing Haskell code 12 years ago, most languages didn't have easy ways of doing lambdas. Lambdas are now all over the place. I believe both Java and C++ have added lambdas in the past 10 years. JavaScript had, what is it, ECMAScript 6 to provide a simple lambda kind of syntax. And everyone uses them. You don't have to feel embarrassed when you use this kind of thing. MapReduce, when I first started teaching or teaching or at least talking about Haskell in general, I repeatedly got this pushback of why would I want to learn that concept? I could just write a for loop. People legitimately believe that using for loops instead of mapReduce, fold, all of these kinds of concepts was much easier to just learn the for loop once. I've not heard anyone make that claim in the past five years, at least. And that's because the concept has gone all over the place. When I was reviewing a co-worker's TypeScript code recently, I'm not any kind of an expert on React. I used it a little bit, and I was a little amused to notice that for each and map are just commonplace and the idiomatic way to solve problems in React these days. I have a particularly fun story, though, about JavaScript and the result type. So I work here at FP Complete, and FP Complete started off exclusively as a Haskell shop, and we've added additional things that we do over the years. One of the things that we now provide is we provide Rust services. We were contacted by a team of JavaScript developers who were working on some front end code, and they came to us completely for our Rust expertise. They didn't even know that we were a Haskell shop. They didn't know we had anything to do with Function Program. And they started describing this problem that they had where they were trying to use a Rust library call out show from their JavaScript code. And one of the issues that they were running into is they saw this weird result type, and they didn't understand how they were supposed to deal with the result or even why the result was a part of the API in Rust. So I started explaining to them what result is, and for those who aren't familiar, Rust results is basically like the either type in Haskell. It is an either okay or error ADT enum, some type, whatever you want to call it, and it allows you to do proper error handling in Rust. I get about 30, 45 seconds into this explanation, and the JavaScript developers interrupt me, and they say, oh, you mean a result is a monad, which was shocking because my entire career up until that point with Functional Program had been monads are evil and scary and terrifying, and no one wants to learn them, and it's the reason why people are avoiding Functional Program. And all of a sudden, out of left field, I had people who were not Functional Programmers, not familiar with Haskell, didn't even know that I was familiar with Haskell, and they considered monad to be such a commonplace topic that they could use that to explain what previously I would have thought would have been the simpler concept results. So we can definitely see the influence of FP has gone deep into industry. So we're going to have a next generation. I consider putting in some kind of a Star Trek meme at this point. But anyway, we're going to have a next generation of programs. This next generation of programmers are learning languages where the functional programming concepts are built in from the beginning. Unlike myself, unlike other people of my generation who started off with imperative or object oriented programming, and then they had to go ahead and they had to learn functional programming concepts. People today who are learning JavaScript are learning about math right from the beginning, people learning Java and even C++ perhaps, they're learning all these things from the get go. 4H is 4H immutable by default kind of coding standards, pattern matching. All of this is considered normal programming, not some kind of weird FP thing that we have to do instead. As a result, FP focused languages, languages like Haskell or Scala or Closure or other kinds of languages, we're no longer going to stand out from the pack based off of these features. Someone comes up to me at a JavaScript conference and they say, hey, I heard about this Haskell thing, why should I use it? And I say, well, it's got immutability. I'll say, yeah, so does Rust. I say, oh, well, it's got Closure. I'm like, yeah, so does JavaScript. None of these things are really going to go ahead and help themselves. What did Nourish say? Hotel, for people who can't see the, who are watching the recording, hotelmonad.in. So apparently, monads have really taken off in industry. Okay. Instead, like imperative and object oriented programming before, FP languages are now going to stand out, not for the cool innovations that have taken the world by storm and everyone is using them because they're so great. Instead, I predict 10 years from now, maybe even less, people coming out of school, people starting to write code for the first time, they're going to look back on languages like Haskell for the things that other languages haven't adopted. So what are those things? Just small subset laziness. Haskell, even within the functional programming community is somewhat unique in being a lazy language. Lazy generators, things like Python's generators or Rust's iterators, those are still lazy generators and they're great, but the general concept of having a lazy language, that's going to stand out. I actually already see this when I'm training Haskell. A lot of the time, we have to almost become apologists for the fact that Haskell is a lazy language because it does stand out as a weird thing that for many people makes code much more difficult to work with. Purity is something that, again, I'm mostly speaking Haskell, purity is something that many other languages haven't picked up on. Now, there are some concepts in general that people say, hey, your small functions should be pure functions. People understand some kind of advantages of purity, but the idea that we should have Ion-Lunatic code in order to have complete referential transparency throughout the code, I can't really think of another of a mainstream language that is picked up on that and standardized on that. Hieracondid types. I actually think Hieracondid types are a great feature that other languages should pick up because I don't think it's a particularly complex thing and I think it's the power to weight ratio on it is pretty good, but many other languages do not pick it up and I see the impact of that. When people see Haskell and they have to learn Hieracondid types, they get a little bit scared. Similarly to the way that they used to get scared about map and reduce, well, these days they're not scared of that. They're scared of Hieracondid types. Category theoretic nomenclature, with some exceptions like monad, which is actually caught on, you don't see people embracing things like semi-groups and whatever, all the other things that come from category theory. Those things are now becoming the reputation of languages like Haskell. And so we end up in a situation where the most powerful features, at least in my opinion, the most powerful features of FP have already been adopted and embraced by other languages and the features that maybe these are good, maybe these are bad, depends on your standpoint on these, but these features are now becoming the reputation of FP and FP is beginning to lose some of its allure because it doesn't carry the same power that it used to. So what do we do about all this? They've stolen all of our great ideas. Functional programming can no longer compete in the marketplace because everyone is already doing it. What do we do about it? Some language ecosystems have experienced this in the past and they've taken the complain about it approach. We can run around and we can say, you know, Haskell did that first. We had list comprehensions before everyone else. I don't know why people love Python list comprehensions. Haskell did it better. Also we can say, no, that's better in ML or it's not as elegant as it is installed. Please, please let's not do this. This is a wonderful way to ostracize people and get developers to think, oh, it's those salty functional programming people. I don't want anything to do with them. Let's go off and have fun with them because they suck. So I advise against taking the complain about it right. Another thing we could do is we could simply admit defeat. We could say that functional programming languages now are a waste of time. All the good features got stolen. Other languages have taken over. Time to just jump on to whatever other language bandwagon exists. I think this is completely missing the big picture of what's going on. Something that I think is much closer to the mark is instead of defeat, we declare victory. The fact is for many of us, the point wasn't about our particular pet language winning. The point is we want to have better software development in the world in general. On that basis, I would say that we have actually done that with FP. The great concepts of FP have made better programming languages out there in the world. That's what we actually care about. We want software development to be a better discipline. We succeeded by making these great concepts popular. Therefore, and this is the part that I'm not actually advocating, this is the bad part of the message here, we can just let the languages quietly die off in a corner while new better languages take over. It's closer, but I'm not quite satisfied with that being the takeaway from this. Here's something that I actually believe we can do. One thing is declare our niche. One thing that I absolutely believe is that Haskell is one of the greatest languages that exists for proper concurrent programming. STM, software transactional memory, is basically unrivaled in any other language. Haskell does a better job of it, in my opinion, at least because it has purity built in from the beginning. Purity and referential transparency makes STM an incredibly powerful tool. The ability to write concurrent complex concurrent code with a library like async. I don't see that getting passed up anywhere else either. You combine those two things together, you can really define a great niche for Haskell excels beyond other languages. Parser combinators, I still believe that the greatest parsers I've ever written, the easiest way to write parsers have always been with a parser combinator library like Parsec. EDSLs, still best in class, is a language like Haskell that allows you to define arbitrary operators that has great support for this kind of setup. Point being that FP languages still excel beyond the features that have been adopted by others, and we should be playing to that advantage. If someone comes to us and says, why should I be using FP? Why should I be using Haskell or Scholar or something else? We can no longer simply talk about the cool features like mapping and immutability. We have to talk about these more avant-garde, these things that are on the more cutting edge that really give us our advantage. Another great takeaway that I don't think many of us notice, but I see it in my training work, is that the barriers to entry are greatly reduced. When I first started learning Haskell, and later when I started teaching Haskell, there was a massive barrier to entry. I have told a story a few times of the first thing I ever tried to write in Haskell beyond toy programs was some kind of a web service, and I was using the CGI package at the time. This is way long ago, and CGI for those who are wondering, it's nothing to do with images. CGI is the common gateway interface, and it was the way that old web applications were written and tied into web servers like Apache. Back when I got started, I remember reading the documentation on the CGI package, and it used monads, and I had no idea what a monad was, and I bashed my head against a brick wall for a while. I broke my brain, and eventually I got some kind of working code, and I got a web application to launch, and yes, okay, now it's time to use a database. So I go to the docs, and it says something about databases. Great. It says, to use a database, you'll need a monad transformer, and I do not exaggerate when I say I closed the computer right then, and I took a break from Haskell for the next six months because I could not face the thought of having to learn a monad transformer at that time. This kind of learning curve still exists to some extent for Haskell, but it's not nearly as steep as it used to be, like I mentioned with monads. Monads are now a common topic out there in the world. It's not weird to have to teach someone about recursion and mapping and reducing. All of those are common topics these days. Another thing that we can go ahead and we can take advantage of is that functional programming languages are a great sell to normal programs. If you are out there writing day-to-day JavaScript code, you may end up being a better JavaScript developer if you learn functional programming languages. You can take those concepts and bring them back and write better JavaScript code as a result. We can also learn from the market. FP has been a Petri dish for new ideas. Some of that has to do with its academic background. Some of it has to do with the kinds of people that adopt FP, so some level of selection bias. Some of the ideas that we have created in this Petri dish of FP have flourished, and I've mentioned many of them. But as I've also mentioned, many of them have been ignored. I may offend some people here, but I'm going to claim that we should not dogmatically stick to our guns. If we have come up with some ideas that we think are cool, but the rest of industry is looking at it and saying, now we're not ready to accept it, we shouldn't automatically believe that the rest of industry is correct, but we should at least be willing to learn and say maybe they have a point. And finally, I think one of our takeaways should definitely be humility. Unlike the way I started off this talk saying that OOP sucks and C sucks and all these other things, and FP is just a better way of writing code, let's change the tone. FP languages stand on the shoulders of giants. All of those innovations and improvements that have come before us, we have adopted and we have absorbed into these FP languages. We should recognize that FP has a history of learning from others. And I think at this point we should be going out there and seeing what ideas should we be stealing from other languages. It's not fair that everyone else gets to steal our great ideas and not the other way around. We should recognize other languages and other ecosystems, other concepts are out there for us to explore. It's okay to adopt established best practices from industry. It is true that there are many cases out there and many of us got into functional programming because we see problems. We've seen perhaps a local maxima where Java or C++ can only get us so far and then they get caught in some kind of a trap and FP improves on that. Those things are definitely true. But sometimes they are actually pushing for good ideas and we should be embracing that. That is the end of the talk. So now I will take questions, which I see at least one is already coming up. Yeah. Okay. So one question, all advantages in Haskell in the current times is just about better libraries for STM etc. Couldn't other languages adopt those libraries? Okay. So STM in particular is one that I really picked on. Because STM really can't be adopted by other languages without fundamental changes. It's true there are other languages that have some level of STM. But the real thing that makes STM as powerful and Haskell as it is, is the fact that we have purity. And since that's really the basis, you can't just shoehorn it into a language. I think I could be mistaken on this. I think I heard that the .NET team tried for quite a while to add STM into the .NET languages and eventually they had to give up because they really didn't have that purity backing everything. Hopefully that answers the question. If you have a follow-up, let me know. Are there examples of concepts we can learn from other languages or ecosystems? I think overall application design and structure is one of the big ones. How to do logging. Some of the very mundane boring things. How to load up a config file. Sometimes we in the functional programming world spend a lot of time reinventing the wheel. How to build code, put it into a talker image and ship it. I see a lot of the, you know, I spent a lot of my time on the DevOps side of the shop also. And when it comes to functional programming, I see people really trying to reinvent the wheel more often than we need to. There is another concept that I didn't mention in the talk, the concept of a novelty budget. And we should really pay attention to where are we getting the most leverage, the most power to wait to use that phrase again. One of the most powerful things we're getting out of functional programming, focus on that and use more standard techniques for the other things. Okay. It is definitely a long ways away but could you foresee an FK language being the first to mainstream quantum computing? I can definitely foresee it, but just to be completely honest, I'm far from an expert on anything related to quantum computing. So I would be very hesitant to say something like that. I would imagine something like, you know, monadic code, applicative code, do notation. I can imagine something like that coming into play, but I'm grasping at straws. So I probably said something very stupid and people laugh at me, which is great. Go for it. Okay. Have you noticed any nice ideas that Haskell hasn't adopted yet that make the language even better? Let's say, oh, and yes, thank you for the great talk comment. Thank you. You know, recently I've been in the Rust world quite a bit and I think there are a lot of ideas over there that are worth adopting. One of the big things that I've worked on in the Haskell world is my library called Condor, which is about streaming data. And I think it's great and it's wonderful, but it's far enough away from the core that you can't use it for everything. One of the things that really struck me when I jumped into the Rust ecosystem is that iterators are such a fundamental part of the language. Every single thing in that language is built around iterators, down to for loops being built on it. And as a result, you end up being able to write very efficient idiomatic code because everything in the ecosystem supports it. I really believe that if we had something along those lines, probably based on string fusion, but we had something along those lines in the core at Haskell, that could be a revolutionary concept. Things like the fact that Rust has the VEC type and VEC is universal again and everything is built on top of VECs and slices. Instead in the Haskell world, we've got strings and text and byte string and all of these things are ever so slightly different from each other. So yeah, I do think that there are some great things to learn. What do you think about Java, Fp and Haskell Fp? Can they learn from each other? I can't actually answer that question, just because I don't know very much about the way Fp is done in Java. I've heard a few things. I think even someone in the chat mentioned streams in Java. That's one of the things I've heard, maybe we could be learning from. And I think maybe some libraries in Haskell have learned from that. But overall, I have to defer just because the last time I did Java in any kind of serious way, it's probably 15 years ago. And I got scared with just several notes. The reason I ended up on the journey that landed at Haskell was I got scared of Spring MVC, way back in the day when you had to write massive XML files to get anything done. And I went all over the place looking for a different language. Stopped off at PHP and Perl and other surprising things along the way and eventually ended up at Haskell. Is functional reactive programming supported in Haskell? Yes, there are functional reactive programming libraries in Haskell. I think there have been some really cool innovations in that space. I don't know how much they're being used these days, especially as approaches like virtual DOMs on the front end have really taken over. Functional reactive programming, I think is taking a little bit of a dive. FRP doesn't just have to be for UIs. It can be for data processing and other approaches as well. But overall, it is supported. I'm just not up to speed on what the current best practices are. That was an amazing session. Thank you so much for sharing your experience with us, Michael.