Hi, and welcome everyone to the session on stumbling overstate by Daniel Steinberg. We're so glad you could join us today Daniel, thank you so much for being here and without any further ado over to you Daniel. Thank you. So, often when we have these concepts that we think we know so well, we forget it what it's like not to know this thing. We get so comfortable with functional programming or monads or whatever. And so I think back to learning a bicycle and what it took to learn it the first time and someone helping us and running along beside us. We forget when we ride a bicycle we think we're just steering straight but we're actually making constant adjustments. And we forget all of these things that we do to make this thing stay up and ride and just do the things natural now we get on a bike and we just go where we want to go. We forget what it's like not to know how to ride a bike. And it turns out, once we can ride a bike, we can pretty much ride any bike. It takes very little for us to learn shift or not shift or handbrakes or coaster brakes or electric or traditional. And so we forget what it's like not to know something and that includes functional programming. And so as we try to explain it to others, we have to put ourselves in their mindset. I remember very well coming to functional programming six, seven years ago. And so many people were very helpful but so many people were very well just figure it out just look at the code and figure it out. So I do want to note that I probably know less about functional programming than than any of you. And these are the thoughts on my journey here and how we can help others follow along with us. So I work in iOS. I teach a lot of iOS like I code a lot of iOS. And so our local gatherings are called Coco heads. And at a recent Coco heads. One of the attendees asked if we can give an example of where we might use generics. And their question was just so general that I was afraid it would be dismissed by the group and yet the group was so kind. And so my answer was the answer that was probably given to me when I something similar and that was in Swift and my examples will be in Swift. So hopefully you can translate into the language you're comfortable in. You can't create an array. You have to create an array of something an array of ints for example. And so we can create an array of ints. And then we can do something without array events we can ask how many inch there are in that collection. And we could create an array of bicycles. However, we do that. And we can also ask our bicycles, how many bikes are there. So whether it was an array of instant array of bicycles we can ask these common questions, but what the array contained. That's what our generic is is describing to us. And so count didn't care what it contained. On the other hand, we have these higher order functions these things like filter would say, you give me an array of ints and I'll tell you which ones stay in and here I'm just going to keep the ones in that are that are multiples of two the even ones. And for bikes, maybe I'll say I just want to keep all bikes in who are less than $300 to buy. And in each case, we've used the type so the collection of ints used a function that took an int. And the, we write it really with the square brackets more commonly, and this collection of bicycles used a function from bicycle. And so we gave her and other cocoa has chimed them and they gave a network example in a parsing example, you know where F was was generic and a and we parsed the data into something of type a and someone demoed code and what was notable to me was the person who demoed code had never spoken to the user group, ever. And they were just so astounded that they could share something with people. And it was just such a great feeling for them. No one said functor, no one said monad, and no one made fun of anybody. We ran beside the person that asked the question, well they learned to ride a bike and we supported them, and then we let go, and we let them ride by themselves. When they fell and we all fall, we rush back over and help them get back on the bike and sent them on their way. And so, I just want to urge you as we go through this material, not to forget what it was like not to know because once we know what a generic is, it just seems natural to us. So as we try to explain to others, that's what I want you to keep in your mind. Now we're remote this year but a number of years ago I was lucky enough to be at funk comp in Bangalore. And at the end of the day, a few of us decided we were going to go to dinner. And dinner was over there. It was across the road and Bangalore traffic. And me being new to this, all I could see was this expansive water with sharks and alligators in it and I had no idea how we were going to cross. But one of our hosts, they saw that if we stepped off the curve and we walked with confidence, we could clearly walk through this. And so having that person to guide you to give you the confidence to take that step, and then to take that step with you. That's the help that I needed to get across the street. For me, I came to programming late my training is as a mathematician. And so I was self taught I wanted to learn some things in Java and then Objective C and then I came to Swift and other languages in between but primarily I was a mathematician I was a differential And one of the things you do to make a living in mathematics is you teach a lot of freshman calculus classes. And so when we teach calculus I remember the first day I walked in this is what was written on the board in the class that I took it I vowed I would never do that to students. It's true. It's the definition of a function. It says for every x there's a unique why such that f of x is why, but that's not helpful. That's the way of getting people to say, I wonder what they're teaching down the hall. A typical calculus class begins with limits. And you talk about limits from the left and limits from the right and the limit from the left equals a limit from the right then the limit exists. We talk about continuity if the limit from the left equals the limit from the right and the equal the value of the function and the functions continuous at that point. And then we use these definitions this definition of derivative and this definition of limits. We use these to calculate derivatives. And the whole time we're doing that.  I've taken calculus before I know what's coming. And they tell the people around them, don't worry about it there's an easier way. There's a formula for this you don't have to know about limits you don't have to know about continuity. And so, as a teacher I asked what if we start with the easy way. I'm not saying don't teach limits I'm not saying don't teach continuity, just start with the formula, use it to motivate some examples, use these concrete cases to give people context. And then we break out of the context when we need to turns out calculus is built on just a few important ideas. And one is that the graph of a function is a smooth curve near some value of x if that's the case, something like this. That's me drawing a smooth curve. You can see near x not that that red graph the y equals f of x graph is supposed to be a smooth curve, whatever smooth curve means but if that's the case, then it turns out we can approximate the graph of the function your x for the graph of the tangent line. And so, what we're saying is close up that purple line looks something like that red curve, at least really close to x not. And so, near there, since it's so much easier to understand what's going on online than on a curve, we can approximate what's going on the curve by looking at the line. And that was the idea of the derivative the derivative is the slope of this tangent line. So the derivative of effort x not that's the slope of the tangent line, whatever the y intercept happens to be. And that is our first very simple idea in calculus, and we use it for all sorts of things. There's special things that happen when the derivative is zero there's special things that happen when things are increasing or decreasing. But if we have a smooth curve now that word smooth curve means something and there's details that we're kind of leaving out for now that we're going to have to come back to later, because it turns out not all curves are smooth. We can quickly encounter the absolute value of x. And if we look at the absolute value of x we see there's a corner there at the origin. And it turns out then that this smooth curve thing the easy way. It's a good start but it's not enough. When we get to functors and an array will be our way in, but it won't be enough. If you look from the left you can see everything to the left of zero, the slope is negative one, everything to the right of zero the slope is positive one and now we get to that issue where the limit from the left doesn't equal the limit from the right. And so the limit doesn't exist the derivative at x equals zero doesn't exist. All of a sudden we need these more complicated these more formal ideas. So one of the semester in the calculus class one of my favorite things is writing everything they've learned on the blackboard and everything we've learned over an entire semester painstakingly with examples and graphs and formulas can be condensed to just this much. And that's what happens with all of our learning. If you think of what it took for you to understand all these concepts and functional programming, it took quite a while but now that you know it.  So that's us with functional programming. Now, I mentioned that I use swift there are people in functional programming that roll their eyes at this fortunately, there was a talk yesterday where the talk said what do you need for a functional language. The answer was well ergonomics are better in some languages than other but there's actually very little that you need for a language to be considered functional. And yet I know some people don't consider swift to be necessarily a functional language but you can do functional programming in it. So there are functional practices that we can follow. And there's nothing in the language that forces us to behave. And yet, you're becoming, we're coming to the point where people will say that that's very swifty code that that's more swift like, and one of the things that's driving it is our new UI, Swift UI. So even though Swift doesn't have support for some of the things that you might consider essential like lazy evaluation or partial application or currying. You can do functional programming in Swift. I think of this with the bicycle. Last year, I decided I was very out of shape and I needed to get back on my bicycle and so, instead of driving to places, I should bike there and so I took out my bicycle. And after using it for a couple months I decided to buy an electric bicycle and I felt so guilty, because an electric bicycle. It's not a real bicycle. I'm not really biking it's it's helping me along with the motor. As I pedal it gives me an extra kick, you know functional programming is functional programming. Swift isn't a functional language. And yet what I found when I looked back was in the first four months of last summer. I went 80 miles. And once I had my electric bike, I bike 600 miles. So even though each mile might have been a little easier, it wasn't that factor easier and now I'm more likely to get on the bike to go meet a friend for coffee or go do my grocery shopping, or I'm not in loss. So that extra push got me on the bike, in the same way that using Swift Swift is the language I use. I'm writing apps for the iPhone. And so, even though Swift might not be considered a functional language by some people. It's the language in my pocket. It's like the iPhone is the camera in my pocket. And so, I'm going to do more with functional programming because Swift is the language that I that I use. One of the things driving us in this direction is Swift UI. And so here's how we might create something using Swift UI. It's a little button component. And so I'm going to create a button that has an image on it. So the button will have text and an image. And so if you have a button, a button has two things that you need. Now in Swift UI, a button is a value type. It is immutable. And so we're making this this nod towards doing the right thing, at least from a functional perspective, we're creating these things very inexpensively, and we're not mutating and we're throwing them out. A button needs to do two things. It needs to know what it looks like what is it displaying, and it needs to know what it does when it's tapped. And so I have to input that. So here's the text in the symbol name that I'm entering. And that's what will be displayed. And here's the action that will perform. And this for many in Swift is the magical moment because all of a sudden they realize that a function and a string can both be properties. And this is obvious to people in functional programming, but the people that come from this oh world from a Swift world. This is very new. And so like tangent lines and calculus, we have this very fundamental easy idea. And one of the most easy and important ideas in functional programming is that functions aren't special. Now, we tend to say functions are first class objects but the fact that you can treat a function, the same way you would treat a string or an int, and you can store it in a that's a big step for some people. So let's render our button here's what I want it to look like. And so in Swift UI the way I do that is I conform to view and I implement the body. And so here's my button and my button constructed there's several I'm using the one that takes an action and a label. And the action is a function, and the label is a function. So here is a constructor that accepts as its parameters to functions. And this again is something new. Now we've been talking about map and filter in Swift for years, but a lot of people haven't made that leap to where it's very natural to pass a function in. And so my action in this case I'm passing in as that property name that was passed to me and for the label I'm constructing a label using that text and that symbol name. And in Swift, we tend to use trailing enclosures to make this a little cleaner. And so instead of using that label. We can just use this as a trailing closure. And so this is very typical Swift UI code. So Swift and Swift UI has driven many people that never would have thought of functional programming in the direction of functional programming. There's the immutability there's the first class function. There's a higher order functions and so let's stay with a higher order functions. And let's return to arrays because once we understand higher order functions and Swift UI, maybe we'll reconsider what people have been telling us for years about using them in arrays. So I had this collection here, this array of ints. And I took this collection, and I filtered it. And I filtered it saying you give me an int. And if the int is a multiple of two I return true and I keep it in my collection. And so filter returns a new array with just the even numbers in it. So once I have those, I can further process it. And so I know folks from Haskell work the other direction. But here, I like this because it looks like a bulleted list I take a collection. I filter it, I take the results of that and I map them. So I have even numbers so I might as well take those even numbers and divide them by two. And so I will get back one and two in my final array. And the point is that inside of this closure for the map I have a function that starts with an int and returns an int. And so the map of F takes an array of ints, and returns an array of it's again very natural to us. If we instead have an array of strings, then my map will take a string and do something with strings in this case, I have a function that takes a string and returns the count it returns an int. And the fact that an array of F is taking an array of strings and returning an array of us. And the fact that we can transform and produce a new array. This is new to many people but arrays is our entry point into it. And we're starting with those smooth functions we're starting with the easy cases, like we do in calculus. We can use our closures and in swift instead of doing string and string count, we can use our dollars zero placeholders for the first parameter, or we can use key pass. And we can just say words dot map using slash dot count, and all of a sudden, it's very readable it's very natural we know what we're doing with these things. So we learn map for Ray. And it's as if I give you this question. So on this for you. Here is why equals f of X for X less than X. Not. What happens to the right, how would you continue this graph. Now there are many ways to continue it. I would expect that most of you would do something like this. Because that's the nice smooth graph and, and that's what we're used to. Now we'll return and look at other cases, but this is the array. It says start your understanding with something concrete that you know, start with arrays start with dictionaries start with sets, these all are similar. And so filter and map and reduce and all these higher order functions exist in collections. It's very natural for us. What we're headed is by the end of the talk, we're going to get away from these things that are essentially containers. And that's another huge jump but for now, the huge jump is if I give you this and I tell you to continue the graph. There's nothing that says you couldn't have put an angle in it and continued it this way. Nothing said that the graph had to be smooth and get in our head, we tend to gravitate towards the nice examples. What comes up for us in in swift is optionals or you might think of it as a maybe type in swift and optional is implemented as an enum, it is generic and wrapped. And there are two cases. Either I've got a value in which case it's wrapped inside of the some case, or it's nil, in which case it's formally the none case so we informally talk about this is the nil case. And so that's an optional. So, just as we had an array of strings and we could use map there. I'm going to give you a kind of a dumb example, and we're going to do map for optionals as well. And what's interesting is most people in swift, never reach for an optional map. In fact, many don't know that a map exists for optional so it's hard for them to generalize on this. I have a possible word I have an optional string which we write more like this a string with the question mark. And so that's an optional string. I'll let it be nil just for ease, and I'll use that same function count. And it looks like I'm using the same function map but this is map for optional not map for arrays. And so map for optional takes a nil to a nil. And for a non now it reaches inside transforms the thing using count, and then wraps it back up in an optional. So, count is a function from string to it. So the map of F in this case is a function from an optional string to an optional it. Now, those of us that have been here for a while, we see these connections right away. They aren't easy to make an array doesn't feel anything like an optional. And so, we put this in our list we have an array a dictionary set and now an optional, and we let that sit with people so they can see that working with hand breaks is just a detail. It's different than coaster brakes, but a bicycle is still a bicycle I still essentially ride it the same way. I just have to think of the details a little differently. It's time for me to stop. So here's another question for you. I'm only giving you the value at x, not. And I ask you, create any function y equals f of x, passing through that designated point. This is a big moment. When I asked you to create a type that accepts a map. That's a big moment. So first we learned by looking at map for array and map for optional and now it's time for us to create one. And so we have to see the need. We have to see why that would help us. And so this is a huge step for people. So as an example, I want to look at magic hat. A magic hat contains exactly one item. So it's not like an optional where it can contain something or nothing. A magic hat contains something exactly one item. So it's a struct. It is generic in contents, and it contains contents, which is of that type contents. Now contents could be an int contents could be an array of events contents can be a stringy can be a bike can be anything you want. We're generic in contents. And so I can make one that contains an int. Here's 17 it's a magic hat whose contents are 17. That's a magic hat generic and int. And what's inside of it is the number 17. So what should map do for magic hat. If I have in function from int to something else that the map should go from a magic hat events to a magic hat of that something else, or should we say it, if F is a function from a to B, then the map of F is a function from the magic hat generic and a to the magic hat generic and Now, if we think too much about magic and we think about a magic hat sitting on the stage and a rabbit turns into a scarf or something or a pigeon. Then we forget that actually we're creating a new magic hat. And it will have something of type B in it. So we're not only swapping what's under the magic hat we're actually swapping the magic hats, and that's the immutability. If someone has been motivated this way you can ask them to write map and they can generally figure it out. They've seen map for array for optional and for other types. And so they know that it has to be generic and whatever the target type is. I need that f that transform that takes whatever my type is to that other type. I end up with a magic hat containing that other type, and to implement it, I know that I have to create a magic hat containing be, and all I have to tell you is what are the contents, and the contents are what I get when I apply that transform to the current contents. And again you've done this for years it's very natural to you. It's a big moment when someone can do this for themselves. So, it's, it's like, for those of you that have kids, it's like that moment where you relive the things that you loved as a kid by looking at the joy in your child's eyes when they do something for themselves. When they make their own lunch for themselves when they ride their own bike, when they do something all by themselves, it's a big moment and watching the joy in someone instead of saying well that was easy and obvious. It's, it's wonderful what they've done. Now we can use our new map. I have this magic hat that contains the number 17. So I can take 17 and I can map it using a method that I've created which is, I have a deck of cards. And so a card has a rank in a suit, and a deck is just an array of those things. And I'm just going to count down so many positions and give you the card at that position. And if I have more positions than cards I just get to the end and I start again. And so my card from the fresh deck, I'm getting the magic hat that has 17 in it, and I'm replacing it with the card, which turns out to be the five of diamonds. So what should map do for magic hat. I had card for fresh from fresh deck which took an inch and mapped it to a card. And so the map of the card from fresh deck to become magic hat containing an int and gave me back a magic hat containing a card, still containers.  Now these examples provide context and allow you to learn new things. And so Apple came along a few years ago, and they introduced something called combine and combine was their functional reactive framework. And it looks like they're now phasing it out in favor of an async await and all the friends that go with it, but at the time combined had publishers, excuse me and subscribers, and ways of connecting to them. So these are pipelines from publisher to subscriber, and our maps and our filters in between took one publisher and converted it into another publisher. So this is an example where I write a rock paper scissors application. And when you hit go, you choose rock paper scissors, and you get a response either from the computer or we do a network version.  So you're choosing rock paper scissors that's a hand position. And so I have a hand class. And inside the hand class, it has the hand position, and that's rock paper scissors. And because that is set, either by you pushing a button, or by the machine, I'm going to publish that result. And so this is a publisher of hand positions. Now, like the result type publishers have a success they have an output type, and they have a failure type and in this case, I'm publishing a hand position and I can never fail. There's never an error. And it's a detail but for this type, you have to have an initial value so initially I'm going to publish a rock. Now what I'd like to do is take that publisher of hand positions that never fails, and somehow transform it into a publisher of strings that never fails, so that I can display it on the screen. I can get the string that represents the image name and I can display it on the screen. And as soon as you see something like that, you can hear the need for a map. And so we're adding to our array, our dictionary or set are optional. The result type we mentioned, the one you created publishers also have a map, and because of your experience using and creating other maps, you're very familiar with this one. And so you say I want to create this image name that is a publisher of strings that never fails. I'm going to start. Now this dollar hand position. That is the publisher of hand positions that never fails. I start with a hand position publisher of hand positions that never fails. It's initially rocks so I throw out the first one. And now I want to convert it to a publisher of strings that never fails, and I can do that using a map. And from my hand position I asked for the image name using this key path. Now it's a technical detail, but the actual type of this is this nasty massive nested generics. And so we use type erasure to clean this up to any publisher. It will get easier and swift, but I've highlighted the main two pieces, the drop first and the erase to any publisher details. The real thing I want you to concentrate on is we had a publisher. Excuse me we had a publisher of hand positions that never failed. And we've converted it to a publisher of strings that never fail. I'm going to duplicate the setup, because I want to look at possibly throwing an error, and I want to do that because we've been looking at map, and I want to look at flat map as well. So I'm doing this for no reason, except to motivate this example. And so instead of picking a hand position, I'm going to pick an integer between one and 100. This divisible by 10 I'll throw an error. So this is completely made up so that I can throw an error. And if I don't throw an error, I will take the integer mod three and assign it to rock paper or scissors. So I have a situation now where an error could be thrown. And I want to show you the first attempt. I start with a publisher of ins that never fails. I start with the first because I had to have an initial value for it. So that's still a publisher of instant never fails. Now, restricted position can throw an error. So instead of map in combine they have us use try map. And this gives me a publisher of hand positions that can throw an error it can throw a divisible by 10 error. And if I throw an error, then combined says, I should catch the air. If I caught an error. I want to come up with some hand position I can give you, but then my types don't match. If my try map was successful. I'm returning a publisher of hand positions. If it's not successful. Right now I'm just returning a hand position. So I have to wrap that random hand position inside a publisher of hand positions, and I do that with something called just. In your language, you may have just or unit or ID. It's a way of taking an element and embedding it in the in the monad. And so, if I have just five and I'm in the world of arrays, then I get an array that contains only the number five. So just random hand position takes my random hand position. It publishes just that random hand position, and then it says, I'm done. I'm not going to publish anything else. So the nice thing is the types match up. I end up with my publisher of what I want, but the first time, a number that's divisible by 10 pops through. The restricted position throws an error. Try map re throws the error. I end up inside of this just, and I'm done. So as soon as I hit my first multiple of 10, I get a random hand position, and then might my process stops I don't get any more hand positions, my game is over. So I'd like to be able to keep going after I hit my first multiple of 10. So let's wrap my try map and my catch inside of something. And so because it dollar and drop first. These are publishers of hand positions that never fail. What comes into my closure is going to be an end streaming in from the top. I want to somehow connect that to my try map. So I take my int my five, and I put it inside of a publisher, and now just it publishes that five that came in, and five falls into try map, and catch, and so on. So, what is that question mark thing that is on the outside of this closure what is the operator that I'm using. Inside the shape of the inside is it's a function that takes an int and returns a publisher of a hand position that never fails. If it was a function from int to hand position, I would use a map. But if I use a map. The problem is, I get a publisher of a publisher, I've double wrapped it. I've taken the inside which gives me back a publisher of hand positions that never fails, and map takes that int and wraps it inside of a publisher, and I get a publisher of a publisher. And as all of you know, this is calling out for instead of that. Going the wrong way, sorry, instead of map a flat map flat map will flatten this out so I go from upstream a publisher of instant never fails to a publisher of hand position that never fails. And what's nice is every time I get a new int. I get something out of this. Just is inside of my flat map. And so the next int that gets published from upstream pops in something will always come out of the inside of my flat map. And so this is, this is where we can handle errors in combine, we keep going after the air is thrown. And so I look at things with map things with flat map include arrays and dictionaries and sets and optionals and results and publishers and maybe something that you create. And so if I look back at introductory calculus I now have map and I have flat map in introductory calculus I have these two operators these higher order functions, and the derivative takes a function returns a function, and the integral takes a function that returns a function. And it turns out the fundamental theorem of calculus relates the two. So once we have map and we have flat map. Another big moment in the lives of people coming to this world is seeing how they connect to each other and I'm just going to use a raised illustrate. Suppose I have a function from string to int. Suppose a function G from string to an array event, but it's a very specific function. I want G to be what I would get if I take F and take a string and produce an int. And then I use just to take that int and embed it into an array of events. So G takes a string and returns an array of int that contains a single int. So what happens if I map F by map F I've lifted that to a function map F from an array of strings to an array of events. And what happens if I map G. I lift that to a function from an array of strings to an array of array of ants and as soon as I see that I think, uh oh, what I really want is to flat map G. So once we have this diagram it motivates our understanding to see that the flat map of G is the same thing as the flat map of doing F, followed by just. And that's just the map of F. In other words, as soon as we have a flat map and adjust, we automatically have a map, and all these things that we were taught were hard and category theory kind of fall out of this so roughly like smooth curves. It's similar about all these types of map. And there's something similar about all these types of flat map, and a type with flat map and just always has a map, and there's some fine print about map and flat map. Now, I give you this curve missing the point x not and I ask you to complete the point. I understand that many people would fill in that dot, but I want to point out that any of those points any of those purple points is a valid answer. And there's many more messy answers than clean answers. So even though we think of graphs as functions as being continuous curves and smooth and well behaved. But they aren't. There's many more bad curves than nice curves. When we think of map and flat map we think of these types we think of containers. And that's because the context we've learned them that.  You've taken your container a and you produce your container be, but what if it's not a container. For example, the reader. The reader doesn't contain anything except a function, and the function goes from something we think of as the environment to a. So this reader monad, which tells us oh it's got map it's got flat map it's got just. And that what it's like not to know something, this is a huge step. And we try to build on what we know from magic hat and do this algorithmically we use our formula. This is what we did for magic hat. So, could we do the same thing for reader. If I had a transform from a to B. How do I get from a reader EA to reader EB. And the answer is I'm going to have to do some sort of a composition that I'm going to have to take this f from e to a, and use the transform to get that a to be, and now I'll get an f from e to be. So my map takes that function from a to be to produce a reader from e to be. By using my transform on f. So if f goes from e to be, then I got my composition. Now let's use reader. So sorry, just a time check it out five minutes to go. Okay. So I use my reader. Let's produce an example with the deck of cards. And so a card has a rank ace through King and a suit. And the deck is an array of cards. And so in this case, I have the 17th card. And so I've got my e and my a and my f to fill in my E is my context as a deck. My a is a card, and my function says, get me the 17th card you give me a deck, and I'll produce the 17th card. Now I won't know the deck to later on. So let's play. I take my 17th card, I use my map to take my card and return a rank. I use my map to take my rank and return a string. Now this thing took a reader deck and card and transformed into a reader of a deck and string, I can try it with different decks. If I use a fresh deck, I get the five of diamonds.  So notice what's different is we passed in this F at the end, we passed in the environment at the end. This is a huge step you're building up this context thing and then adding the specific instance that we're in later. Now what if we wanted the next card. If we want the next card that depends on the deck, and we don't know the deck yet. We just somehow work with the deck that we don't know about, and we don't know which card we're on yet, because that depends on the deck. So here's a helper function for next card. Notice its shape it takes a card and returns a reader of a deck card. Soon as you see that you feel flat map. So somehow I have to return a reader and my function that I produce in reader because that's the only thing reader needs is that function from E to a it's got to go from deck to card. And so my deck to card says, if the card isn't in the deck just return the first card, and if it isn't the deck return the next card. We use it. We take the 17th card, and we flat map it, and that gives us a reader of deck card. And it depends which deck we pass that the environment gets passed in last. It's not a container that contains all the things the head at times. So for the fresh deck we get the six of diamonds, and for the face cards we get the jack of clubs that's the card after the king of diamonds. It's not a reader monad state is similar. It's also not a container. The difference is that instead of it being from E to a, it's from E to a and E again we're modifying it and since we want to think of E is not being the environment but the state we use the letters instead. And so let's deal from our deck and to deal from the deck, we return a tuple the top card and the remaining cards in the deck. So I have my S which is my deck, my a which is my card. And I'll create an instance of state my dealer will be the, the state that I create using this function. This is my function from s to as. My dealer can deal cards like this, I asked you to run, and it returns a card and the rest of the deck. Now this is a pain in the neck, because to get the next card, you have to pass in the deck you just returned the one without the top card on it. And this is kind of exhausted and annoying. Fortunately, we have map and flat map. What it allows me to do is just say, this is an example for dealing cards but I could use it to flip coins. If I get a red card I'll call it heads.  And now I make my coin flipper from my dealer, and I run it. Now notice, I'm still getting a deck back. And my a is my coin. So map converted the a, but not the s. So that was the map for state. Just quickly to show you the implementation again if I have a function from a to b. And I want to end up with a state I need that run function.  Well in this case it's a b and an s, because I'm transforming it. When I run it I get an a and an s, and then I use the transform to get it to be a b and an s. So this is exhausting. I'd like to be able to deal five cards at once, or end cards at once. So if I have my dealer, I'd like to say, give me the first five cards. And it gives me the first five cards. And if I want to keep going, then I take the deck which is what remains after I've dealt the first five cards off of it, and I deal the next five cards. So what is this next, it feels like what we did with handling errors and combined. It's like the next card with reader. I say how many cards I want, and I build up an accumulator and I started with an empty deck of cards. And inside I'm going to flat map because of the shape of this function which says, you give me a. And I'll make sure that I haven't used all the count that I need if I've used all the count that I need, I'll give you my accumulator. Otherwise, I'm going to recur. Otherwise, I'm going to pick another card, add it to my set of cards that I'm going to return to my accumulator, and I decreased by one, I need the flat map because of the shape of the function inside. I'm not going to show you flat map for state of reader. I just want to point out that as we ventured into the world of these monads into these states, we had these hard points we had generics. And that because you're so smart and so experienced but new people who are also smart just not experienced generics functions as first class objects, map concrete examples, these are all new to them, and each step is hard. At the end we can combine it onto the single slide, we saw patterns we created our own functor, we made the leap the flat map, we understood the connection between map and flat map. And we felt we really understood containers and so we took this final leap into reader and state. It's hard. We forget that riding a bicycle is hard. We forget what it's like not to know something. Thank you. It was an amazing, amazing inspiring very inspiring session. Thank you. Thank you. We have a hot take. If you do F from FB right, you get OP for free and vice versa. I think that's dead on. I know people get very religious about that. But I think that if you do what you see mainly from FP people who take on OP people is they take the worst cases and all people who take on it's the same thing but if you're doing either one right, you're factoring into these small reusable testable components. And so I completely agree that at the end we end up the same place in many ways. Right. So we also have a comment from a lady she says really like how it started from the basics of FP to reactive form of FP. And then he says this is a reactive approach with elements and other operators are used to transform the elements. Exactly right. And so in in combine and I assume that's when they were talking in combine the map and the filter are called operators so it's exactly it's exactly the same. Swiss combined comes from reactive streams. So that's the Java library that they derived from. Right. So yeah, they also shared some something here generalizing out of container context is giving me lots of funds to transducer wipes. Now or maybe that's because I spent several sleepless nights on it. And I wish we had transducers and swift I think closure has them and it makes things so much nicer and so I wish we had those there. The cheeky signature for transferring service, whatever input, whatever, go gives whatever input, whatever, and then there's the link that he shared. Right. So, yeah, and yeah, the closures are the poor man's objects after all, that's from other. Thank you all this was a lot of fun. Thank you. Hopefully we'll be there in person again.


