YTread Logo
YTread Logo

The Functional Programmer's Toolkit - Scott Wlaschin

Jun 02, 2021
Well, welcome, welcome to the

functional

programming

toolkit

. This is a talk for beginner to intermediate level people interested in

functional

programming and you've already done a little bit, but there are a lot of things you don't understand, like monads for example, or functors and everything. this jargon, so the goal of this talk is to really go over that jargon and hopefully explain it to you in a way that demystifies it, so it's helpful if you've done a bit of functional programming before, but even if you have . t I think you can probably understand what I'm talking about because I use a lot of small images so my name is Scott volution and I have a F Sharp website for fun and profit.
the functional programmer s toolkit   scott wlaschin
The code examples in this talk will be in F sharp, but there is not much code in this token, so don't worry if you don't understand the code, so the main question starts with why functional

programmer

s use so many strange words and It's very scary. for most people there are words like functor applicative cat morphism that takes monoid and monad, the scariest word of all and I think the problem is that these words sound a little scary, but they are actually not scary concepts if you understood them. which were, I mean, you could be like Homer and I don't think I can understand any of this.
the functional programmer s toolkit   scott wlaschin

More Interesting Facts About,

the functional programmer s toolkit scott wlaschin...

It's too complicated, but it's not. I don't think it's scary. I think it's unknown, so if you knew what the words meant or at least demystified it a little. You could be like Homer here and you could say, "Okay, you're mappable." If I call it a map, I could understand it, or folding or aggregator of any words, it doesn't really matter what the words are, but these words don't. It doesn't sound as scary as the math kind of words, so that's really the goal of this talk is to demystify. You may not know what they mean.
the functional programmer s toolkit   scott wlaschin
They're not familiar yet, but they're not scary. What's really scary is object-oriented programming. just because you're used to it you don't think it's scary, but if I'm a new object-oriented program, there are all these words like hair polymorphism and generics and covariants and solid and solid are five other things and there are IOC interviews, di and ABC , you know, you just don't realize how scary it is if you don't have experience, there were people, so never say that functional programming is a scale of words because, oh, it's just as bad as their jargon. we were just used to it, so there are four words in particular that I want to talk about in this talk and, as I say, these are mathematical words and you might think that this is kind of like an abstract academic theoretical thing, but it actually turns out to notice that these are tools. very useful and again, if you demystify them, hopefully you will see at the end of this talk that they are actually useful tools, so there is something called what I call a functional toolbox and it is analogous to a real toolbox and a second one in a real toolbox, you have all these different tools that you know and each tool does a particular thing well and you know, if you are an experienced person, you know which tool to use for what thing and a functional

programmer

has a lot of tools for you. know map return link whatever all these tools have names and if you are an experienced person you will know which tool to use in each situation and basically it is eleven types of important tools that you should know because you may know another ten. which are not that important, but if you know how to use these eleven tools, you can do practically anything in the face of programming, so this is a toolbox for problem solving, they are not academic toolboxes to really get your hands dirty .
the functional programmer s toolkit   scott wlaschin
What are the types of problems that functional programs need to solve well? The first problem they need to solve is composition, because everything in functional programming is composition, it's the fundamental principle and I'll talk in a second about how things are combined. adding things, that's a common problem in both oh and functional, how do you iterate through things, how do you work with effects now, this is a more functional type of programming, they like a plugin, let's talk about effects everything time and what we mean by effects and I'll explain what I mean by effects but sometimes it's a little bit tricky to work with these effects so you have to mix things that are effects and non-effects where you may have to chain them together or that you need to work in parallel.
There are all the different things that you need to work with when you have effects and there are a lot of non-overlapping tools, so these are the type of words that you will see used a lot in composition to compose keywords. Iteration is generally not called folding. functional people combine and reduce Mack and the return sign, which is also called flat map application and reverse zip sequence, these are the types of function names or tool names that you use a lot if you are doing functional programming and of course , if you get into the jargon, these things actually have names, so the combination is usually called amyloid when you're working with different types of effects.
You use a functor if you want to chain effects like a monad, if you want to work in parallel like an app, so don't do it. worry about this, I hope to explain to you at the end of the talk all these things, I hope they make sense and even if they don't make sense, I lived a little less mysterious, that's the point, so this talk is good, it's going to be one of those things like those tour buses where you go around the city and you'd like to stop for a minute at each famous place, you don't really get a chance to look around, but at least you can see the sights, so that's what this is. like a whirlwind tour of the sites, you can't possibly understand everything you know in one talk, but hopefully, if you demystify and walk away, you'll know you can say "Oh, I can, and at least I can't be afraid.
I can." get in". and I will learn more about this later when I have a chance, so start with some principles of static type functional programming for people who are newbies, the functions of things come first and fortunately we also attract analogies and composition is used everywhere. so there is no inheritance, there is nothing else, everything is composition and if you know how to use Lego, you know how to do composition because this is exactly the same thing, so let's look at functions as things, so a function is a small thing. I like to use the railway.
Follow the analogy in this little tunnel transformation of the tunnel something goes in if something comes out in this case an apple goes and becomes a banana so this is what we call apple - banana faction Mayan Trot transforms samples into bananas and the functions are things standalone, they're not attached to any class because they're things that you can use just like you could use an integer or a string or something like that, you can pass them as parameters, you can put them in lists that you know. it can do all kinds of things because they are things like everything else and this independent thing is actually very important because independent is another word for reusable if it is on its own it can be reused in any context if it is part of a class it is really difficult to extract it from that class and we use it in a different context, but all the functions in front of the program are independent functions, so here is an example of a function that has a normal input but has an output that is a function here is an example of a function which has a function as input and a normal output here is a function with a normal input and a normal output but it has this additional function which can be any type of parameterization and this would be called strategy pattern in our, so this is that, that's really all you need to know about programming right there, if you understand that you understand everything you can see, it can get really complex, it's a very simple base, but you can have functions that return. other functions that generate other functions that use premises other functions can get very complicated, but the fundamental principles are basically what I said in the last few minutes and most of the tools in the functional toolbox that I'm going to talk about are our transformers of functions, they take functions and spit out other functions, so having functions go in and out, that's a very common thing in functional programming, so the next principle that's really important is composition, so I'll talk about Lego for a while. moment. second, because everyone understands how Lego works, hopefully, and Lego actually has a kind of right philosophy, which is that everything is designed to be connected to everything else, you don't have LEGO pieces that don't fit with other LEGO pieces. and if you connect By putting your LEGO pieces together you get another piece that can still connect to other pieces, but you've never done that, you never run into a wall where Owen has more LEGO pieces because I've run out of points or something so, you know, and they're reusable. so here's some Lego.
Every Lego piece has little dots so they are designed to connect and when you start putting them together you know no, you can keep adding and adding pieces, you know they are designed to be that way. that you never reach a limit, you can add two pieces and that makes another piece have more pieces, you don't need a special adapter, you don't say well, this piece will not fit with this piece because then I need a special type of adapter pattern to make that two Lego pieces fit together, no, you don't have an adapter pattern in Lego, right, they literally connect directly to each other and you can keep adding, adding, adding, and you can do really big things with Lego. add all the little parts and here's the thing about reuse right?
You can make something and then you can take it apart and make something else. The pieces themselves have no links, literally no links if they had links. connected will get tangled, the springs will get tangled and this is one of the goals of functional programming is that all the functions that you created are unlinked and because they are reusable, they are not attached to a particular context, they are not It's like that, you don't have to remove them to reuse them and they are literally designed to be reusable from the start, so you can make really big things from small things in Lego, that's what I would like.
To call the power of composition, now let's look at the functional programming philosophy, which is very similar to the Lego philosophy and this is because the automatic rental static type functional programming, the dynamic type generic function program is similar, but there is a bit of difference, so at the front of the program, you try to design functions that do one thing well, sound principles also apply to functional programming, but functions can be reused, so you design your functions so that are reusable and you design them to work together and hope that the output error function can be the input to some other function, you know you design them so that you can be working with parts that you don't even know about yet and, by the way, if you are familiar with UNIX philosophy, this is exactly the same as eunuchs, yes.
Learn the philosophy of utility, wait, and actually work with the Li guy. Functional programming. We use types to ensure that inputs match outputs. We make sure you can't accidentally put the wrong kind of things together, so this is the functional tool that designs things that do. One thing we'll have in the

