 I'm going to be talking about something that I've been thinking about for a while, but first let's talk about me a little bit. I work for a company called Alasian. When I first started out at Alasian, I did next to no Functional Programming. I did a little bit, but not much. Now pretty much always I'm doing Functional Programming. Last week I had to modify a Python script and I wrote like five lines of Python. We used side effects, but almost every other time I'm doing Functional Programming. I'm based in Australia and there's a lot of Functional Programming happening in Australia. Is it much happening in Bangalore? A little bit, but you end up if you do like a significant amount of Functional Programming. Okay, that's pretty awesome, that's awesome. So I grew up in a place called Brisbane and there's a lot of Functional Programming is there and I learned Functional Programming based on that, so if there's a community in Bangalore that's getting people to learn Functional Programming, that's absolutely awesome. So I hear this thing sometimes, I hear it at work quite often, but I hear it outside of work as well, which is that there's no such thing as a silver bullet. And if we look up what this is referencing, we'll find something written by Fred Brooks in the paper's title that there's no silver bullet. And his point is that, one of the points in the paper is that there's nothing that comes around in a decade that significantly impacts us to a order of magnitude in reliability, in productivity, or in simplicity. So his point is that we should be trying to get great designers, trying to improve programmers and not focus so much on the technology. And he says that there's significant differences in programmers between the average programmer and a great programmer. So his point is kind of that there's no such thing as tools that will improve your productivity ten times, but there are programmers that improve your productivity ten times. I don't really agree with this, I haven't actually experienced anything like this. I don't have any, I haven't worked with anybody, that's ten times better than the average person on the team. So this was Fred Brooks' experience at the time. And so we can't really talk about, like there was no study about the paper, there was no, it was all based on experience. So when this is referenced, I question why this is referenced so often, considering that there's not a huge amount of evidence, it's mostly an experience report. I think it comes down to that if you search for, like, there's no silver bullet online, you'll find arguments saying that there's no tool that will improve, that will significantly reduce all of your problems. Which I don't think is a very useful thing to say, I think that's just true. Like there's nothing, there's nothing insightful in that message. Like if I stub my toe, Haskell's not going to fix that for me. I understand that, and I don't think that's a useful thing to say. But I often see this argument as well, which is that no silver bullet means that there's no tool that is going to significantly be better than any other tool and everything's about a trade-off. And if you consider that, that's quite true. If we take availability and consistency, for example, sometimes you want consistency, sometimes you want availability, there's a trade-off there that you have to decide for your particular problem, what do you want, what do you need, what does the customer need. When you're choosing an algorithm, you have to choose between space and time sometimes. Sometimes there's different complexities for algorithms, and some will be more efficient in space, some will be more efficient in time, and it depends on your domain, which one makes more sense. Then we can go into tools, specific tools, and say that Git is better at some things than Mercurial is better than some things. But there's a trade-off in deciding which tool to use. And then there's Emacs and Vim, everyone loves this one. I'm a user of Vim key bindings in Emacs, so I'm probably the worst one. But there's a trade-off in when you use Emacs and when you use Vim. Vim is better at editing things in some ways and Emacs is better at editing things in some other ways. So there's trade-offs. And then there's YAML and JSON. I don't actually know pretty much anything about YAML, but I am assuming that there is a trade-off between YAML and JSON, just because this is so common that I'm able to say that any two particular tools, there's a trade-off between them. And this is almost true all the time. But I'd like to switch over to functional programming, talk about functional programming for a minute. So this is the first functional program we're going to look at. It's pretty simple. All of these programs are exactly the same. They might operate slightly different, but they denote the same program. And if we have this property, if we have the property that if we just calculate the value based on the expression, then that is functional programming. And so that property is actually called referential transparency and it's a property of expressions. So if we are programming with that property, if we're programming with the property of referential transparency, then we are doing functional programming. Functions are a particular way to create referential transparent programs, but referential transparency is the property when we're talking about functional programming. This is a couple of benefits, one of them is reuse. This is a program that's got some duplication in it, right? Everyone agree that we've got some duplication? So it would be ideal if we could reduce the duplication here, right? Like I'm someone that absolutely hates duplication. I hate any duplication in our program. I hate this. I want to do better than this. And so if we are doing functional programming, this will work. We can always take expressions and put them out into a variable. This will always work in functional programming. If we're not doing functional programming, this won't work. So if print line here is not reference transparent, we can't do this. If we were doing something like JavaScript, for example, doing this would result in Hello World being printed once. In a functional program, if we're doing functional programming, this will print, this will be equivalent. Those are always equivalent in functional programming. And that's a property of reference transparency. So that's one benefit we get, reuse. We can always extract duplication out in functional programming. Another benefit we get is refactoring. Just in general, refactoring, if we've got some code that looks like this, so we've got some function and we've got some binding inside of the function, we can always lift out these definitions. If we're using side effects, if, for example, fromname or make client configuration had side effects in them, this may not be a safe operation. We might be calling bind before. If we transformed it, this side effect, if this was a side effect, and this was a side effect that happened in a different order. And that might cause problems for our program. If we're doing functional programming, we don't even have to care about that. We always know that that's safe. We can always make that refactoring. Does that make sense to everyone? Anyone a bit lost by that? And lastly, a benefit that I really like about functional programming is equation reasoning. And here's a program you don't have to understand it at all. We're going to step through and figure out what this program does because it's a bit complicated, right? So we're calling traversing. We've got two arguments, a list and print line. And in functional programming, we can always substitute those arguments into the function and we get the same program. So this is the same program as before. We just remove the function and we inline the arguments to the function. And so we're just doing some fold write stuff and what we've inlined also is the print line here before that was F. And now we've inlined it, but we get the same program. We know we get the same program because we're doing functional programming. If we reduce that another time, so what we've done is taken the fold write and we've reduced it. So then what we'll do is we'll print out hello and then we've got the rest of the list. Fold write takes something from the list and then uses the rest of the list to calculate something. So this is the rest of the list, which is the same call. So we can actually reduce that again. So now we've got an empty list because we've taken the world off. We've got empty list, empty list. When we do a fold write, we get the second argument. So reduces to that. And there's some laws around this. We can actually reduce that to just this, which is pretty simple. And if we had special syntax inside of our language, it looks something like that. So we're able to take something that looks pretty complicated and we don't know what it does. And we're able to reduce it one level at a time or many levels if we want to and figure out exactly what the code does. Does it make sense? This is only a property of functional programming. If we try and substitute in these arguments, we might actually get a different program if we use side effects. And so this is only a property of functional programming. So these are only benefits for humans. These are some important benefits I get out of doing functional programming. Compilers get other benefits. They're able to use some of the same tools that I was showing, like being able to inline arguments and things like that. Compilers can do that. But I mainly care about the benefits for humans. For humans, these are huge benefits to me writing programs. I get huge productivity improvements and being able to reason about the code a lot easier. So we should, if we're talking about there's no silver bullets of functional programming, we should compare the alternatives to functional programming. And if you Google around functional programming versus something, you'll find things like functional programming versus imperative programming, functional programming versus object-oriented programming and a few other things. But I've done a significant amount of imperative programming using functional programming. So I don't really see these things as being the opposite of functional programming or being alternatives to functional programming. Someone, Peyton Jones, even wrote a paper saying that Haskell is the world's finest imperative programming language. And I find that to be true because we get a lot of the benefits that I was talking about. We get the benefits in reuse and refactoring, but we can still apply it to imperative programming. For example, this is an imperative program. I hope everyone agrees with that. But using the tools, I could refactor it to look like that. And so I'm still able to write imperative programs, but I might be able to write them slightly differently and I'd be able to use all the same tools that I use in functional programming to write imperative programs. So I don't really see these as antonyms or as opposites to functional programming. I don't really see these as alternatives. I see these as tools that I can use when I'm doing functional programming because the primary thing that we're talking about is referential transparency. And I don't think imperative programming says anything about referential transparency. So really what I think it comes down to is functional programming versus not functional programming, which if you apply the definition that I gave for functional programming, referential transparency, you can kind of see it as something like values versus side effects. So I see this as the alternative to functional programming. So if we're going to insist on not doing functional programming, we have to insist on doing side effects. Does anybody disagree with this? Roll on the same page. So let's look at the benefits of side effects then. If we're going to consider the alternatives of functional programming, we have to consider the benefits that side effects will give us. And I've not been able to come up with a single benefit inherent to side effects. Like I completely welcome anyone giving me a single benefit of side effects, but I've tried for probably like a year now just thinking, is there a single benefit to side effects and I have not been able to come up with one. So because of this, because we've got quite a few benefits to functional programming and we've got what I've been up with, we've got no arguments for side effects that I've been able to come up with. I sometimes have colleagues that say, we need to do Scala because Scala lets us do functional programming and use side effects. So we get the best of both worlds. And if I'm not able to come up with a benefit of side effects, I'm a bit wary of that opinion because it sounds like we're getting, we're making a compromise, but one side's getting things and one side's not. And not only that, there's a bit of a problem with trying to mix functional programming and side effects. There's an article by Eric Meyer saying that most of the functional programming does not work. And his point is that if you start mixing side effects into functional programs, you've got side effects. So you can't just put a side effect in the middle of your functional program because then it's not a functional program anymore. And there's a really good, I really like this quote, which is that if you offer a lie to someone and you offer the truth and then you say actually I'm gonna compromise, I'm gonna come up with something halfway between that, you're still lying to them. Like you're not telling the truth, you're still lying to them. And in the same way, if you take a side effect and you say I'm gonna make it into a value, well no, there's still side effects, sadly. Sadly, you can't just mix them both together and hope that it all works out. I'm not saying that you can't have a project that uses side effects and uses values and have that work out well. You can do that. You just have to be really, really careful with it. You can't just mix them all together and hope that you get the benefits of functional programming because you won't. Yes. Right, yes. Yes, so the point is that side effects affect the world. What my point is here. Yeah, yeah, no, that's fine. So the way that I've positioned this is that we've got reference transparent expressions and a side effect is something that is not reference transparent. That's the definition there, yeah, yeah. So that's the classical computer science definition that a side effect is something that is not reference transparent. Now I'm not advocating that we don't affect the world. I want to write programs that affect the world. So I think the definitions there are a little bit different. So we do wanna have effects and I will get to that in a minute. Okay, so yes, we have to be careful about mixing together side effects and effects. I'm advocating for functional programming. I'm saying that functional programming has benefits but I'm not saying that you should go out there tomorrow and remove, you should stop doing Python and you should start doing Haskell because Haskell's always better, I'm not saying that. Functional programming itself has benefits and I've put forward some benefits that I see. I don't see any benefits inherent to side effects but tools do have trade off. Sometimes you have to write Python, sometimes you have to write JavaScript to get your job done. So don't mistake this as like I'm saying Haskell's always better than Python, I'm not. I'm saying that functional programming is always better than side effects as far as I've been able to come up with. Now I'm gonna give you a tool for applying functional programming when you've got a library or you've got some framework or something that demands side effects. And so if you can Google, I'm going to show one example of doing this. There's quite a few different methods you can use to be able to mix, sorry, to create a functional programming language that is able to affect the world or do effects. This method I'm using is gonna be something called the free monad. And what we do is we basically write a data structure that creates values representing the effects that you want to take onto the world. So here we want to make a program that writes to the screen and maybe reads from standard input or something like that. And if we, with a sufficient code written, you can write something that looks a lot like this which is pretty nice, which is just write to the screen, read something in, write back out to the screen. So you can write in an imperative way and you can write using, these are just values, right? These are just values that we have to find in our data structure and we can still get all the benefits of reuse. We can still get all the benefits of being able to refactor and reason equationally about this. We can figure out what the program does, but it can still change the world. It can still do effects, which is exactly what we want to do. So there's a lot of different methods you can use to manipulate existing tools and existing frameworks to be able to do the effects that you want to do, but you can still get all the benefits of functional programming. This is code that I wrote that runs on an Arduino, so this is creating a mutable variable, then we're updating the mutable variable. We still get reuse and we still get refactoring and we can still do that inside this program. So I don't see us having to give up anything. I can write code that runs on a microcontroller. So this is not having an Arduino plugged into my computer and I'm sending messages to it or anything like that. This is literally code that will compile down to a code that will run on Arduino and so it will actually blink in LED. So I'm able to write Haskell code that compiles down to a machine code that blinks in Arduino. And so I don't have to port Haskell over to Arduino or anything like that. I can still write programs and have it run on a particular architecture just by writing some tooling around it. And I still get all the benefits of functional programming and I can still affect the world and I can still write code for microcontrollers. So I don't think we have to give up anything by advocating for functional programming. We just have to carefully construct tools that allow us to achieve what we want to do. We've put a lot of effort into using side effects. I think we need to carefully consider any further cost we put into there. Any further effort we put into using side effects. We have to consider whether it's best to start writing tools that allow us to solve our problems that we can discard the tools that are demanding us to use side effects. And I think some of the tools like this do allow us to get to that direction. So we have to start considering should we continue to use side effects in our projects or should we start writing code that allow us to get all the benefits of functional programming while also working on the projects that I need to work on. I'm gonna give you a couple of tools that I've used to be able to convince people or to use functional programming at work. One of them is that I was working on a team and I was advocating for using functional programming and they wanted evidence that functional programming is going to make them achieve their goals better. Now, what I pointed out was that we already did functional programming, not everywhere, but we did functional programming. We got the length of a string or we got, we multiplied numbers together. So we were already doing functional programming to some extent in the project. Not a huge extent, but to some extent. So I shifted, I tried to shift the message from being we need to start doing functional programming always to any further use of side effects, we need to justify. And because I'm not able to justify to myself using a side effect, none of my team members were able to justify to each other to use a side effect. So I think shifting the message from being we need to do functional programming to why should we continue to do side effects is a better position to put yourself into. And so I worked on using this, using this message, I was able to convince my team that we should probably try doing functional programming in Java and only doing functional programming in Java. And we successfully did do that. We actually had a purely functional program written in Java, which I don't advocate using Java to do that. But if you are working on a project that is using Java, it is better than the alternatives. I suggest that using side effects in Java is unnecessary and that you can just get by with using values. And also I think saying that everything, absolutely everything we do is about trade-offs, is a bit of a problem. I think that that's a common trap we can fall into because so often we do deal with trade-offs, almost everything we do is about trade-offs, but I don't think everything is. I think we've critically analyzed functional programming and what it's about and what the alternatives are. We'll come up with the idea that functional programming only gives us benefits and that the alternative doesn't give us anything. So maybe we should start considering side effects to be legacy things that we don't have to deal with anymore and try and continue to push functional programming forward by using some of the tools that I just mentioned such as using free monads or wrapping APIs up as values. And I think that that is where we should be going with programming. Do I have questions? Yeah, okay. So side effect is literally, we want a definition of what a side effect is versus an effect. And so reference transparency is the thing that you can take an expression and you can replace it with the value that it evaluates to. That is reference transparency and a side effect is anything that doesn't have that property. So that's a side effect. So if you take a look at print line in JavaScript or something, for example, if you did a console.log and you had hello and you evaluated that, the value that you get from that is, I think, undefined. So you don't get the value that you get from reducing that is not what it actually does. It also does other things. It prints to the screen, for example. So because we can't replace this with undefined and get the same program, it's not reference transparent. Does that make some sense? And so an effect is something that can still change the world in some way, but it still upholds that property of if you reduce it, you get the same value. Does that make some sense? Okay. So in Haskell, it's the value printing to the screen is a value. And so it doesn't really reduce any more than that. You can't say, you can't replace it with, you can't write out the underlying value of it, but it is a value in itself. So it doesn't reduce any more. So what I could say, yes. So, well, it does mean things because it means that you lose the reference transparency property. Therefore, you lose all the benefits that I gave such as reuse and equational reasoning. You can't apply equational reasoning when you've got a side effect of like, if you replace the expression print line with undefined, you get a different program now. So if I replace this with undefined, I've got a different program. Do you like that is? So I lose all the benefits that I've put forward of reuse and refactoring and equational reasoning. Does that make some sense? Yeah, yeah, my point is that in Haskell, if we were to use put STL line, we still have reference transparency because we get all those benefits of reuse and refactoring and things like that. That still applies if these things are reference transparent, which they are in Haskell. They are not in JavaScript. Yeah, I don't know. It wasn't important. So the question is, how did a purely functional programming in Java affect performance? And for my problem, it didn't really matter. We're making like a website that had like a H2PM point or something. It didn't really matter how performant the underlying calls were. It was more like as long as it served a web page in some amount of time, it's fine. Yeah, so I don't think types are essential to functional programming. I think like this is the definition of functional programming. I think this is the only thing essential to it. I do think types help significantly in doing functional programming. So I do value types a lot. And I think that some of the same arguments I've put forward, which is that that there's no benefit inherent to side effects. That anything that you can do with side effects, you can do with functional programming. I think similar argument can be applied to dynamic types in that you can emulate like how we've emulated, we've captured everything as a data type. We've captured all our effects as data types. I think similarly we can take anything that a dynamically type program can do, like have all of its data types inside of a single type. And so I think we can get some of the same benefits of doing dynamic types, but doing it in a type language. For example, I could say this type of JSON, and JSON has numbers and it's got strings. And so I can actually say everything that Python's got, for example, I can say it's got dictionaries and it's got Booleans and things like that. So I can have all that represented as a single data type. And so then I can write functions that work all over a single data type and what have I lost from dynamic typing? I don't believe I've lost a significant amount from dynamic typing once I've created a data type that's got every possible data type in it. And I think I get some benefits from static types, from types because I can have more than one type now. I can have type of everything in my program, except also I want another data type too, actually. So I think we can take any dynamically type program embedded inside of a type language and then improve it or add to it in other ways and have separate types when we want it. But we don't have to do all that at once. We can just say this same program is embedded all in one type. I'm wondering if you, if somebody's using a DSL, say to model a real world problem. Yeah. Where it's natural for them to think of, you know, an iterative process, modifying data, leaving it for a week, coming back, doing it again. Is that not programming? Because I would have thought if you force a function model on somebody who's trying to do that, you'd actually make me harder for them to think about the problem. So I think they can still express programs like this, right? Like they can still, like this still reads as an imperative program. So I don't think, so I think they can still get all the thought process that they have by executing it like this. But then they can get benefits to the extent that they want the benefits of, hang on, I've got to create a code here. I can extract that out. Does that make some sense? Right, but I mean essentially the mental model they have of what they're doing is that they're manipulating states. Yeah, yeah. I don't think they lose that by starting to use reference transparent expressions. I believe they can still, like for example, here I've got some mutable state, which is whether an Arduino's light LED is on. And so I can update that. And this is still functional programming in a way. These are all expressions that I can. I guess I'm also in the camp that's confused about effects and side effects. Okay, okay, okay. This is, so there's quite a bit going on here, but if I wanted to say, if I wanted to replace this with a LED blinding and say this is L, I can still do that. So I can still replace everything in here with a different blinding and still get exactly the same program. Okay, so this is more of a comment from the question, really. I really like your question, is there any justification at all for side effects? Now if you were to ask, is there any justification for using mutable data structures? That the answer is, of course there is. There are algorithms that we want to implement data structures we want to use to depend on those fundamentally. That's why Haskell has references of Monads. But the way that we operate with those in Haskell is that we make use of Monads and it's visible in the API that effects are going on. So we use them in a very disciplined manner. Either you're passing in state and returning it or you have a Monad and the type checker will ensure that you don't use side effects in an undisciplined way. So one might take your question and ask them, well, is there any justification for undisciplined side effects? And that's why Haskell has unsafe performance. So I've heard a defensive side effects along the lines of sometimes you might want to use side effects in your implementation, but you might want to hide that in the API. And that's what unsafe performance lets you do. It lets you build something that looks as though it's purely functional, but which in its implementation uses side effects. And there are situations when you'd like to use that. For example, when you implement memo functions, you'd like a memoized function to behave like an ordinary function. You don't want when you use it to need to be aware of the updates that happen to the memo table. And that's a safe example, because when you use a memo function, it behaves in a referentially transparent manner. And we know that you can implement abstractions like that, that integrate well in a purely functional setting and don't cause all of the headaches that undisciplined side effects can cause, but you have to be extremely careful. You have to understand what you're doing very, very well, especially in Haskell, when you mix that with lazy evaluation, you have to, for example, understand how the compiler is going to optimize your program. And as a result, I think the number of occasions on which I've used unsafe performance justifiably in all my years of functional programming be counted certainly on the things of two hands, maybe on the fingers of one hand. So yes, sometimes you do want undisciplined side effects, but it's very, very, very rare. I'd be interested, like, you mentioned memoization. I think, like, I'll have to write that one down, because I think that is a pretty good example, but I'd be interested to see if there's like, like what other use cases you had for it, if you can remember any, that'd be awesome. Yeah, so this is like aspect-oriented programming, I think, which is great for logging and, let's see, logging. Well, undisciplined side effects are great for memoization. And reading from a config file, well. I want to do that. Yeah, I'm not sure I would use them. Matrix multiplication. No, for that, I would use, in Haskell, for that I would use references, and then there's something called run-sd, which guarantees that you use side effects internally, but they behave in a purely functional manner from outside. So that is another for discipline use of side effects. Sorry? Rapp-related underings. No, no, there are nice papers on how to do that in a disciplined way, too. So there are very, very few examples where you really need the undisciplined side effects. And that would be really too short to apply, because it's difficult to give you access for the function of the language. Yeah, if we put memo function for language, then it's hard to think of any examples at all. And your point is also that if you use a side effect, you should also make sure that it is reference-transparent in the end. Like you should give it an API that is reference-transparent, so. Absolutely, otherwise, hell is waiting for you. There you go. Thank you. I write a lot of Scala at the moment, lots of Scala. I have like probably four, five months ago I was working on a Java project, but that eventually got rewritten into Scala as well. So pretty much completely Scala is what I work in at work. I work on the identity part, so anything that handles log-ins or anything that to do with user information at all goes through our systems. So we are trying to make it so that if you use any of our hosted products, we're trying to scale it a bit more. At the moment, it's not very scalable, so we're trying to make it so that's a bit more scalable so that if you log in, you can always log in, that it never goes down, and so on. What about subtyping? Yeah, what? Hmm, I think if you apply the same thing of like, show me the benefits, I don't know. That would be a... Okay. Not on the top of my head. I'm sure I could come up with some weird thing where it's like subtyping expresses this in a type system way, like, because it's very like, subtyping is a very type theoretical thing, so I think you could actually come up with some sort of justification, say that in a type theoretical setting, subtyping expresses this property and you can't really get it from parametric polymorphism or something like that. I imagine that would be the case, but in practice, I don't care. I would not use subtyping. Yeah, yeah, yeah. So the question is, downsides of Scala, and there's a lot of them, you have to be really, really careful when you'd write Scala. If you're insisting on functional programming, like my teams do, you have to be very, very careful and it's very easy to accidentally bring in things that Scala generates for you. Scala often generates things like equality and sometimes that equality is not what you want. Actually, quite often, it's not what you want. It's quite easy to accidentally put a side effect in because you're calling some Java API or you're calling some other Scala library and it's got side effects everywhere, so it's very easy to do that, so you have to try and make sure that they're in the right type and to try and move them off into the right place. There's things like null in Scala, which is something that you don't usually want. So it can be very, very difficult to write Scala. It requires a lot of effort, but Scala also allows you to do some of the reuse things that matter to me. Like, for example, there's a traverse function here and this traverse function, I've just simplified it a bit and it works for lists and it works on IO. You can actually generalize this a lot more, so it works on a lot more things in lists and it works on a lot more things in IO. Scala allows me to do that, Java does not. So there are significant benefits to using Scala but there's also significant drawbacks with all the stuff that Scala generates and all the care that you have to take when you're trying to insist on entrepreneurship programming. So it's kind of like a double-edged thing there. It allows you to do some cool things but you have to be very, very, very careful. Scala Z is something that is very useful for doing entrepreneurship programming in Scala. We've written quite a few libraries around doing Amazon stuff at Alasian. We're very set on AWS, so we've got a lot of AWS libraries. Monocool is a very good one. So there's something called lenses and optics and Monocool is a way of going into an immutable data structure updating a little bit of it or taking an immutable data structure and seeing what part of things you are viewing and updating them and things like that. So Monocool is extremely useful. Scala Z is very useful and there's quite a few libraries around doing Amazon stuff and just doing logging and configuration and things like that. And they do do functional programming. You are able to do functional programming and people have invested time into doing functional programming on Scala and produced libraries for it. You have to be pretty careful with choosing what libraries because some of them, they look like they're functional programming but then you got to use them and they're not and you only find that out in production and it kind of sucks. So there are some good libraries but you have to be careful. Any, yep, yes. So the question is have I lost performance when I do functional programming? And on some platforms, yes, that is true. Like for writing functional programming on Scala, I have lost performance taking a side effect program and making it purely functional. I have lost performance. For most of the applications I work on, it doesn't really matter. But in the cases that it does matter, you are able to work around that. Like what John was saying was that you can use side effects but wrap it up in a pure API so that you can recover some of the performance benefits. Like if it was really important to you that this happened really fast. If it was really important to you that you printed hello and then within a nanosecond later you printed world, that was really important to you. You could write this as two side effecting functions but then wrap it up and say print hello world and you can call that. So there's tools that you can do, like you can use side effects every now and then to get performance and wrap it up in a way that it is purely functional and that you can reuse it. And so you lose the fact that you can't refactor this, you can't reuse part of this. This has to be written once and it can only be written once and you can't, it's very hard to work with it afterwards. But if you wrap it up in a function you can say I can reuse this function and anything that calls this function I can reuse that or I can refactor that. You just can't look inside of it and say I can refactor this part. So you do have some downsides to doing that but if you really need performance you can make sacrifices to get that performance and I have done things like that before. But I think that is usually a limitation of the particular machine that we're running on for the JVM. It's not very good at executing a functional code. Haskell's runtime is extremely efficient at running purely functional code and so I think the amount of sacrifice you have to make depends on the machine that we're targeting. So for the JVM, yes, I have done things like this every now and then where I've used some side effects and wrapped it up and just said this is dodgy, don't touch this, but everything else is good. Any last questions? Yeah, yes, yeah, absolutely I am. Like I always strive to use purely functional data structures, immutable data structures. There are tools in Haskell for example and in other languages where you can use, we can take an immutable data structure but then you can run a heap of updates over that immutable data structure and so you can get some performance benefits over that. There's also tools where you can have references and you can have immutable data inside of the references but then you can use those references to, like you can pass the references around and so you can have like a mutable variable but use references to update and things like that. So there are tools where if you need mutation for performance reasons or just for your application needs a single mutable variable you can pass that around and you can still get the benefits of functional programming but do mutation and but that's very rare that I have to do that, it's very rare. Usually pretty much every data structure I write is completely mutable and I'll just pass it around. Any last questions? Yeah, so the point is convenience versus discipline. So it does with the current state that we're in. This is why I'm advocating that we do functional programming because we're in a state where everything is using side effects and if we try and use reuse code that has side effects we have to be very careful and we have to start wrapping up and that's why this is impressive because we've had to take, like this is generating a C program and so we've had to create a library to generate a C program so that we compile it using GCC to run it on an Arduino and like that is really annoying, I agree. What I wanna see is us investing more time into, like if we understand that the current state is only the way it is because it's the way it is that there's nothing inherent inside effects that make this current state beneficial to us like that we're just in this state and that we should be doing functional programming because it gives us all these benefits, the current state doesn't give us any benefits and so we have to put effort into achieving the benefits that we wanna achieve and it sucks. I completely agree. What I want to see is us spending more time doing this so that in the future, if we wanna blink an LED on an Arduino, we don't have to write this library. It exists because someone's already done it because they've already recognized that functional programming has these benefits that the current state doesn't give us. So yes, I agree and I wanna fix that. Okay, I think that's all the questions, so thank you.