You guys also like shockwave? I mean... Sure? I'll livestream Krega on shockwave. Okay. Oh. That's a problem. Yeah, just put it in this bag. Okay, take it apart. It only does if you're sitting on the outer seats though. Yeah, I know. Canceled. Canceled. Yeah.  Although it's starting to feel a little more like Wonderland. Like... It's definitely getting busy. Are you going to ride shockwave? I'll keep them entertained while you ride shockwave. Are you sure you're going to be able to keep them entertained from that one? Yeah, I... Ew. Wait till you guys see the video we have. We pranked Krega at Wonderland Hardcore. Yeah, we pranked him real good. That is so shady. Brendan, you can still close your exercise ring. No, not Siri.  Yeah, look. What are people saying? Oh. Nothing much yet. Look, the line's getting long. How do you reduce stomach feelings on rides? Start on a smaller ride and work your way up. Leviathan's running amazing. They should be next, I think. I don't know anymore. Only a couple more days of social distancing. Behemoth lines are short. We filmed some really cool videos today that I think you guys are going to like. We filmed a lot. Like a lot. The lines are busy. I mean, like, they waited 45 minutes for Behemoth, which was un-terrible. The lines for flat rides? Non-existent. It definitely... Normally, the midways are dead and the rides are busy, but if you look, the midways are pretty busy. It's starting to look like a normal Wonderland up in here. The 40th store isn't open yet. Should be open soon. Yeah, they're riding... They're running shockwave because we forced... Our team has been filming all day today, so now I'm letting them enjoy some rides. While I livestream. It's going good. I'm really sunburned. Sunburned. Look at my watch tan. This ride almost just faulted. I don't know if they're waving. Wait, this ride now hurts? We'll get Krikko's reaction after it. Make sure to put sunscreen on. Yeah, I know. The 40th anniversary merch store is going to be... Beside Sky. I forgot what it's called. Extreme Skyfire. Oh no, you're good. Don't worry, don't worry. I always feel bad because guests here are really nice. Like, if they see you filming. The, like, stop walking and I feel bad. Like, I shouldn't be getting in your way. Will ride capacities be normal by August? It should be back to normal by August. Thank you, Alastair. But I am not. Shane Dawson knows. No, I'm kidding. Live on Behemoth? No, you guys get bin POVs. That's what you get. We'll get you a bin POV. People are saying this ride's painful now, so good luck. Wait, how are this many people getting on? This looks like a normal, like, ride. What happens in the bin stays in the bin, remember. The crowds are a lot more busy today. I mean, like, flat rides are pretty dead, but I don't know why people are waiting for that. Here, I'll show you guys. He hasn't written... Hi, it's Jonathan. We are not going to Wonderland the Day Stage 3 starts. Actually, I might change that now. It might show up. I don't know. But yeah, there's the bad line. Oh my God, look at that sun. Look at that. It looks like a fake, like, sky in the back.  I can't take a picture on my phone right now, because I'm live streaming. They're about to go on the ride. Look at the goose. The bad is overrated. Yeah. The fastest line for Behemoth is about, like, five minutes. Maybe 10 minutes max. What time are you going to Wonderland? We normally go to Wonderland on Wednesdays and Thursdays. All day. We're here tomorrow as well. Can you guys hear me, by the way? It's really loud around here. I feel bad if you can't hear me. There's still dates available. Go ride time warp. Yeah, we might go ride time warp, to be honest. Wonderland will be at 75% capacity, approximately. And there should be zero social distancing measures in place on the rides, but I can't confirm that. I don't know if you guys saw that, but... What are the lines going to get very big this Saturday? I mean, with better capacity on rides, it should be better. Oh, that is a great angle of Yukon that I got to get. Dragonfire is a good roller coaster to ride. You just get a roller coaster, but I'd start on Vortex. I'm going to get Krega in the shot. We're right at the park, Leviathan. Just go straight to Leviathan. We don't know all the changes. We reached out to the park. The park didn't fully know all the changes. Just capacity is 75%, starting on Friday. Look at these losers. The park is open until 8 p.m. Do you think they're going to enjoy it? Do you get butterflies hanging over Yukon's drop? Not really. When we first started coming back to Wonderland, the rides were hitting us really hard, like the butterflies in the stomach. I think this ride's been neutered so hard. That's the best ride in the park. Rides do seem faster this season. We won't ever get an RMC conversion. You'll get a ground-up RMC. This ride looks so boring now. I don't know why. The park was at 8 p.m. I don't think there'll be one person per car. I waited two hours for it to rain. I don't know. Canada's Wonderland seems to be their baby park. I love when people look at you so offended when you're recording a ride. We had a really bad experience in Splashworks today. We were filming the new attraction, and a Karen flipped her lid and caused a whole scene. We basically, the supervisors of Splashworks tried to ask us to stop filming, and then we were like, I was just filming Krega jumping off the attraction. There's nothing against the role. It was just so awkward, and all because some woman was so ticked off, because the camera pointed at her at one point, and she didn't want to be in the video. All she had to do was like, approach me and ask that she not be in the video, and I wouldn't. Now I'm just gonna do it. I'm gonna put her in the video at a spite. Sledgehammer's not broken. It's just not operational. Yeah, you too. How was it? It looked so boring from out here. It's not. It's a lot of fun.  I don't know. I don't know. I don't know. I don't know. I don't know. Every time you go one way, you just get sent, and do the other way.  It's just unpredictable. Somebody just said, I'm behind you. That's... I'm waving. Do you see that? Who said it? I'm behind you. I'm waving. Max? No. Gentlemen, what ride do you want to do now? You want to go check out Yukon? Yeah, let's go check out Yukon. Let's see if we can get another... last ride of the night on Yukon. Oh my god, but he gave them a true moving bin at POV. Yeah. Honestly, if you still have time, I'll just try hitting up a lot of things. Do you think there's still time? Yeah, if there's time. I am craving a Tim Horton's quencher so badly. Again? I didn't get one. Oh yeah, that's right. We didn't really... No. I think it's a join-backy question. I miss them so much. Thank you, Daniel. The $1 will go towards Craig's new haircut. Oh my god, we're going to get copyrighted. Blah, blah, blah, blah, blah, blah, blah, blah, blah. Blah, blah, blah. I know. Yes, the line-ups are pretty long. Oh, here we go. Are the lines long? You guys should hear the sound. Please get him a haircut. Let's save the questions for later. The lines are long. I can do it or not. Yeah, you just walked pretty much onto... You have the camera, right? Okay, good. Okay. Can you say Yuki's hamster is cute? Just say it. Yuki's hamster is cute? Yeah. Okay. Yeah, we have a... Oh, sorry. This is top blow. Come on. You literally just... I watched the camera. You literally just didn't get it. Yeah. Let's go this way. Is it busy today? Yeah, it's pretty busy today. Did I just see a white text on the line? It's like... Yeah. What happened? It's just light mode. Why is that fast?  It's not.  My head shaped bald. Yeah. The park? Definitely dies down. Yeah. Like even vortex? Oh. Did you go on any... Did you go on any big rides today? No. Behemoth. Wait till you guys see the prank video we did on Grega. It's pretty epic.  On all the rides. Yeah. Park's dead. What time is it, anyways? I do not think we're going to make it from Levi. We have 30 minutes. Time crunch. Look at this shot. Wide angle right now. You'd prefer vortex over Yukon? You'd prefer vortex over Yukon. Timberwolf bridge for you. What do I look like? Hi. Behind the scenes photo. What's my favorite ride, Leviathan? What? Yeah. Are you talking about how we used to like Yukon more? They kept in some pretty funny boats. Oh yeah. Yeah, because he's funny. I'm not funny. To Yukon. I thought we were waiting for it to come out. No. When you buy a season basket, you go as much as you want. Yes. As long as you reserve. As long as you make a reservation. Yeah. These Timberwolf boats are... Oh yeah, that's because... Here, let's go. Let's go. Let's get this team on our live stream. Yes. Yeah, so Timberwolf is killing it right now in terms of operations. You see that? A boat is about to come around the corner.  Yes, we are having fun, Louise. I think the lines will definitely... I don't think... I don't know when the 19th is. We come Wednesdays, Thursdays. All right. I keep pausing Yukon. No time. There is bring-a-friend discounts going on on the season pass. Sorry, what? If Yukon's line is too long, we're going to go to Leviathan instead or we're going to do Yukon. I haven't been on Leviathan at all this season, but... You haven't been on Leviathan at all? He hasn't been on Leviathan at all. Okay, yeah. You can't not ride Leviathan. Let's go this way, no? No, that's not faster. Yeah. We're just going to... Yeah. It's literally... No, it's like this. We're going to Speedwall. Okay, he hasn't been on Leviathan this season. Well, I haven't had the time. The line is like too long. You should have said something. I did say something earlier today. Oh, really? Yeah. Is that legal? Yeah, no. We're not letting you leave without riding with Leviathan. Uh-oh. I've made a mistake. Even if it's like an hour away, you have to get on Leviathan once. Yeah. I've been playing on it. I haven't gotten around to it yet. Everyone's making fun of the fact that we just walked all the way over here and now we're... Yeah. We started this out while at the beach. Do we not? You know, exercise is good. What do you think? Yes, more spots will be available in Stage 3. In fact, if you go check right now, the spots have been made available. After 1pm. Yeah. 1pm on where there's been a ton of spots added. How many people are watching? Yeah. 87 right now. Oh, cool. That's a lot of people. It's not as many. I think we had like a hundred and like 80. If all 87 people were in front of us, physically watching is a lot. That'd be a pretty big group of us. Hey, Brendan. Everyone's telling us to run. I don't know if they saw me when I put the camera on me, but I'm not really built for running. You want to run like that? Yeah, people are saying run. I run all the time. If I start running, I could accidentally get momentum in the wrong direction and I'll end up running, rolling down that hill. You can run into a tire. Yeah. Whenever I'm like, I need to get somewhere here without anyone else on all this running. It's a moose. Isn't it like a deer for Winterfest now? Yeah. There's like a deer animatronic. Yeah. Oh. Yeah, it's a lot busier on the midways. I can't believe you haven't been on the Viathan. Oh, yeah. Yeah. Yeah. Sounds great. Y'all hearing Thunder Run? Where did she go? Thunder Run. Oh, there she is. I think so, yeah. Y'all hear that horrible noise? No. It would do it in the rain. Now it does it all the time. You're going to cancel us if we don't go right. Aw, man. Look at the eyebrows. Do I need to do them? Why? Oh, you prefer threading? I prefer the unit to do it. Oh. Was it too painful? Do you need a... How many funnel cakes to the face did you get today? Yeah, that's a spoiler. Yeah. Tomorrow's video is going to be really funny. Everyone, 9 a.m. Make sure you watch it. We're going to be up from 9 a.m. to post that video. I'm going to be up all night tonight editing it, and then when you want to come to Wonderland tomorrow morning, I'm not going to wake up. I hate how security always looks at us. Like, can you not? Everyone's saying speed walk. We're almost there. Did we not keep right? I swear we kept right. That's what I said.  We didn't keep right? I was telling you, when you got right in there, yeah. Did someone say something? Yeah, a lot of people are. I think they might have heard me. Y'all, we're about to get canceled. Because I was like, Oh, that's sick, Louise. I've always wanted to try making funnel cake, but I know he had probably burned my house down. Ice cream on the fire? I didn't even clue into what you said. Are you excited? You're finally getting on the violin? I almost ended my stream. Sorry guys, I almost dropped my phone if you couldn't tell, because I'm trying to put my mask on. I just got rained on. Or pooed on, I don't know. I don't think it's rained on. Okay, cool, I just got pooed on. Oh, the line's not terrible. Have you seen his tires? Yeah. I love when people are like, you're that guy. The voiceover guy.  I like status. Okay, yeah. Sheeter. Hey, Kristen. I love how my team knows I can't fit under these. So they walk it with me. Shadow. Oh, hey, Helen. Wherever you are. Line jumper.  That's rare. Don't make up the line, not the... Are we even abiding by it? Ew, what is that? Just don't film the floor, Simone. I think I just killed a bug on my face. The line's not that long, to be honest. Guys, is it okay to cross over these bars when no one's there? It is, right? Everyone's making fun of the fact that I got pooped on and bugs on my face. That's good. People are saying, do not sit on the handrails. They're not actually mad. Cancel. Guys, when you stand up for this long, it's like a whole day of wonderland you're going to want to sit on the handrails, too. What rides have you been on today? The Wild Bees. Behemoth, Shockwave, and Wild Bees. We were filming all... You went on cliff jumping.   That's so Gen Z of you. Oh. Wild Bees. Wild Bees. Wild Bees. Wild Bees. Wild Bees. Yeah, back room. Wild Bees. Did you get the new head chopper at the end? I didn't notice it.  There is. I thought you said that was on my butt. No. Uh... Wild Bees. I am sweating.  Is Behemoth good? Sorry, Leviathan's interrupting you right now. Oh my God, I have a whole night of editing. I'll edit. Oh yeah? I've seen your editing ability. It is. I meant to be like a good thing or a bad thing. Better than his. Oh. I remember the video you tried to edit. Hey, where's the hidden video that he's welcome? You should hear his voiceovers. My life is... That's okay. All I have to say is... All righty, I can't do a voiceover of my life. No, we didn't ride UConn today, but we rode UConn. It's so hot in here. We can tell. It is hot in here for some reason.  Right, really? Sometimes you're like... All righty. Or sometimes you're like... All righty. Really? I can really tell if you're feeling good and all. Is that obvious? Yeah. Yeah. All righty. I'm feeling good and all righty. Then you're like, I don't know. He's sad. It'll happen. That's usually a red video. Yeah. Look at this Wonderland live vlog with a like on it. Did you know you could hit the bell button and get our notifications? Oh my God. It's got five dislikes. Wait, are we abiding by the lines? Yeah. Okay. Wait, how do I type one? And then you're saying the lines sitting on the rails. The dislike came from the seagulls. Brenda, look at your arms. Oh, God. That is... Oh. The other arm too. It doesn't look as bad on the camera. Oh yeah. It looks not the worst on the camera. I mean, it still looks pretty bad. I've never seen someone that red. How about my face? Oh, there's other people in the line. This line actually. I take it, is that you? No. Someone said, look at how many dislikes, then look again in a second. Okay, I got an air drop. Let's see what it is. That's me. I'll just type in shots so you can mod me. Oh yeah. No, we're not using Fast Fast. Wait, where are you going? Air drop. Oh, it's you. Well, I turned off my air drop to give people a hard contact. It might not be tall enough. I'm literally sweating. What I always see in parks is I always get spammed with air drops. I'm nowhere. So I guess, sir, I'll track slowly. Any news regarding Wonderland in stage three? Yeah, they're at 75% capacity and there should be... The weirdest thing. Oh, I can't put that. Wait, what was that? List. How tall is your front... Oh, that was cool. Not you, someone else. Look at your photos. We can see all your photos on the stream.  How... Look at this photo. Never used it. I can see why. I mean, realistically, it was taken on your camera. I have the same... What is that? You. What? All of them? Yeah, you sent it to me. It was a Snapfield day.