toolkit

is a very generic set of functions that you use, you know, since you're creating books, so let's look at function composition. Here is an apple-banana function and here is a banana-cherry function and how is it done? glue them together how you compose them how you make them how you connect them well it's really obvious if they're good we keep track you just literally glue the two pieces together and you get any function and the nice thing about this is that you can I'm not saying this was created from more functions small, so now you have another function that you can then use to create a larger function and so on, and also the good thing is that the banana has disappeared, where did the banana go? now you have some hidden data, you have some abstraction, the fact that the thing was built from small pieces that use something that the bigger function can hide all of that so you know you have this kind of nice API and you can build really big things. things that just use functions without any kind of objects, so if you think about a web, a website, a website is a function, an HTTP request comes in and it spits out a HD that listens once everything is one giant function, it's with an input and output and when you do a functional function layout inside your main web function you have all these little functions that do everything it seems and they are all connected to each other by pipes, you don't need classes, you can even seriously create all the correct certificate applications using purely functions and if you want to call these microservices, be my guest, although themicroservices are very similar that's not an example of a parallel composition so I have a whole talk about this if you're interested on my website okay so let's look at tool number one tool number one is hand eight it's okay, or the number one tool that is not the number one tool, is the first tool that I will talk about and there will be some math in here, so I hope this I won't discourage you, okay, if you are afraid of math, then let's see , this is the first part of mathematics and this is the second part of mathematics and this is the third part of mathematics, so this is all the mathematics that we will use, so if you can understand this, you would say that the interesting thing is that mathematicians They kind of like programmers and they always like to do abstract things, they're always looking for patterns so a mathematician would look at this and say mom, well, that's interesting, I can see if I can see some patterns here and let's look at this.
We have some things and we have some way of combining them and the result is another of the same type of things, you add two integers and you get another integer. I wonder if that works or something else, oh yes it works or multiplication too if I add if I multiply two things I would get something else, other integers. Back, what else does it work for? Well, it works with chains. If I have two chains and I can chain them, I get another chain and if I have two lists and I can count Nathan, I get another list, so this is pretty common.
The pattern happens everywhere, well, the interesting thing about this scenario is that when you add two things, in this case you have to enter, you get another integer, you can continue to be able to add 3 to that and that gives me back another integer , TRUE? And then I can add 4 to that so I can keep adding and adding and adding like Lego, so the Lego analogy is pretty good. What we have is that we start with a pairwise operation like addition or multiplication or you know, adding these things. and now we have an operation that works on lists, we can extend it infinitely by adding more things without running out.
No way, what about the next one if you know that 1 plus 2 plus 3 is the same as 1 plus 2 plus 3? ok, what that means is that the order of combining things doesn't matter if you combine 2 plus 3 first or you can find 1 plus 2 first, the difference, so you could do one plus two and then you could add three and then you'll get at four or you could do one plus 2 here and the fridge was full here and then add them later it doesn't really matter which way you do it you always get the same answer so that's good now it's not always true. subtraction doesn't work with order it does matter for subtraction subtraction doesn't fit this pattern okay, what's up with this zero? okay, this is what this zero means, so a mathematician will say well, this is very interesting, we have this very special type of something that when you use it to combine you know that you can combine it with this other thing, you always get back the original like the zero leaves that alone, it kind of doesn't do anything, it's kind of a null pattern and it becomes Note that zero is a pretty common thing, so when you multiply it there's a special thing that when you multiply it you get the same thing and that would be number one and if you have strings there is a special thing that when you add it to any other string you get the same string back and that is the empty string and so on, the empty list there is a conceptual zero zero for all this kind of stuff , is very, very common, so here is the pattern we have recognized.
We have a lot of things, we have some way of combining them two by two and that is the first rule we have, the closure rule, that when you combine them you get another thing of the same type and the second rule is associativity, which is when you combine them more than one thing, it doesn't really matter what order you combine them in and the third thing is that there is a zero or an identity element that when you combine it with the thing you get the same thing back, so it's like it doesn't do anything, so these are pretty obvious patterns if you start to think about it and mathematicians have a word for this, they call it monkey eight, so here's math jargon for something that if you just look at it from pattern analysis, it's like , it's a pretty common pattern I read, I recognize, so let's stop with the jargon.
Homer says no more jargon, don't talk about monoids, why is why these patents are being analyzed. Why is it useful? What are you like as a programmer? If you think about how it will affect the closure, you can combine two things and get another, which means that all the powers of attorney operations can become things that work on lists that parents abuse at the start. with an even and still out of the list and this is normally called reduce so if you have 1 + 2 + 3 + 4 you have the even plus operation and you can take a list of integers 1 2 3 4 and reduce it using + so the only thing the reduce operation does is basically take the list of elements and place that pairwise operation between each one if you have a multiplication that reduces a very common practice, one of the things that is enough in some tools if you have a multiplication, that's the pairwise operation, then we can take a list of numbers and we can reduce it using multiplication.
Okay, and we can take a list of strings. Do the same thing instead of adding them in pairs. We can collapse the entire list of strings into a single string using the string concatenation operator etc. for lists, so this is a really common pattern now associativity, the benefit of associativity, there's also some divide and conquer stuff, an incremental buildup of parallelization. I'll talk about parallelization right now, so parallelization means you can take a bunch of stuff and you can spread them across multiple CPUs on one of my machines or whatever, so let's say we have to add 1 and 2, 3 and 4, we could paralyze it and say we will do 1 + 2 on this. machine and we will do 3 + 4 this machine and then we will take the results or add them together.
You wouldn't do that with 4 numbers, it's ridiculous, but if you have a million or 10 million things to do and these pairwise operations are quite complicated, then this is great, so if you have a monoid you can parallelize it instantly. Now it turns out that normally most of us don't have to worry about parallelization, but another really useful thing is incremental accumulation. which is much more common, so let's say EO's boss asks you to add 1 + 2 3 because your boss isn't good at it and she's fine and then the next day your boss says I've actually changed my mind , You can add? up one plus two plus D that's it for today and then you say well I have to start all over again, you know, I just had it and now I have to go back to the beginning on that one, two and four, you know.
Of course, you can't keep the number you calculated yesterday and just add 4 to it. You don't have to add everything from the beginning because of this associativity. I have already calculated 1 + 2 + 3, which is 6 and all I have to do is add 4 to it so I don't have to start from scratch. I can accumulate incrementally, so every time I have a monoid I can do it incrementally on the late Hulme data and eventually we have all these problems that we run into. How do I reduce when the list is empty? How do I do a divide and conquer when one of the steps is empty?
How do I do an incremental rollup when I don't have any initial data and that's what the identity element is really good for? the initial value for empty data or missing data, then you have these fake things and you can do anything once you see this pattern you start seeing it everywhere and you can have a missing 0, you can have patterns where there is no zero and the mathematicians they got that semigroup which is even more obscure, so let's look at a real example, let's say we have to do some aggregation, let's say we have a bunch of order lines and we have to add them up and find the total, now we could write a loop and write A specialized piece of code dried them up.
The problem with that again is that if I have three or four things again it's not fun, but if I have a million things, then tomorrow I'll have a million. First thing I have to start. I have to execute. the whole loop again, you know, so let's use the monoid idea because that gives us the best bullet point about all the possibilities, so instead of trying to write a loop, what I'm going to do is say, well, you know, integers are AIDS floating mono amides. any combination of a mind like another money so the whole line is one moment and all I have to do is write a pair combiner where I just add the two pieces and return the new one so I have a wire pair combiner Which is usually pretty simple. write and then once I have the pairwise combinator I can run it on the entire list, just reduce the entire list using the pairwise combinator, so voila, there really is a pattern, it would be helpful not to say it if I have another one.
The order line arrives tomorrow. I don't have to count the entire sample total. I can simply add this extra using the principle of incremental accumulation. Now in many situations you don't have mono, so, for example, I have a lot. of customers and I want to know how they know, let's say I track how many times they visit my website, how much money they spend or whatever. I would like to add all that up but I can't because clients don't hand eights, however I could create a special kind of class or a structure called client statistics that are just integers and stuff and that would be a monkey because they are all kinds of numbers, so what you normally do is you take something that is not a one night and you turn it into something that is a hand and once you have it as a monoid, you can reduce it so well, turn something that is not into a model in terms of honor, which is Mac and then applaud everything in a reduction of single values ​​and you've probably heard of MapReduce, but MapReduce removes them, that's why it's called MapReduce, it's something to do wet, so here's a nice gift that I saw a long time ago, how was it? make me a sandwich, so how do you make pizza?
You just know it does parallel calculations and you start with, let's say, you start with some bread and some lettuce and whatever and onion or whatever, you can't just mash them up and make a sandwich okay, they're not, they're not. composable, they are not mono, but if I cut the bread and I cut the onion, I cut the lettuce, the slices can be composed into sandwiches so you know you can then reduce the cuts of interest intercessor session of sandwiches, so this is mapping followed by reduction as a way of knowing how to make sandwiches, so it's fun.
Here's the problem with monoids, once you recognize this pattern you start seeing everywhere, for example if you do devops or something and you need to keep track of sixes, there is a little rule that says to use counters instead of rates and if you say if you like mono age, you say just make sure you measure the moloids because you can do incremental updates and you can handle the misses. data Renaissance art, and indeed many design patterns are actually mono, is behind the scenes. Marc Seaman just wrote a blog post the other day about things like the composite pattern is mono and the null object the hand is mono composing commands together to make a new command is mono and if you like the DVD in the DVD book , talks about going out of business, that's the mod, so you really start, you know it really hurts, now you say well, why use the word monoid? a slang, your word, but like any piece of slang, once you know what it means, it's a shortcut to explaining something quite complicated, so if I tell someone else and I tell them this is a monoid and they know what what that means, assuming they know what that means. it means they'll know instantly that they can cripple it, but they can do incremental things that a zero element has.
You know all this kind of stuff, so it's a great shortcut to explain that you know a company and that they also know the surveillance patterns they should use. how to work with them immediately what about a functional composition? It's a monoid, so here's an app you know, whose are two functions and we compose them together and have Apple carry the function. It's not the same kind of thing as Apple. one thing is an apple-banana function the other is an apple-cherry function, so when composing functions there is not really a male; unfortunately, but if we have functions that convert apples to apples and we combine them, we get another function that converts apples to apples. and that's a monoid because they're exactly the input functions and the output function is the same kind of thing, so if you're working with functions that convert integers to integers or strings to strings, you can do that kind of thing. incrementally.
You can do them, you know, all those kinds of things because they have wrong weights, right, so that's all you know about mermaids, a set of values, a combination function and it also has those words, even if this is what I'm saying, so you could do it. I don't recognize it because the actual word you used with a permanent function could be anything, sowhich for strings or lists is not the golf jack for an integer Zitz called more in Haskell is the angle bracket sometimes and sometimes you see a platinum, you are more. all kinds of symbols and weird stuff, but it's the same concepts everywhere and this combination, the combinator has to be closed associative and zero, so here you can use it to reduce a list, you can use it to do parallel calculations, you can use it to do incremental calculations. calculations all these things, so there you have it, that's a monoid, so that's tool number one.
Hopefully my nodes aren't so scary now, okay, they're demystified a bit. I hope now we're going to be even scarier, but let's talk about effects. What is an effect? Functional programmers talk about effects all the time, so the effect is really just a generic type like a list, a list of something, or it could be a type with some extra data in it, like an option type or a type of result, it could be a type that changes the state of the world like in a sink or interacts with the world you know, with random number generators or it could transport the state like a type of car state. or type can be all kinds of state it's actually a little vague one effect is it could really be all kinds of things it's basically you know it's just a generic type person you know the generic type is it's a normal type with some extra things Well, I'm going to focus on three types in this talk to use as examples: enumerate an option and a receiver, so I hope everyone knows what list is the option type if you're using Java, this no, no, there are optional elements integrated.
Hopefully most people are familiar with the optional type of some type and the asynchronous type, you can think of it as the task type, it's something similar, f-sharp uses a sink and then C shop uses tasks, like this That's all this effects stuff. there is a normal world and an effects world okay so in the normal world you have strings and you have integers and you have billions anyway the functions of converting strings in the case of strings you have the function of converting them to bills , so this is like your normal world of the Normal Everyday Objects now, what's interesting is for each type of effect, like options, unless normally there is a parallel world, it's like a mirror world and everything in this world is options, for example, so instead of having strings, you have optional strings instead of in your options and The optional books and every function that converts a string instant into an optional world, that function converts innocent optional strings optional or becomes optional in sins, they are optional tickets, so it's like a parallel universe and the same with lists of worlds in list worlds, everything is lists. of things there's a list of strings and lists of events and these billions and all the functions convert lists into lists, you know, so this is a conscious analogy for these worlds and it's going to be a pretty important concept that we'll talk about. there are many worlds and async is another world, all you can see how it goes well, you can see the pattern here and there is an effect called generic, no matter what effect it is, there is some kind of e.
I'm going to call Eve generic. effect and there are generic effect types and a generic effect works well so that's my effects world so that's all you need to know about effects just remember that every time you hear someone talk about effects you probably you can replace it with an option, a list or a receiver. or whatever, here is our first problem: how we work with these effects, sometimes we need to do things in the effects world and how we do it and I will give you some concrete examples, so let's say here is the normal world. values ​​and here is the options world and sometimes we have a function that takes us from the normal world to the optional world and then we need to work with the data in the option so we basically extract that data and do something with it and then somehow it comes back to the option world optional again and then we extract the data again and it returns to the optional world.
This back and forth between worlds is a very common pattern, it's actually very bad, so don't do all this. Correct functional progress I would call this a kind of design smell or code smell, so you know how you could solve that. What you really want to do is when you enter the world of effects, whatever that is, you want to stay there. You want us to continue working there and only go down at the end if necessary. I mean a good example in c-sharp is the task or async/await once you've done something asynchronous or you become your basically the things you leave you have to do, everything else has to work in that world in the world asynchronous or in the world of tasks and you only get to the top of your program, you don't know, it's bad bad practice that you like to wait for a task to finish and then start another task than to wait on the side, what you want to do it's lifting everything up into this asynchronous world and working there and then at the end of your program, which everyone can drop into or whatever. that's where it really comes down to the async or the task so that's the right way to do it, let's say we have an ad to run a very important function and if we do something normal like 1 we get the response 43 if we do that. not on anything else which is a world of options like someone, it doesn't work, it only works on normal things, it doesn't work on options, so this ad 42 feature is useless, by the way, it's a dance, so we say, well , let's write our own custom ad 42 - option function, so we say well, if the option is something, if it's about that, then we're going to run the ad 42 and then we'll have to put it back into the options world again and if it was never something. then we break up, we don't have to do anything, so we unwrap it, we do what we have to do and then we break up again and that's like I say, it's a bad way to do it, you go down, you're doing something, you come back up , this is an old man, so what you want to do is somehow be able to work with this ad 42 function in the effects world in the optional world, so we want to stay up there, so how do we do?
How do we make an ad 42 work up there without having to use the only special thermal every time? And that's what we mapped, so this map is a function transformer. that moves functions from one world to another Wells, so if we have a function down here that converts T's to use, if we make an option map, it converts cheese options to use options, that's the option that does it in our code instead of, you know, with our normal function we can say options map around 42 and that gives us our option and 42, so now we have plugin 42 that now works in the options world and we can run it right away , so now we have a function in the option. where we didn't have to write any special code to wrap it and unwrap it again, it just happens for free and we usually don't write special code, we don't give it a special name, we align it digitally like this, the option outside of this and we can apply it to the other.
The same is true of this world. Let's say we want to add 42 to each integer for each item in the list so you know that for each item in the list we had 42 and then we put it back. in the list again and return the new list let's say but we are doing this when you are doing an iteration you are basically unwrapping things out of the list you are taking out each element one at a time applying the thing and then putting them back into a list again, so again this has been a dependent, you don't want to go down, do the same thing and come back up, don't do that again.
We can use list map instead, so it requires a normal function. in a normal world, you run the list map and it gives you a function in the list world, so if I wanted to find the add 42 for each function, all I have to say is the list map of the add 42 function, now I have a function that works on For this I didn't have to write any special code, so that's great, you can see that this map is actually very useful and people say, well, I can always write my own loops. Why is this easier than writing my own loops and the The answer is, again, if once you know what this map does, first of all, it's easy to use because you don't have to write any code.
Second, it's also easier for someone else to understand, assuming they understand how it works. they can look at your code and know exactly what's going on sometimes if you look at a complicated loop you're trying to figure out what's really going on in this loop you know because it's not the logic of the loop that's getting in the way of the loop. what you're really trying to do if you use things like this map the loop logic, it's a little bit hidden so you can really focus on what's actually being transformed, what's really happening in this case, it's really obvious that we're adding 42 to each other. element now if I had a main loop and there were like 42 in there it would take me some time to figure it out so I think this is better once you understand what this map does it's actually easier and of course asynchronous, the same as us. has a normal function and we can map it to the world on resync and that way we can chain asynchronous functions together so that most generic types have a map, there is no single zone, use them and if it is its own generic type, so Let's publish to a library, create your own map and then everyone else will be able to use it and of course now we have the Mac slang version so the slang version is a funk guitar so a function It is a type of effect that is again an option. not a single list or one or whatever, apart from some kind of map function that works with it, is designed specifically so that you know the definition, the map implementation for options is different from the map implementation for lists, which It's different from the map implementation for tasks or whatever, but the concept is the same, so I can use it in a list map or whatever once I know what this is, I know exactly how to use it, the map function has all sorts of different names, sometimes it's called selections sometimes it's called elevations sometimes it's called map f, so you need to have a sensible implementation.
It turns out that there are a bunch of things called functor laws, which are really just a fancy name for some rules that implementations should have to make sure they work sensibly. like you think you shouldn't do anything too stupid to them and function laws are basically a way to make sure your implementation makes sense, so that's number two, what about number three? Well, this one is really simple, this is just sometimes, you know. we just talked about moving functions from one world to another, let's talk about moving individual values ​​like integers or strings and that's called spinning, so here's a normal values ​​word and we want to convert it to an optional int, we just use return right here . and here is a normal value and we convert it to an optional int or it is missing something similar with lists, if we are a single integer and we want to make a list from it, we use the list return and that generates a list of events, so here you have 42 and we make a list from that, you know, in this case it's very easy, it's just tonight a single item on our lists, so again, it's not normally called return.
I mean the actual way of doing these things, the name is all kinds, it's all different. in a different environment, the concept is that you are just moving things from one world to another, normal world value, value in this world, so be patient, you will probably think that all these things are really useful and at the end of the talk In fact, I'm going to show you how to assemble everything into a real piece of code using all the different tools together and you just think about how you know how these tools can work together to build a complex program.
This is the most important tool. probably in the function problems which is link and used for world crossing functions. I think it's a cross-world function. Well, I know all these types of concepts are introduced, but they're not particularly difficult to understand. Don't think it's something different that you're not used to if you know a functional program, so here you have a function called range and you give it a maximum number and it will give you a list of all the numbers up to that number, so if you give it a you know the maximum of 100, it will give you all the numbers from 1 to 100.
Okay, it's pretty simple now, if you look at what it does, you pass an int and you get a correct list of events so you can have a value in the world normal and the output is a list of values ​​in the world, this is actually very common, so if you think about it like this, you start with an int down here and you end up with the list of endpoints here. I mean this. is the range now here is another more complicated example let's say you are getting a customer from a database are you passing the customer ID?
If the client is found, then you can say yes,I found some customer information and I'm going to return it to you. If I don't find the client, I say okay, I won't give you anything back and again, if you look at the inputs and outputs of the function that says, will you give me a client ID, which is a normal thing? We'll give you an optional piece of information from the client so that the input is in the normal world, but the output is an optional world, so again, this is a world crossing function that starts at the bottom and ends at the top.
These functions are actually very common. in functional programming, the cases where the client works, this is a really, very, very common problem and how do you change these things together, so here is some code, it's a bit silly, in this example you have to do something and you return. an If it's anything, let me. Go ahead and then I do something with that and that maybe that gives me another something and I have to say I have to check that too and maybe only when it's valid can I do the next thing and I have to check that too and only when it's rylynn can I get the next and so on.
Now you can replace this with a null check. You've probably seen the same type of code if not. Now do the following. If not, no. I will do the following. know if that's not null do the following so this is just the option version exactly the same code and it's this horrible thing that you get this huge thing, you have all these nested checks and they add up if you get more indentation in your code and this it's usually called the Doom pyramid because you're known as you if you have like three checks it's already pretty until you have 20 checks you'll be, you know, it's just ridiculous, you wouldn't want to, this is horrible code, no one wants to code like that and you see this all the time in other situations, let's say we are doing. with the guitar and we perform a task and then when the task finishes we get the rally that generates output and we execute the next task with that and then when that task finishes we do the next thing and when it finishes we do the next thing.
So whether it's tasks, promises, or futures, whatever you want to call them, you see this pattern frequently, and again, it's a pyramid of doom. You can have a world crossing function. You always have to verify, you always have to deconstruct it. these two nested callbacks in this case end up with this pyramid, so this is ugly no matter what it is, so let's see if we can solve this problem, let's fix it. Here is a pattern we can exploit. Maybe see if it's something to do. something if it's something do something if it's something do something this is the tray so let's change that intraductal auxiliary function well we're going to say if it's something do something and if it's not then we don't do anything that's the pattern so what exactly do we do ?
We don't know what we're going to do with that thing, so we're going to parameterize it. Let's say we'll pass in a function parameter and the function parameter will do what we want to do. We don't have to do it. Worry about what exactly it is, so we could create a little piece of code like this if something works and if so, if the input is optional, then we run this with a helper function and if it doesn't, this parameter is missing. this function parameter is the things you want to do as a next step if it's valid so once we have this little helper function we can rewrite our original code to look like this do something and if it's something do the following and if this if that is not something, then do the following and in fact something does the following and what this little helper function does is basically clean up all of those nested things.
Now we have a nice linear vertical alignment, no bleed. So this is a really, really nice way to organize your code. How am I going to use the railroad analogy so that with options you can think that there is one input and there are two types of two possible outputs: there is something or there is nothing. and if it's something we want to do, the next thing in the chain and if it's nothing we want to overlook, then if you really had little bits of rail, like whether you were playing with Brio or not, we wouldn't, well, we have somehow, how would you connect these things?
Well, you couldn't connect them like that, but you could connect them like this, so this is, you know, this is very close to what we want, but if we can get something like this, then I've connected more together nicely, so that's our aim. Now here is the problem, if we have one track functions with one input and one output, they are easy to compose, we just connect the inputs and outputs, if we have to track functions with two inputs and two outputs, they are also easy to compose, just we want them in the obvious way, but what we have is an input track and an output track, and those things can't be composed, they just don't fit together correctly, so how can we combine them? mismatched functions like this and the answer is link link everything functional programmers love the word link so here we are here is our problem again we have these kind of points that don't make up if we were to trace the functions that they would compose.
Okay, so how do we get from before to after? Well, we have a function adapter, a function transformer and if you think about wooden train tracks, you can get these kind of little wooden adapter blocks that stick together, you know, so you know. put this in this adapter block, put your dot function and it reduces as a two track function and that is in RSA, it is a type of function that transforms functions as input and functions as output and the implementation is a great SMO, since you know it's actually it's a very simple print, it's like literally four lines of code, it's more complicated to explain and then show the code, so here's the code, enter an input and if it's anything, we do the following function , we do what you pass and if it's nothing, we don't know anything, then that's actually the full bind implementation for these kind of point functions, so if we use it for training options, this is what it looks like before If we use a string to do, you know, we write.
By the way, this in a hook helper function is exactly so small if something works that it's exactly the same, so if something does actually buy the same thing again, it has this parameter that is passed as the next element in the chain and then our code then becomes linear, so now we use bind as the word here, so there are no pyramids and it is linear and clean, and if we do the same with tasks, when a task is completed, we do the following in the task and if it doesn't complete whatever, we don't do the next, same kind of pattern, we write a little task link, insert, okay, so this is the ugly version with the pyramids of doom and we add a task link which again is no it's a different implementation but it has the same concept it's like chaining tasks when we get the result we want to run a function on it okay there's a little bit of what is our next parameterized function and then once that we have something like this, we can, wow, then we can connect everything.
Tasks together in a linear way we can start a task and then we can link it to the next task and we can link it to the next task or buy it to the next task, so this is like I said my as a general concept, it's not just specifically for options in this type of tarsus, a concept that you can apply to almost anything with any type of effect and let's see one more example which is error handling, so here is an example of a function that does not handle limited receives a request, validates the requests, you can canonicalize the email, maybe make sure it's lowercase, you can update the database, you can send an email to the client or something you know, but this is pretty, you know it's just five lines of code is Pretty simple, but here's the problem: errors happen, like what happens if the request is invalid, what happens if the client is not found in the database, what happens if you get an exception in the database, what happens if the SMTP server doesn't.
When you send an email, you know that suddenly you start with a bunch of simple code and also your code becomes very complicated, in this case it is three times as long or twice as long as those and this is what you know if you have written our driving code, you see this all the time, you start over on something that starts out very simple and gets a little messy and complicated and confusing, and you lose track of what the important features are, the important stuff is buried in everything. error handling, so let's look at the functional equivalents, we're going to define a result type which is basically two options, it has a success case, a correct case and an error case or a failure case and it's one of these points, functions again, something comes in and it can be a success or a failure and then all our little validation functions basically say in this case if it is if the name is blank as an error if the emails are blank that is an error if of the opposite is fine and you go through all your functions in your workflow, do exactly the same thing and end up with a bunch of points.
Features like this. Validation may not return an error when updating a database. sending an email may be an error or whatever, again you have exactly the same situation here before we have these dot functions and we want to connect them and that's it, we're done, so that's the two way model of error handling, aka rail order scheduling and I have a whole talk about that if you're interested, here's the code before adding error handling, let's say we don't do any harry handling, we just throw exceptions correctly, so we take the request that validate it, we do all the stuff, it's nice and clean, but there's no proper error handling because maybe a hint now, if we add error handling, let's see how much more complicated it makes it, okay, we're going to make a lot of mistakes . helpful, now everything will be handled fine, so after this is what it looks like ok, it looks exactly the same now I'm cheating a bit because I'm using exactly the same function names, but I could validate the requests where they were handling a mail file email with an error when handling your database update.
Was there anything you could name the feature slightly differently, but the point is that you still get this nice workflow, but behind the scenes on the two tracks it's handling all the errors very well. is very good because it keeps the coke clean, so join and C is really important, the reason why it is important is because it makes the world crossing function composable, so let's now do join and make it very generic for any type of effect. You might ever think about this because it's a pattern, really this is a conceptual way of thinking about props, we have these world crossing functions that start in normal worlds and end in the effects world, so this It is a kind of diagonal function. you go diagonally from one world to another and the problem with these things is that they are not composable at the moment.
What bind does is turn it into something where the entire function lives in the effects world, so it's a horizontal function, so I've turned a diagonal function into a horizontal function. Now these horizontal features are great because they're easy to compose. You can literally just glue them together, so let's look at an example of that. Let's say you have a bunch of diagonal functions like this. you say you can't glue them together they just don't work it doesn't work but if you use bind and make it a horizontal function like this and bind it again now we have a bunch of horizontal functions and they can all be glued together that's why it's so important make it a way of chaining diagonal functions and diagonal functions are functions that happen all the time when you when the effects happen every time you know you work with I/O, whether it's worth a database, whether that you work with options, errors or results, or if this happens frequently, that's why I bought them, they are so nice, that's the right way to do it, so let's go back to some terminology now that we know what a monad is. it's a type of effect of whatever type you want to call it like option or list or anything like that, whatever it does, it doesn't really matter what it is, other than a spin function, it converts normal values ​​into things, well, that It's trivial.
I understand they were and return is sometimes called pure sometimes unit objective there are many names at the moment here is the key there is a link function that converts the diagonal function to a horizontal function so you have these three things and for of course people are inconsistent with names my programmers are always some people call it bind some people call it Mac Mac in Haskell they don't even have a name for it it's just as fun a symbol with two angle brackets in c sharp ifyou use link select many it's a link operation and you have to have sensible implementations and that's Monad laws so when you hear something like Monad laws you know if you break Monad laws you're going to go to jail no if breaks Monad laws, it just means that your code doesn't work the way people would expect because you're not the implementation, right?
It doesn't make any sense, so that's what a monad is. There are these things. It's just that one type plus two functions. Also, you have to follow some rules when you implement it, so hopefully it won't be so scary, maybe the monad is a little demystified. Okay, so monads are very important because you have these effect generating functions and you want to chain them in series. You need to use a monad now a quick thing is mono is versus mono AIDS and this sounds like the same words, they are efficiency, they are actually different, but there is a connection because there is another way to compose these point functions, you can compose two point functions , retrieves other points function is the same type of thing and there is a symbol for that type of thing angle bracket equals angle bracket the interesting thing is that if you combine these two things you get another thing of the same type does this sound familiar so can you repeat it repeatedly? add things to them and it also turns out that the order in which you can buy things doesn't matter, so this looks very familiar and in fact, if you do this, this type of composition is, in fact, I'm already using point functions quite well . that thing more and then we're talking about lives so we have these effects like we have an option of something and in that option something you will combine them so get a couple so let's say we have an optional 42 and an optional hello and we We can find them when we have a pair.
You know, it's optional.42 and hello as a pair as a tuple, which is affecting what you expect now, if one of the things is nothing, then the overall result is nothing, that's also what you would expect now, what What happens to the lists if we combine two lists and create? a couple of elements, a couple of elements from each list, how do you do that? It turns out that there are actually two different ways, one is the cross product, so if I have 1 2 3 and ABC, I can pair each one with the other, so one in a and then one in C and 2a or 2b and 2c and so on, so there are nine possible answers.
The other alternative is to compress. When you compress this together, you simply take the first in pairs in the first, 1a and 2 B and 3c. There are two different ways to combine lists, the general term combining things like this is an image functor, another type of nasty word and asynchronous opt-ins, pretty much everything you'll come across can be treated as a target, so it's a package. functors, that's a horrible name, it really isn't again, it's one of these effect types plus a spin function plus some way to combine these two effects into one and you have it all over again, name types also apply, pairs of different, slightly different implementations, exactly how it works, but the point is that you're basically combining things and again there have to be sensible implementations that are called functor applicator functor laws and so on, why is that useful?
It sounds a little interesting, but it's actually relevant, well, here's a here. a very common problem is that you want to validate the field in parallel, let's say we have a client and you need to inform him that the name must be exactly 50 characters or less than 50 characters, you cannot reward, the email address must be validated. Other than that, you know it has to be the right date of birth, which is more than 19 less than the Hyundai. Whatever the frequency, you have these validation rules, so we complete some validation functions just like our point functions we've done before, but when you chain them together, the problem is that if there is an error, we get the first error and then the rest are skipped, so we get one error and all the other possible errors we don't even know about, so you know it's okay, but it would be nice if you got all of them. the errors at once, right, that would be nice, so what you do is say you start with a JSON fragment or a little bit, you know the DTO toy where there's nothing about it, the string could be anything in the mail electronic could be anything to everyone. field in this data structure, you won the little validation rule and you get some results and then you combine the output to make a final signal that way you can keep all the errors at once, that's what we want to basically run this in parallel in instead of serially, so how do we combine them?
That's where the app comes in, so we have all these different values ​​that live in the results world. We have the result of a name that could be valid or not. We have the result of an email that may or may not be valid and a birthday that may or may not be valid, how do we combine them well? We don't have to combine them in the normal world if we have a valid name and a valid email etc, we just use the constructor to combine them correctly, we can use the constructor and now we get a van as a customer, but this works in the normal world.
The good thing about applications is that you can convert a function that works in normal worlds into a function that works in results. world so that you can take that construction function and elevate it to worlds of results using the magic of applications. I'm not going to tell you how to do it because it's a little confusing, but the point is that you can take these individual things and create a client and this client is in the results world and it's done in parallel, so if there are any errors, all the errors are combined, so if you look at the code for this, here is the creation of a valid client in the result worlds, what you know is that it validates the one thing and the other we get the name or an area, it's not necessarily a valid name, it could be a name or a bug right now, that constructor is the normal constructor, but we use these magic symbols here with the angle brackets and we call it just like with a different, like we have called the normal constructor but we use the magic symbols instead of just a normal function call and this is magic and the output means we get this error message here are the magic symbols and they don't explain how it works but the nice thing is that everything works as if you were calling a normal function.
Now notice that we get a list of error messages. How do we combine the list of our messages by combining two lists to make other lists? We are using monoids. We are using applicative nanoids in this example. Well, let's review the tools that we have combined, that combine two values, that we have, that reduce, that reduces a list, that we have a map that raises the functions, that we raise the functions, that we raise the individual values, that we link and that we rotate . This diagonal becomes horizontal functions that we have applied, which combines things in parallel and there are other words for that, you may see elevators etc., let's look at an example.
I think I'm a little late. I'll be just a couple more. In a matter of minutes, let's use all the tools together, so let's say you need to download a URL into a JSON file and then you need to parse that interest from Jason, for example, a customer DTO and then you need to convert that customer DTO range and then I need to store that customer in your database. Okay, now we all have these different worlds that we're going to work with. When we download the JSON file, we start with the URL in the normal world as a string and actually end up in an asynchronous world. world which is on top of the resulting world, so when you download it it could be a valid piece of JSON or it could be an error because the server wasn't one and everything is asynchronous because it doesn't respond immediately.
So we have an asynchronous result of a Jason fragment. Okay, that's our first function. The next function we take that fragment from Jason and parse it when we decode it into the client DTO, but that could fail because Jason's entitlement is invalid. Okay, so it could be a bug and then we take the customer DTO and we take out the three fields and each of these could have a valid value and then we take those three fields and we can create a customer and then we take that customer in the normal world and we store it in a database that again may or may not still function correctly and it could be asynchronous, so we have all these functions and how we're going to compose them together, they're all diagonal functions, all weird. forms, they're just not going to be composed together, none of the things match, but fortunately we can use our set of functional tools that we know how to use, so the first thing is to analyze and then create the client that we just saw. do that with applicatives so we can replace it with a function that turns the DTO into a client, okay, so we have a DT and a client now, where does the DTO come from?
It comes when parsing the JSON, but when we parse the JSON, we don't get a DT, oh, we have a detail or a possible error, so it's not supported, we have these diagonal functions, well, how do we do it? We use bind. Okay, so we link these two functions together and now we get some horizontal. functions that we can then connect together, we compose them into a function that now takes Jason and turns him into a client and then here is the code to do it, we have a JSON or error, we bind the first, we bind the second so that Literally, the code is small okay the problem with this is it's still in the result well we have to move it to a receiving world so we use mac and now it lives asynchronously and then that's the last one that stores a client , again it's a diagonal function, so we're going to use bind again to rotate it horizontally to the right and now we have the first one that goes up to asynchronous worlds, so Jason and the client are now all in asynchronous worlds, the client that stores a Database is also asynchronous. world, so now they're all exactly the same type, we can put them together and create a single function that goes from one to the other, so there's an example of how you would use these tools that you use in this toolkit, so here's the code again, but to download install custom we start with ul, download the file, take the process we just defined and assign it and then use bind on the last one to summarize it, so again just a few lines of codes.
It really takes a lot more time to explain everything than it does to write the code. You could write this code in mini R. Yes, but we are using the same tools. I am using different types of tools and the concepts are the same throughout. just one thing to learn, even if you don't understand everything, which I don't think you can cross, we can, slang is slang like any kind of joke, but it's not that scary, you know you can, it's just unknown and hopefully, you can see a functional person talking about monads all the time right now.
This is a very generic toolset. They have a feature set like Mack and link up for anything. It is a set of patterns. This is really the equivalent. pattern language as used for strategy patterns and factory patterns etc., this is the equivalent type of pattern language for functional programming, so we use these consequences over and over again and just use a bunch of them just for this is an example, hopefully. Now you can see when you view the map and apply and link usage. You will have an idea of ​​what they are for, but like I say, I don't expect you to understand them or it will take you a while to get used to them, so there is the functional programming toolkit.
I will post the slides on my website if you are interested in this. I have other talks. I have everything about design patterns. I have everything about composition. What is under main modeling. I have a whole book on domain modeling. If you like it, follow me on Twitter if you're interested. Otherwise, thank you very much for coming. Don't hesitate to ask me questions. I will be available all day.

If you have any copyright issue, please Contact