 So, hello. My name's Ron. And I wanted to talk about how, if you're used to working in an OOP space, you know, you're used to thinking in terms of design patterns, you know. I think most of us have a copy of the Giga 4 book on our shelf, whether we've read it or not. And we refer and talk to them a lot, you know, in interviews, if not always in our code. And, but we're at least familiar with using them and talking about them in our programs. And so I wanted to do a talk about how that those design patterns that we're familiar with, sometimes more, sometimes less, translate when put it over to the functional world, specifically closure, since that's my, currently my favorite programming language is what I work in every day. Unfortunately, it was hard for me to put this talk together actually, because I've been using closure now, like, full time for nearly two years. And I found when I opened up my Gango 4 book, started flipping through looking at the design patterns, for examples, I, it was very hard for me to understand that they were problems that needed to be solved. And let me share a quote with you that sort of expresses what I've got here. This is from Alan Perlis, who you may remember as one of the founders of the Algo language and actually the first winner of the Turing Award. He did an article, which is awesome, you guys should all read if you haven't, for ACM back in 1982, called Epigrams on Programming. We're just little one-sentence nuggets, you know, distilling his wisdom, becoming over decades working in programming. And this is one of my favorites, you know, it's better to have 100 functions operating on one data structure than to have 10 functions operate on 10 data structures. And I really didn't understand this until after using closure for so long, because in closure, like our basic types are really maps and vectors, like that's what I deal in every day. That's my functions that I write are mostly taking in maps and vectors or maybe lists of maps and doing operations on them and returning the same things. So I'm writing, you know, hundreds, thousands of functions all operating on one or two data structures. And so a lot of the patterns that you need to deal with the problem of having multiple data structures or these multiple objects, like, you know, writing an iterator for a set of objects that doesn't normally have it. Well, I don't have to do that. It's built-in to all the stuff I use. The visitor pattern of being able to, you know, do an operation for each one of a set of objects, you know, and have it, you know, work with several. Well, I don't care. I just write map over my vector and I'm done. So there's a lot of things I just don't deal with at all every day in the enclosure. But there are a few that I want to talk about, a little spoiler there, three that I want to talk about specifically where you might need them still in a functional namespace, functional language, and to show what they might look like. So specifically I want to talk about strategy, adapter, and the template method patterns. So strategy pattern. So just of this pattern, for those of you who have forgotten or never learned it, that's fine, is when you basically, you want, you have multiple methods of calculating something or doing an operation and you might want to change them out on the fly. So you're going to write several classes probably to the same interface so that whatever is calling them can just swap one out for another and not notice or care. So in a functional language, this is what something like that might look like. And if you're not familiar with reading closure code, it's usually best to start at the bottom, actually work your way up, because we have to declare things first and all that stuff. So here at the bottom we have a DefVan, we're defining a new function, ShaveYak. So we're going to ShaveYak. This is what we're going to do. And as you can imagine there might be multiple ways of shaving a yak. We might want to switch them out. So we have a yak. So the next, the little vector there is defining the inputs of this function. So we're going to take a yak, some time and some tuits, and then we're going to shave the yak. So right below that what we have is ChooseShaveTechniqueTimeTuit. So in case you're not used to reading parentheses, what this is doing is calling ChooseShaveTechniqueTimeTuit. That's a function, right, that I'm calling those inputs. And that's going to return me a function that I'm going to call on the yak to get the shaving done. Okay. Sorry. So we need to look up one more, DefVan ChooseShaveTechnique. Okay, so we're going to choose that ShaveTechnique. We're taking time into it. So how are we going to make our decision? We're going to use a structure called a cond, which is basically like a big case statement enclosure. So each of the things in the initial parentheses, like the equals zero time tuits, that's like an if check. So if this thing is true, do the thing that follows. And I've got three laid out here. The first one, if you have no time and no tuits, then return blunt force. So the function that we're going to end up calling on this shave yak is blunt force. No one's laughing at the pun. That's fine. Okay, so if we, and then the next, okay, what if that's not true? Alright, we're going to fall on to the next one. So if we have enough time, so the next check is an and on those two predicate checks, enough time tuits, enough time time, enough tuits, tuits, then we're going to hammock first, which is the best way to program, I think. So you don't make mistakes later on. So we're going to return that function. So the else is that catchall for our cond statement here. So if we have more than zero time, but not really enough and we have more than zero tuits, not really enough, we're just going to take a little off the top. And then at the top there, the three of the deaf ends just sketched out blunt force, hammock first, just a little off the top, they all just take a yak. So this is a function that's doing the work of actually shaving the yak, but it's letting this choose the strategy, so to speak. And you could use anything to switch out your strategy, right? You can have config values or anything else to do that, but it's just an example of what it should look like here. So you notice, I mean to me this is a lot simpler than the implementation I saw in Gang of Four in terms of objects and you have to have a class hierarchy and maybe you have to define an interface or a couple of interfaces and other objects keep tracking that. No, it's all functions. I'm just going to call functions. And I don't even, this actually is kind of my favorite part here because it's saying I'm calling a function that gives me a function that I call the function on here. And there's a simple way to express that. I love it. Any questions about that before I move on? I mean we're all familiar with shaving yak, so I think that's pretty clear. Okay, good. Okay, adaptive pattern, next. So this is where this comes into play really bad if you are pulling at a third party library and you've got a set of objects or an interface that it's a square peg and you've got a round hole, basically. You need to adapt the lib or the objects, whatever that you're using to what you are expecting on another end. Maybe you've got some intermediate piece of code that you need to write to get between the two. And again, in an OAP space, this is a fairly frequent problem where you're going to have, like I said, third party libraries aren't written to your specs. They're written to theirs. So you have to write some glue code to stitch them together, maybe a couple of extra objects. Again, you're going to get into class hierarchies and all that stuff. Well, in enclosure, it's a lot simpler. So we're using protocols here. And protocols are something that we use when we actually have to touch objects in closure, which I don't recommend. But when you have to do it, so we use a protocol. The protocol is basically it's like an interface, it's the equivalent to an interface in closure. So at the top there, the reason the user hyphen there is because I actually wrote this on a REPL. So you can go to a REPL right now and check this if you don't believe me. Please don't believe me. Please check it. So we have DEF protocol barking dog. So we're defining a new protocol. We're calling it barking dog. This is a barking dog. That's just a dox ring that's part of the definition of the protocol. And then we're saying, okay, so this protocol, this interface, anything that implements this interface needs to define a method bark that takes the thing and does something. You notice it's not even sketched out what will happen here because this is just the protocol definition, the interface. And again, I've got a little dox ring there. The dog should bark whatever it is. Okay, so now we've got our protocol. Now what can we do with it? Well, it turns out we can alter a fundamental building block of the closure language, the vector. I mentioned that vectors is one of those fundamental data structures that we use every day. Well, I can make them bark. So I can use extend protocol barking dog. So I'm going to extend a protocol, which protocol? Barking dog. That's what I'm going to extend. And I'm going to extend it on this class closure.leg that I persistent vector. I had to look that up. Don't worry about it. And then I give the function definition there. So if you call bark on a persistent vector, you get the thing v that's just the argument. And since it's a vector, I can call conge on it and I'm going to conge the string bark on it. And that's what I'm going to do. And so the nil there is just the repl acknowledging, okay, I got it. But what you gave me didn't really do anything. So I didn't operate on anything. So you just get a nil back. That's fine. Alright, so let's define a new vector. So def of vector and it's just a list of integers there. One, two, three, four. And the repl gives back the hash quote there saying, okay, in the username space, you define a new thing called a vector. Great. And now let's call bark on it. So we call bark on a vector and then we get that same list of integers but now it called the our bark method that we defined and conge the string bark on to the end of it. So now it's bark. So just with those few lines, I've completely changed in this way, you know, extended the behavior of a fundamental class here. So if you can imagine, if I can do that to this fundamental piece of the closure language, I can do it to any third party object that I get or any other class I get in. I can make it do exactly what I want. I don't have to mess around with an adapter class. I don't have to write a new thing. I can say I wanted to do this, make it do that. That's how it's going to do it and then it does it. Very powerful. Any questions about barking? Template method. Okay, so this is something you'll use when maybe a class that's doing an operation, maybe something that's part of that strategy hierarchy of objects you wrote earlier, yuck, needs to I've forgotten the word offset. It basically wants to leave off some of the calculations to some other subclass that maybe you might input to it or maybe it finds on its own. Maybe it's defined in a parent class somewhere over here that you have to go with the, yeah, whatever. But basically part of the calculation that you're doing is being handled by some other subclass instead of the class itself. So enclosure, again, it's much, much easier. We basically use a higher order function. So since enclosure, like we saw in the strategy pattern where we were calling a function that gave us a function, we can write functions that take functions as arguments and then they call those functions and things get done. So in this case you actually have to ignore my bottom to top and actually go top to bottom. So we start with defining up-to-get account status. So we're writing either a server-side app or maybe it's a web app. We're updating the status of an account status of a user. And that function is going to take four parameters. It's going to take an account ID, a get fun, a get function, a status that we're updating it to, and then the save function that we want to call. So the first thing we do is do a let us define a function that we're updating. And that's just an easy way to define of our inside function. So it's available there. It's just for readability. And so what we do is we define account. So we're going to say account inside the rest of the body of this function. It is going to be whatever we get when we call the get fun on that account ID. So we got a function from somebody else. We don't know what it was. We don't care. We're just going to call it. And we're going to expect something back. Whatever it gives us, that's the account. That's what we're going to work with. Okay. It's probably going to give us a map because this is closure. We're probably sending in an integer or maybe a UUID if we're fancy for the account ID and then getting a map back. Okay, so then we got the account. So then we do a when check. That says when not equal status account. So again, I'm assuming in this case the account coming back as a map. And so the status keyword there by I can actually, in closure, I can use the keyword as a function to call it on the map and it gives me the value. So what this is saying is take the status, the current status of the account, give me that out of that map that I got back from the get fun. And check to see if it's equal to the status that was passed into this function. So presumably the new status that someone wants to update it to, we want to see if those two things are equal. If they're not equal, if the new status is different, that's the only time I want to do anything but this function isn't responsible for knowing how to do that. It got passed into save fun. So it's going to call that save function after associating that new status onto the account. So the source there is to say take the account map and associate with it a new value, this status with the keyword status. So basically what this will do is give you a new map that overrides that old status value with the new status and then sends that into the save fun. And then later on we can define, so with this function written we can define as many get and save funds as we want. We can get a define a get one that gets it from a database or gets it from the atomic. It gets it from some HTTP service, maybe it's calling a REST API to get it and we can do the same thing with the save. And this function update account status doesn't ever have to know over a care where it's getting it to date or where it's going to or how it's doing it. All it cares about is if I call the get fun on account ID do I get a map and if I call the save fun does it do what I want it to do. That's it. Alright, and that's all I have. Are there any other questions? This was a really quick talk. Okay, thanks for coming.