So today I bring you a guide on this new Hyperion SMG. It's called the Proprietary License and while people it's utterly amazing.  So this new Hyperion SMG is one to be honest that I first put off using as I was determined when I found this to find all legendaries for a guide video. So I got this in many other variants but just put them aside as my initial feelings towards the weapon wasn't great if I'm honest. But after testing it for this video I've got it I didn't bring you guys sooner because I can't believe how wrong I was with my initial thoughts because this thing is actually amazing. Now as you can see I do have many variants of this thing and damage wise on a mayhem 10 level 60 variants between a 3000 or 4000 damage or thereabouts. It offers all elements and this is a world drop but dedicated burst drop is the Hydro Goryan who is located within the Obsidian Forest. Root on location I will direct you to at the end of the video. So this SMG is a 5 burst and it's only a 5 burst it doesn't come in any variant as I believe as far as I know and it is very very unique as you can see shooting a test dummy headshot seemed to ricochet and body shot stick projectiles that later explode. On the test dummy's projectiles seemingly slide off him but with usual enemies they do stick and do that damage all the time. Now using this within a slot of chef for the most part it isn't the most powerful but it is a beast and I've used it now for probably a few hours straight and what I was noticing was headshots and those ricochets was an actual fact targeting nearby enemies. At first I wasn't sure so I tested further and it definitely does track nearby enemies and it's a lot like how the redistributor works. Only thing this doesn't have though is that amped damage so what this is it's basically a 2.0 version of the redistributor and it works similarly while it's then different at the same time. The redistributor is very weak against single target enemies but when enemies are grouped up it absolutely melts. This under other hand is decent against single target enemies but also having the ability on crit shots to chain it's also great at the same time for mobbing enemies. I wouldn't say it's unpar with mobs of enemies with the redistributor but it is decent. So this weapon which I first shoot one side in actual fact is an amazing addition and it's one I do feel will be worth your time farming. Again it drops in all element types and is a world drop too but dedicated boss is the Harjot Goyen who you can find a route to here on screen now. So enjoy that people and go get this thing if you want it. So my final thoughts on the proprietary license it is an amazing well-rounded SMG. One I feel people who like the redistributor will indeed love too. It isn't the most powerful SMG in the world but for an all-round weapon against single target enemies and mobs it's very very good indeed and it's one I would recommend you check in out. But on that note we have come to the end of the video if you guys enjoyed it leaving a like really helps out. If you're new around here and want to see more Boilands be sure to subscribe and if you never want to miss a video or upload you can turn notifications on by hitting that bell button. But guys thanks as always for stopping by hopefully you enjoyed the video and hopefully I'll see you on that next one


This just in, you're looking at, we have a very new story to tell you about. I just want to know, that is the way trade center and we just have unconfirmed reports so you don't have to explain it. I just want to know how serious news that we're made to have a severe tragedy for the many times we stand in crime, and they claim the question into the public trade. It is hard to think of an event in American history that transformed the nation in the profound way that 9-11 did. September 11th marks a day of chaos, uncertainty, and fear for this nation. However, it is also a sign of this nation's resilience. It's easy to understand the sequence of that day for those who did not live through it. But at that point in time, no one knew why America was being attacked, or if and when another attack was going to strike. These attacks targeted buildings that symbolize American power, but the perpetrators were not able to destroy American pride. 9-11 has always been a tragic event in global history. It is important that future generations understand the magnitude of this event. We should continue to learn and educate ourselves about that day. With over 3,000 deaths, 9-11 has been marked as the deadliest terror attack in the United States. Not only that, but many first responders had risked their lives to save the people stuck in the tower. It is important to honor those heroes who risked their lives for others. This day was a day that started out with blue-clear skies, but turned into dark gray within hours. We saw how things can change in a split second. Suddenly, without notice, people were hurt, died, or rose up to help others. 9-11 was the first air attack to happen in the United States after Pearl Harbor. On this day, we need to honor those people who passed away due to unexpected attacks, those people who were just doing their jobs on a normal day. We have to honor those who risked their lives to try and help people from the burning buildings. They became our heroes. So many people ran into the line of fire on 9-11, whether they were firefighters, police, or volunteers answering the call for help. We need to remember their bravery and selflessness. Their actions serve as a reminder to be selfless in small ways in our own lives. 9-11 was a day that completely changed America. On this day, with 3,000 innocent individuals losing their lives, so many different families were affected by this event, losing the lives of their loved ones with all of the uncertainty that they went through. However, it also represents how strong our country is. You were able to come together and bounce back from this terrible event. Through pride and courage, the citizens of America persevered, showing how we truly are a united nation. It was a truly devastating time, and it's almost unreal to imagine. But through the loss, it made our country stronger and more united. We were prepared to show that we were ready to defend our nation, and willing to prove it. One step at a time, we were covered, but we will never forget. I look back at this day and I feel an immense sadness that reminds me to not take the life I have for granted. On 9-11, so many people's futures were cut short. The people who were killed and their families paid a huge price. This reminds us to be grateful for every day we have. I don't think my generation realized the impact of 9-11 until they got older. In eighth grade, my teacher told me how before 9-11, airport security hardly existed, and she could remember walking right up to her relative's gate, waiting for her plane to arrive. A world without airport security or security in malls and schools seems very different. Although I was not alive on September 11, 2001, I believe it was an extremely devastating day. Growing up, I heard all the stories from my teachers, parents, and friends had. Everyone who was alive during that time could tell you exactly where they were and what they were doing. 9-11 is a truly tragic day that impacted all of America. Even though I wasn't alive during the September 11 attacks, the stories of the heroes of 9-11 have always amazed and inspired me. Most are about humans putting their lives on the line in order to save other people, but this story is about an animal. It all starts with Omar Eduardo Rivera, a blind technician who was working on the 71st floor in the World Trade Center's North Tower on September 11, 2001, when a hijacked plane flew into the tower. After Omar and his guide dog Salty fought their way to the stairwell, he unclipped the dog's leash and ordered him to go. Convinced he would die, Omar wanted to give his beloved Labrador retriever a chance to survive. But Salty refused to leave his owner's side, despite the panic and intense heat. For nearly an hour, Salty patiently guided Omar down 70 flights of stairs to safety. The tower collapsed shortly after they escaped. An incredible story. The impacts of 9-11 transcended geographic and political differences. People from all around the country came together to grieve and help with the aftermath of the attacks. Many people displayed American flags after 9-11 as a sign of patriotism. Educating the younger generations is vital to ensure that they understand the consequences of that day and to encourage their patriotism for their country. We need to remember this day to honor all of the innocent individuals who lost their lives. It truly was a day that affected America and will go down in history due to its significant impact on our country. Today, we honor the principles our country was founded on and demonstrate pride in our nation. We remember and honor those who lost their lives that fateful day. Here at PCTBS, we will never forget.


Page. Display information. Although it's very easy to upload your course materials such as word process documents to Moodle, it's sometimes better to add them directly into Moodle in, for example, a book or a page. This is better for your learners too because it means they don't need to have the same software programs that you are using and they don't need to download anything. They can read it straight on Moodle. To do this we click the turn editing on button top right or we scroll down to the administration block and click the link turn editing on there and in this section where we'd like to add our information we click add an activity or resource. This brings up the activity chooser and there are two resources which are helpful to us here. The book resource allows us to add a series of pages into which we can type the basic information we want to display or we can use as we are now a page. We can click the button twice or click it once and then click the add button and this will display a screen where we can add our information. Name is where we type the title the learners will see on the course page and then the description and if we wish to show it on the page we can check the box display description on course page. We then scroll down and it is in the content box where we type or add our page information. If you only have simple text to add to your course this is much quicker and better than typing it into a word processing program and uploading it and you can also add images, video and sound files onto a page. There are various other settings you might like to explore in your own time for instance appearance but for now if we scroll down and click save and return to course we can see that we've added a course welcome which any learner on any device with any software can open and access.


Well, hello and welcome to another Dev nation tech talk We actually have another excellent presentation to give you today And I just was a few minutes late because I had a cable modem challenge You guys know what I'm talking about here when the internet won't connect. What can you do? So in this case, we're gonna be talking now to Alex Soto Alex Soto is part of our developer experience team He is the fellow coming out of Spain right now traveling all over Europe and all across the globe Talking to developers about how build better software and today's gonna talk to us about how to do testing Specifically leveraging something very cool and a Kubernetes open ship standpoint You guys are gonna see it here Presented today and talk about end-to-end testing and testing in production. So Alex at this point Let me not take up any more time, but take it away. Thank you I'm going to start sharing my screen Thanks for for this introduction today. We're going to talk about testing in production So thank you very much for joining to these the app nation session And we're going to just see you know an introduction of testing in production because you know, it's a really big topic But you'll see just say the basics you will learn the basics of testing in production And also I will give you some hints so you can start implemented it after this talk My name is Alex Soto. I work in Red Hat and the cool photo testing Java micro synthesis book and I was also in the Outdoor of several articles in magazines also and also cheat sheets One of the things that I want to tell you before I start is that probably some of you will say This thing that you're explaining me is a stupid or it has no sense Or my manager will never allow me to do this or even I Think that it's not the right way of testing applications and that's right It's it's normal that you think this but If you start doing tests for micro services architecture and when I say micro services architecture, I'm not saying 10 or 15 services. I'm thinking about 100 120 services. Then it's the right time to Re-watch this presentation So this presentation is about testing and DevOps and one of the great resources out there is in this and in the puppet side Well, they every year publishes this white paper about the state of DevOps, right? And they and a one really interesting quote about DevOps is that high performer organization are Decisively all performing day-low or performing peers. So if you adopt the box, you're going to be able to upper form Your competitors, but let's see some numbers For example, you're going to be able to do 46 more deployments than your competitors and this if you think about it Definitely means that you're going to be able to hit the market 46 more times than them Also, you're going to Have shorter lead times in fact 440 Shorter lead times rather than your competitors and lead time is the time that is measured from you have an idea And this idea, it's available for your client or your customers So it's the process of thinking about it designing Developing testing on finally deploying and releasing to your public So if you have this time shorter, it means that you are going to be able to release These ideas faster than your competitors and of course errors happens because it's natural and if you Embrace developed then your your time to recover is going to be 96 time faster So this fundamentally what is happening today? In most of the companies is that developers are not responsible of what's happening after the checking So the life cycle for a developer is that they just go to the issue tracker They get it some issue. They you know, they create a branch with it They fix the problem. They write a test. They try it locally and then they push the code After that, they wait until the CI system for example Jenkins Says that everything is green so that all the test passes passes that everything is fine and then someone will review the change and Squash and merge into the master branch, right and That's all they do not care about how this piece of software is going to be deployed to production Because at the end this is something that you know operation guide will do some time Probably at 5 p.m. So we need to break this wall of confusion. We need to work together hand-by-hand Debs and apps and this means that if operations team stay all the weekend trying to deploy At a new service to production developers should be there as well And of course this means that there is a change basically the change of the definition that we have of done usually from the developer point of view then it's Something it's done when you close the issue on the issue tracker So for example when I tested and I know that it's that works and this changes Merge to master then as a developer point of view this is done. The problem is that this is not True if you want to do DevOps something It's done when it's deployed and released to production because we need to think about something really important Your code has no business value until it's deployed So you can discuss about you know frameworks to use if you are willing to do this with Quarkus of our spring boot or vertex or any technology or we can discuss about patterns You need to use this pattern of this other pattern or even we can discuss about clean code If this if we should do our code more clean on but We can discuss more and more and more but you need to always keep in mind that Until the the server is Deploy it's not deployed. We are not giving value to our business But of course it's not about that and now it's the whole organization that need to have you know embrace develop and and Have a common ground regarding the box. It's about ops It's about the PMO the the security team the DBAs the QA Everyone should be involved from the beginning of the project in the task so this means that Testing is not an end part of the cycle Usually if you think about how you're working is like that you develop and then you move the sticker from the board from Developing to testing and then someone test these and then this is a sticker is moved to operations and these operations deploy The the new service, right? This is not how it should be Things should be done from the beginning the testing game should be hand-by-hand with the developer checking how The service is going to be test So this is really important that DevOps means not that an ops about all the organization But of course, I mean after that you're going to start using all these continuous integration continuous delivery continuous deployment continuous operation all these automatic things right to be able to reach production Faster because you know if you automate everything then everything goes pretty fast the problem is that You're you can apply all these techniques, but still your time to reach production is too high And the thing is that why it's happening this and the problem user eats in the QA Organization organization sees testing as an expensive task that slows everything when you check Why a project is never on time? You always end up by identifying that okay the QA department is spending a lot of time testing the application and Why is happening this? Well, basically it's happening because the organization requires to verify This new service these new service manually and once we need to Believe it manually is the QA department. So of course Refining something manually takes a lot of time But it's not only this if you have a process where the QA is doing some kind of manual testing developers involuntarily will think that Someone is going to test my Work after me So I don't need to you know write extensive tests maybe because you know, there will be someone that manner will check. So QA department is going to be in church of verifying the software. It's going to be in church of catching technological bugs But not only this probably they will catch some bugs. They will go to the depth and say, hey look, this is failing depth is going to fix this problem and then the QA the QA guy will be responsible of Checking that it has been fixed correctly. So now QA team is doing two things verifying software catching issues and verifying that the issues has been fixed correctly But recently because of infrastructure as code Everything is really easy to replicate every environment is replicable really fast. You can have production and you have QA just, you know running the same um a script The problem is that since it's really easy companies start Um populating all these environments across the organization So you have the production environment and then you have the QA environment The problem with the QA environment is that this is where you're going to run your manual test, but You need to maintain this environment. You need to update it when production environment isn't updated You need to check when it fails what's going on and how to fix it or even you need to maintain The data sets that are inside the database and usually all these tasks Since it's a QA environment falls into the QA team so As you can see the QA team now is even doing another thing which is maintaining the QA environment. So another task Even if you think about not in the QA team, but in the in the point of view of organization having a QA environment, it's really expensive To run and maintain because at the end you still need machines or let's call it cloud machines Running this QA environment. So it's expensive to run and expensive to maintain because the QA um department is in charge of doing it But in any case I've been in several companies, which you know, we heavily relay on QA environments and manual testing So we did all this process. It took Some time to reach production, but at the end we arrived at two production So, you know developers write unit tests component tests contract tests QA departments do a lot of manual testing We deploy to staging everything works So we go to production and everybody is really happy until well We break production And we can break production because production always has Yeah, some uniqueness. For example, the network setup. I mean the dns the firewalls the database schemas probably are 90 99% the same but it can be some changes or even for example the actual weight of data It's really bigger than in comparison of The QA environment So this is where we can think about that. How about removing QA environment? I don't want QA environment. I don't want preproduction environment I don't want to run end-to-end tests manually The only thing that I want is production environment Of course, just having production environment requires a change on mindset and a particular for risk and also changing the way we develop our services because now When we develop a service, we are always thinking that this service is going to work right, but now what we need to do is start developing thinking that all service is going to fail So instead of developing for success, we need to develop for failure Of course, when we are talking about testing in production We are relating on an another concept, which is really important In the past, we can say that deploy And release was more or less the same when we say that we are going to deploy to production We were just thinking that we're going to take the service put it on the production cluster And Our clients are going to start reaching it And when we say we are releasing our services, it's exactly the same But in microservices that deploy and release is a really, really different steps One thing is the plot, which means taking our service and putting inside the production cluster Another thing is the release space. The release space is changing something in the plastic tool to start sending public traffic into this service So now we have deployed and we have released and it's totally different So probably the testing environment has changed it a bit Now we don't have this unit test component test and end to end test, but we have something like that We have the blue column, which is a production column Where is all the tests that are written by usually developers and they are run In Jenkins for every full request So it's unit test component test, contract test, acceptance test, smoke test and so on But then there is three columns, which is the testing and production column Where it's divided into three stages. The first one is deploy So it's when we deploy our service to production Which test I need to run. Okay. You need to run integration test This is something that maybe it shocks you because why you should run interaction testing in against production environment And the answer is that you need to do it because if not, they don't have Any sense to do it because why you want to run integration Test against an artificial environment. It's totally pointless Then we have that compare lot there showing test and conflict test Then after deploy we said that we release our service in the release space We need to use some of these testing techniques canary that canaries monitoring future flight and exception tracking or future graduation But then with microservices and testing in production There is another place and is the pause release usually when we release our services We said, okay, we've been it has been released That's that's okay. We are not going to test it anymore with testing in production You still need to test in this space using tame profiling logs couch testing monitoring a testing tracing and so on So as you can see then now the the testing is across all the life cycle of the software Of course, you don't need to start at once applying all these testing techniques You're going to start with real for with the the simple ones and a step by a step and increasing your Your um, confidentially with this Of course, none of these things explain it here easy And often requires a fundamental change in the way systems are designed developer tested deploy it and released So, of course, it's a big big change to um embrace testing in production Let's see some of these techniques that I showed you previously And this in this case is a technique tap compare which happens in the deploy phase So when we deploy our service to production, but no public traffic is sent and in this case That compares it's used for Detecting progressions. For example, we have service a version one. We have service a version two and we want to The that if it has been introduced any regression and the regression can be a performance regression It can be a back regression. It can be an output regression Maybe the output from both services has changed So tap compare is a kind of test that allows you to detect these regressions before going public There are two tools for doing that one is differential another one is uh Up and ify the thing about differential is that it's implemented in go, but it's integrated with java So it's very fast um It's given it strongly so you can run differential support And it integrates fairly well with from a few and this means that all these Regressions can be monitored by your Monitoring system in this case from a few but of course it also supports other systems And just in in for the schema It's was it how it worked is that differential? It's a proxy but where you are sending a request and then this request is sent to service a b1 and service a b2 Then both services returns a response and then you compare and then you send the status to the monitoring system and you send the result Okay, another test are the Release part in this release part. There are a lot of tests one of those are blueberry deployment Blue green deployments are based on that you have two identical environments And you are just switching from one environment to another environment in for example in the blue environment You set the service a version one and in the green environment you set Service a version two and It was something like this where you have all your traffic going to the service a b1 and then you deploy into the production service And then finally you re-root all the traffic to the service v2 After the time you need to you know monitor for any failure Which you know You can detect any problem if you detect a problem then you can really quick switch from v2 to v1 So it's really fast to recover from a failure Of course, this technique is really great, but it has some problems and is that it's a All or none problem. So all or nothing, right? So it's all the users work or all the users will receive the failure To avoid this problem. There is another technique which is called canary release And canary release is similar to blue green, but it behaves differently in the sense that you Deploy the new service. Okay, and then you start sending public traffic too But instead of sending all the public traffic You start sending just one person of the traffic or five person of the traffic If you monitor and you see that everything works as expected You can move forward to the 10 percent 25 percent 50 percent 100 percent. So instead of Doing a all or nothing approach where all the users could fail Now you are just, you know, selecting and a small portion of your traffic to check If the new service works or not Of course this works in most of the cases, but if you have a Heavy law traffic and I'm thinking for example like facebook that had thousands of requests For second then one person of the user are a lot of users for this reason Companies like google amazon or facebook created One set of techniques to test on production without the end user noticing it and we just call dark lunches And you can think about that lunches like an umbrella of ways to test or services on production I'm going to show you two different Approaches the first one is dark canaries Which basically are based on the next thing is that you have version one where all the public traffic goes there and then You have a subset of well-known users. Maybe it's internal users Maybe our client that you have and a special agreement with them. So they receive this update Before the rest of the public users. So these internal users which could be the QA department or Some clients that you have a confidence with them. They're going to start receiving This updates sooner than the rest and they will help you to test them Another another technique is shadowing traffic Shadowing traffic is based on mirroring the traffic to both services at the same time But notice that in version b1 you are sending a response The solution one is is that the blue ring the blue You're sending a request and then you're receiving your response In case of grid, which is the b2 you're just sending a request and that's all So this is what's called a fire and forget request. So you're sending the request and you don't care about the response But the good thing about this Approach is that you are monitoring this new version to detect if there is some kind of failures or not So you are anticipating any Problem that might occur when you for example start sending the public traffic Another technique is future graduation which basically lets The user to choose Which level of confidence have with the system? This is from open chip. I own currently It's called could ready which is from red hat where you have an attack Which is called futures opt-in where you can choose The level of confidence with the system. So depending on the level that you choose here better futures experimental or internal experimental You're going to be redirected to a more metro service Another technique. This is for the post release is 1000 g It's basically what you are doing is inject feathers in your system on purpose to see how it behaves under these circumstances Maybe you are wondering why I should do this and basically is that because you don't choose the moment when the failure happens The moment chooses you you only choose how prepared you are when it does So it's really important to See what's happening when there are problems before they happen. So you know that how the system will react when they really happens, but I like to see that.  So for example, you can Create traffic to one service on another service in propose or you can encrypt traffic between services or for example you can Add some resiliency for example automatic retrace in the communications So let's see it in this case. I've recorded because sometimes I have some A performance problem when I'm sharing my screen. So I recorded the demos And this I will show you the link so you can test it for you in this case You can see that I have my customer a preference services and a recommendation And then I have version b1 and version b2. So I have like four microservices there So now, um, what's happened when I you know, I just call All right, get access to the customer In this case, I'm just getting it and you can see that I'm just getting the customer preference recommendation b1 And then I'm getting customer preference recommendation b2 in the second call This is because by default Istio follows a round robbing approach, which you know, you send request to b1 and then request to b2 But just you know, that's fine. But then what I'm going to do now is just send all traffic to b1 So I just create an Istio resource, which is a virtual service and I said, okay now what I want to do is just Send all traffic to b1 and now for every call that I do It always go to version b1 now Let me what's happened when I do QCTR replace and I add the version v2 So I want to send all traffic to redo. Notice that this is a blue green. I'm changing from blue to green Of course, I just apply this Istio resource and then everything goes to v2 if you are you know interested in knowing There is an error and you want to go back to b1 I can just replace again to b1 and then everything is replaced it and as you will see All the code goes again to b1. So it's really fast really easy and if you want to see how this file looks like You can see here that I'm just saying That the recommendation service has a version b1 and I want to send all the traffic Let's go quick to canary if you want to do a canary. It's really easy because the only thing that you need to do is again create a new Or apply a new istio resource in this case. I'm sending 75 percent of traffic to b1 and 25 to v2 Notice that now I'm doing the call and you get it v1s v1s and then um Some b2s and so on it's like 75 35 is a canary release as we explained And you want to see how this works. It just you know, you define the recommendation and I said that the recommendation Service sends the for version b1. I want to send the 75 percent of the traffic But for the 72 I want to send the 25 percent of the traffic and the last one Is that dark or the shadowing traffic? in this sense It's a bit more complicated to show But notice that uh, when I'm doing a call in this case, I'm I'm not applying shadowing traffic yet You see this this is there is a number This is a counter that is incremented for every request that I send notice that the v2 is in the number 13 and v1 is in number 23 Then I can apply another resource Okay, which is the uh recommendation b1 mirror v2 And if you check here and this is the log of the service you can see here that it is sorry I'm just checking the recommendation one b2. I am going inside recommendation and notice that here The last log is the 13. Okay Now I can go up to the again here. I can do the the call And notice that I do call and call and all the time I'm receiving the v1 and the v1 with the 24 and the 25 The counter is incremented and remember that the last counter is a 13 of the v2, but now If I check the logs of v2, you see that there is a 14 and 15 So you can see that this mirroring traffic. It's working and it's working because the request is Received into v2, but it's never get back to the client The client will always receive the v1. So you can see here the request of request and forget approach So we are almost done if you want to learn more about this. This is there are some links here So maybe you are wondering how I can start doing testing and production The first thing that you need to do is having qas and depths working together from the beginning I know that there are some kind of complicated relationship between depths and Testors, but this is something that you need to fix and work always together And a start with a really really simple service preferably and a stainless service Of course depths can still think that Okay, I don't need to write test because you know, there is this Mirroring traffic thing or this tab compare thing that is going to catch my back So I'm going to not spend time on writing unit test or component test because you know, there is another automatic Algorithm that is going to detect them. Now, this is wrong. You still need to write unit test component test Acceptance and so on because you need to have confidence on your Sir on your software and when you have the confidence that everything is going to work as expected Then I start doing testing in production of course the final idea of testing in production is that The manual The manual testing it's going to be done by your clients or by your customers But not by your qa department your qa department has other duties to do But not testing memory for this duty for this task You need to relay on your customers and your clients And that's all if you have any questions or anything you can Pay me on twitter or by mail or in my website or on my youtube channel. Thank you Well, thank you so much for that alex and we are out of time If you could though if you have those links handy drop them into the chat real fast because folks would be In those links and and that way to have access to him here And of course you can follow alex on twitter with the with his twitter You'll see that he'll publish these links and other slides and other demos and other content As available and you should actually take those videos and put them up on youtube and also publish them from that perspective as well Yeah, I will I mean that I could put the videos I will put the videos. I will put the link everything in twitter. I will publish and even the slides I will publish right now. I mean that in even five minutes Yeah, yeah, so just follow him on twitter and then you better check that out I thank you all for your time today and I apologize for our slow start Because we did have a problem a technical problem that I had to work my way through But make sure you follow alex on twitter and I'll just add that link here All right, so there's the twitter link, which is the most important link and that's all we have time for I apologize, but we have to get going. Thank you so much Thank you