 My name is Johnny goes and this is my workshop on learn functional programming with pure script I phrase it that way because fundamentally this is a workshop on what it means to functionally program and That's first and primary consideration is I want to teach you how to be a functional programmer in two hours And if I don't succeed you get me at the end of class and I will go out and buy you a coffee I know we have gallons and gallons of coffees here, but we'll walk across the street And I'll buy you a really fancy $4 latte So you can follow me on Twitter at JD goes if you'd like to hear someone ran eat about functional programming and pure script and All things start up life Today we're going to talk about functions actually we're going to talk about functions a lot almost everything I'm going to be talking about today is Is a function or is related to functions at the very least But we're also going to dive into some of the terminology specific to sort of a pure script and hanskel ecosystem systems Including types kinds and also sort of more advanced types of functions And we'll look at some of the tools you can use as a functional programmer Just some of the real bare bones basics that you're likely to use in any sort of functional programming and especially in the game That we're gonna try to build here at the end and then yeah We're gonna have a coffee break because you never have too much coffee. We'll cover type classes a really beautiful elegant abstraction and Effects which is something unique to pure script and then we're gonna talk about scary sounding things Because a kind of functional programming that I'm introducing today Is is known as like hardcore Statically typed scary haskel like functional programming and it's filled with all these crazy sounding things that I'm hoping I'm gonna show you aren't really so scary after all. It's more their names that are terrifying than anything else And finally at the end I hope we'll have like collectively learned enough that we can put that to use Building a simple game and no graphics to distract us. It's just gonna be a simple text-oriented role-playing game But it's gonna be a lot of fun and I've already built the basics out there in the repository So you want to download that you'll be able to get off to a running start Functional programming it truly is all about functions and if you master What a function is and how to use it you will be able to call yourself a functional programmer? This is what a function looks like. This is the definition of mathematical function and this definition is like so simple once I explain it and elegant that You'll be amazed that you can build full-featured rich applications with something as simple as a function In fact a function is so simple It's simpler than the functions that you learn, you know in JavaScript or in in ruby and in all these other programming languages It's simpler than that. It's so simple actually teach functional programming to my six-year-old daughter And I would never dare try to teach her JavaScript programming because that stuff is hardcore difficult to understand so a function is a mapping from one set called the domain to another set called the codomate and In programming languages, we like to name all these things just so we can talk about them. We do that in math, too and And in this particular case, I've named this function John because it's a model of my dietary preferences I've named the domain food And I've named the codomain happiness and the function John Maps from an element in the in food to an element in happiness So in the case of eggs it maps it to unhappy because I absolutely hate eggs. I can detect them in mayonnaise I will not eat eggs under any circumstances and coffee. I love coffee. So it maps that to a happy face This concept right here as simple and beguiling as it is is at the heart of functional programming and And and if you're thinking to yourself, that's too simple It needs to be harder functional programming is supposed to be harder than that it's actually not and the reason why functional programming has Addicted some of us and and we refuse to write in the old style is because it brings a refreshing clarity of mind To understanding what a program does if you master this concept here Then you will have mastered what it means to be a functional programmer Now these sets on the left hand and the right hand they're not always as simple as as food and happiness and we're gonna go through some more advanced sets that can be tricky to understand But fundamentally every time you're struggling with some concept in this workshop I want you to go back to this and say this is what a function is a function is a mapping from one set called the Domain to another set called the codomain. So this is very sort of abstract and mathematical And you know, it's how I teach my daughter about functions. What does it look like when we translate that to? Pure script to a programming language like pure script Are we gonna have arrows? Are we gonna have named sets of things? Actually turns out that in pure script a function looks a lot like it looks up here Now this is how we define a function and if you have your laptops open Please type this in or type something simpler in just so you can get a feel for how you define these things in this example the function John I've defined below and you can see that it's a mapping you can even see that arrow in there It's a mapping from the set of elements called food to the set of elements called happiness That is with every element in food. It it maps that element to an element in happiness Go ahead Is the rebel for pure script if you want to type stuff into there Yeah So I define the function right beneath that and I say John of eggs is equal to unhappy and John of coffee is equal to happy So I'm defining this function piecewise. I'm defining it one element of its domain at a time Look out there pure script allows you to define these things called sets So in your spare back in the client that's called food And that set of food consists of two elements one is called eggs and the other is called coffee and that pipe operator You can read it one of two ways You could read it as an operator that forms a set out of a number of individual things So I'm building up a set of my things or you can read it as sort of or you know a food is either an egg or coffee And happiness is either happy or neutral But either way you are essentially the same I building sets here and getting the names because this is your script and like I built a set called food that consists of the elements eggs and coffee and the set called happiness that consists of the elements Happy and I'm happy and then I built a function And I'm telling your script this function is a function from the domain food To the co-domain happiness Go back here. Look at this that simple function Translates into pure stuff like that And every single function that you if you look at it's gonna be some variation on that same very simple straightforward thing of What's my what's my domain of the function? And what's my co-domain and how am I going to relate the elements in the domain to the elements in The co-domain and how am I crazy my six-year-old daughter is you feed this function called John an Element in the domain and it will spit out something in the co-domain. You feed it eggs that will spit out unhappy heated coffee will spit out that So that's even a function how you use it And you call it as you would say another Sometimes you don't say all functions or you know the functional program and I use sometimes you say apply them And we apply them at elements in a domain So we can take that function John and I define and I apply it By actually using white space which makes him sort of like a funky way to apply a function But we use white space and we say John space Hey, I feed it an element in the domain that it spits out an element in a co-domain and Say wait for John coffee John space coffee I'm applying the function John to the element in its domain called coffee. What do I get out? We get out happy So notice how sort of to define it I used a little bit of white space to apply it I use a little bit of white space is that element of symmetry here And that's one of the things you'll notice about pure scripted as well as there's a great deal of symmetry To these languages and consistency which makes them simpler to understand So there are two important things About every single function. These are math properties more than they are programming properties, unfortunately But they're the properties of totality and determinism and These two properties here are what makes reasoning about function and programming so elegant So easy and what it makes people like me to functional programming I'm addicted to functional programming now because I think it's complex and easy to know ugly Stanley words and names of things I'm addicted to functional programming because it makes my jobs Programming that would be easier. I have less to reason about because of these two laws The first one is totality says that every element in the domain must be mapped to some element in the co-domain function is total a real mathematical function is total and The second property is determinism so applying a function with the same value in the domain results in the same value In the co-domain in others. Let's go back to this one if I apply John eggs, I am always going to get back on that. I can do that a thousand times a day a million times a day It doesn't matter. I'm always going to get back on that And that's because this is a real function It's deterministic and that is a property of pure functional programming languages is everything is a function Everything is deterministic. You apply a function at a value. It doesn't matter how often you do it You always get that same value in the code And that's the property that makes reasoning about these functions so easy Because if you take JavaScript for example, if you call a function in JavaScript you may get back different answers every time you call it and And that means you have a lot of stuff you have to keep track of your head if you want to understand What that function is going to return because you basically have to simulate the state of the program Basically have to perform these mental calculations in your brain updating variables You mean this and that and your functions are returning different things all the time It makes it harder to reason about the correctness of your program and understand what it is That you're doing but in a pure pure functional programming language like your script You have the guarantee that every time you call a function So let's break and do a few exercises First off, I want to notice these two functions here And I've given them names and I told you what sets a map from what sets a map to So the first function is called superpower it maps from a set called character class to a function to a set called Superpower the second one's weakness it maps from the domain of Superpower to the codomain So what we're going to do is build these two functions We're going to do that by building the sets Representing the domains and codomains and then we're going to define functions and doesn't need to be super fancy or anything But go ahead and create a set called character class. We're just going to represent different types of characters and that's literally anything you want to could be no flying flying person or like I don't wall walking person You want to be inspiring and then map that to another set called superpower to represent So if you've all sort of got that let me switch over to the editor So this is how we define That's that all character class is defined in any way one giving us two elements and it's going to be a flying character Or it's going to be a wall walking one we're going to say We're going to define Superpower this will be a different set and we'll say in superpowers either user beam on ice And I'm going to find a function called superpower I'm going to map from character class I'm going to have flying those two user beam eyes that stickiness those two A wall walking character of the super power So he is I'm going to line my Equal size So now I have to create this function called weakness which is going to map from superpower to to a new side called So let me define you said here called quick tonight Yeah, this should work in the rebel except the multi-line thing is weird So you're gonna have to use less if you use the rebel We have to introduce all these things with No, you should just be able to call the function names space and then the element of annoying Yeah, you can copy at least this whole thing in there Your script out of doesn't remember your previous You're gonna have to copy days the whole thing You said Unfortunately not no, so no overgots are welcome So in the rebel, how would you transform? So does that get an error with that? So what do you need the? Well, he doesn't want to type signature is there a way to specify type signature though in the rebel and multi-line You need the mobile line mode and use the let introduce it to let So we're gonna take up the night will either be Literally Or I put the spider-man's weakness Does he have a weakness Guns very very I Okay, and we're going to define this So we're saying a metaphor Function So we're gonna map the superpower of laser be my eyes To Yeah It actually won't get confused with that and the reason is they only occur in specific positions in your first program And I'll talk about this in a second. That's really excellent question. By the way the question was I'm using kryptonite to describe the set of things called kryptonite But I also using the word kryptonite to represent one of the elements in that set and your ship doesn't get confused by that And that's what doesn't get confused by that this family this entire family of languages don't get used by that They're separate these spaces on entirely and that's because they only occur at certain positions in a go like this one only occurs After these lines here, which you can read Has time And that's where this one occurs and this one here only occurs in value Yeah Why is that so that's just the way you introduce the set Data says I'm introducing some element of data forming a set here It's going to contain a bunch of things like a map from that set to another It is a keyword that it's sort of a weird keyword, but So let's jump right in here. I sort of showed you what it's like to define a function But there's like lots of crazy stuff around the edges, which is why you know, you're all going to need these really excellent questions Fundamentally pure sketch is a static in type That means that we're going to spend a lot of time in this workshop looking at types and dealing with types What is the type? Well, fundamentally a type is nothing more than a set of values So a type is a name that we give to a set of values so just like I have been in the set called Happiness and that consisted of three elements happy or unhappy Happiness is a type of pure script. It's a set in sort of the math world, but in Computer programming languages the notion of set transfers over into the notion of a set And so we talk about sets of elements and these sets of elements have names which are the names of the types So we're going to spend some time looking at a bunch of different types This group has simple basic types that also have some more advanced types And we're going to look at each one Okay, so the set of literal types. There are Currently three sort of built-in types in your script and these are going to be very familiar to you from other programming There's a set that we call string that is a type string And that's a set that contains all strings like boob and bar and so on and so forth And then there's the set called number, which in theory contains all numbers and practice you have to deal with the clothing, voice, monstrosity that is child scripts number And then there's boobing which is the set that contains the values True false. So all these are sets and I want you to go back in your mind that picture that big old bubble And I'm going to take a picture of bubble here that contains lots of different things And in the case of string contains an infinite many things But you don't need to worry about that. It doesn't really affect the visual stage and all that much Just think of it, it doesn't make any points in that fault Number consists of finding many things because we're limited in how he gets he can store what these things and then Hopefully just has two things in it True false So that's pretty boring. Let's go into a more interesting type That's going to allow us to find more interesting data structures for the game that we're building and this This is called a product type. I sort of sneak this in for the last lesson Without properly introducing it and now it properly increases. This is called a product type and basically what it consists of is a set bubble the data keyword he produces one of these product types and Sort of sort of the word being following that it has to start with a capital of a page Just for historical reasons really and that's the name of the set that you're finding is the name of the type and then immediately following that is this thing Called a constructor is actually the name of a function That will create values of that type And this is why you can have something like data kryptonite equals kryptonite Or Mary Jane it's because That's That's second reference to kryptonite is a function. Well, the first one is a reference to a pipe It is pretty okay, so I'm defining the location and the context is let's we're going to go to the game Let's give our character a location He's gonna have a location and we're going to describe them by two numbers So like throw, you know X and Y coordinates on some sort of map so we can track work there And so we're going to define a set call location and We're going to find a constructor function called location It's going to take two parameters and parameters from the types so What we're saying by this is a location consists of All things that our location consists of two numbers the X coordinate and the Y The first location is this name of the set we're defining the second location is the name of a function that will create values in the set If you provide them a few numbers That makes sense So how do we actually create one of these? Well, we just use the name of the function and then we Supply them to parameters using white space to apply a function. Yeah, so it's kind of same like data point equals point number number or Polar Okay, so that's how you define one of these things and now where am I is an element in the set location and so in any function You can use in any function that maps from location to something else You can feed that function where am I because where am I is an element of the set call location? So go back to that that visual illustration at the beginning and You can sort of, you know, see see that emerging from what I'm talking about now Okay, so you can construct this thing you can construct values of type lock With the lock function just by supplying the two parameters it requires The natural sort of opposite of construction is deconstruction. That is if I have a lock How do I extract out its first position in second position? So I know where that character is because once I build a lock like it's not obvious How are we going to get out the two numbers we fed into that location constructor function? So we can tell where that character is on the map Well, you do that using deconstruction, which is otherwise known as pattern action Feature that functional programming languages are very interesting But the pattern action it's basically just pure syntax It looks like What you see up there on the slide I define my function called log x and log x is going to pull out the first number the first part of a Location The x-coordinate of where that character is on the map And it does that by using an syntax there and what it's saying is if you pretend that lock x underscore is creating a value It's saying I want you to give the names x and underscore to those positions inside the constructor function So that on the other side of the equal I can refer to things inside those locations Does that make sense? And again, if I want the lock y what I can do is I can use the pattern action syntax To extract out the second element of that and call it y this creates a new variable called y And I can refer to that as a type of one. It's like that to be equals y the second block y to be equals y And then I can call these functions Which I'll call this extractor functions because they extract out pieces of information from from elements inside the lock set I can call them on those two values as I've done there lock one two I call lock x on the value lock one two and I get back one And I call a lot why on the value Walk one two and I get back to so I'm able to extract out the pattern action Whatever I build using this product type whatever I build no matter how complicated it is no matter how many Different types that accepts. I can always extract that out using any any component I want pattern matching and the components that don't care about I can just call them underscored It's needs ignore it and don't be a variable name for that specific piece of information inside that data That makes sense Yeah This might you might cover this later, but is there a specific name that we would typically use for in this case the x or y others fields or Well, that's a good question Elements of the product Yes, it works Yeah Here's here as a different Conviction for the term field we'll see in a second. So you probably wouldn't call field Well, they know a lot of fields. It's like you have one field. It's like a mean. It's like an anonymous position Okay, so Here's another way that you can use to deconstruct these things And it's basically just pattern action. It's just a different way of doing the same thing and in fact all the examples of this Peer script file something looks like this and that handles this case But it's just this syntax probably seen switch in some programs I wish that you'd use or back or something like that It allows you to switch between a lot of all things and there's a similarity between that cluster up in whatever language you use You know pattern magic So that's sort of where the syntax comes from But you just do case and then you specify the value Then the keyword of and then you match the patterns down below And for every pattern you have that arrow symbol and you produce a value that you Presumably extract from the data element you're deconstructing them So, yeah, oh is There's actually two these faces here. What is the type that is it's a set of locations the type name But it's also I've used it for the name of the constructor So it creates a type called low and also creates a constructor name called low And that constructor name called low allows us to create elements of the type called low So think of locust being this big old set that contains these things But I'll have to do them loose and low is a function that allows me to create one of those things inside that set But it's also the name of the big set. Is that a little confusing? Yeah, quite a lot Oh, yeah, so here I am giving a name to the first Slot inside that thing about there two slots inside both to hold the X and Y and I'm saying case L up And then I say look and I'm getting a name for that slot and I can refer to that X After the year I'm creating what's called a variable binding here. I'm creating a variable called X That's going to catch itself if you will to that spot that first lot of the location case Does that make sense? Yeah Okay, so this is quite a lot to digest and Finally, we're not doing anything but creating sets the sort of the complexity of the sets that we're creating as Well, because now we're not just creating simple things like Mary Jane and kryptonite over creating sets that contain pairs of numbers in a case of low repeating action sets upset cold look that contains these pairs of numbers and With that home complexity comes an excellent time to stop for a little break and do some exercises So let's create a character stats product type It's going to model some character statistics in the role playing games So I'll have health and stranger Whatever else you want to put in yours, but stuff it in there as a product type and then we're going to create some values Of that height I understand how to use the data constructors And then finally I'm going to show you how to use pattern management game to make that more concrete to extract That components of that data Questions with mechanics so sir I've been putting this stuff into a file and I wanted to load it into the rubble I see there's a load but it complains I guess it things are in a module if I put things in a module they seem to be namespace funny So I'm just wondering what's the best way to get this stuff is in a file I think low is the best way But you'll have to put it in a lot on cool and then unfortunately you're gonna have to learn about that Import keyword, okay, which I didn't even want to talk about but import M allows you to import module that things inside a module called M So you define a module called module and where and then you list them on to code here that You can load that in and then you can import them and then you'll get all the junk that she defined inside It's important that Prior to this you were just typing your script to do a file if we want to say okay now You want to test this and make sure it's right? What's the best way to do that? I usually compile? I'm not a fan of problems, so I probably do the wrong person that's okay, so I even sell them some stuff PSE and then filing PSE and then filing so when I did that it complained it wasn't in the module. Oh That's that's exactly right. You're gonna have that you want to put this in a standalone file You will have to put it in the module. So let me do that for now on Inside PSCI something like low Import M and then I start playing with all these stuff. Okay, so character stats I'm going to create a product data type. This is a set all character stats And again confusing you know, I'm going to call the name of the constructor function character stats There's some things like syntax if you're scripting other languages like it. It's just that sort of it used to over time and I'm going to give this Let's see a name So I'm going to choose the literal type string You got on the name. We have some string characters. I'm going to give it a health and Maybe I'll give it a speed And now I'm going to create few examples of few elements in this set by using the constructor name all character stats Remember this defines a type. I'm going to say test one here. It's going to be a test of this type It's going to have five character stats that is test one is an element of the set character stats and I'm going to say The name of this character is very g and Her health is a hundred and there's be is Okay, there it is, but since you put the type signatures, is there a way to say all these Probably elements have the same type signature No, they've got to you you have to Animate that and here's actually I don't want to go into that Why you have a pure script is smart enough to be able to help That's from the context. You don't actually need to Say the test to is an element of the set characters that's it's gonna But for documentation just to get you used to writing things So I have here created two Examples two elements of the set character stats and I've done that by using the constructor function Call character stats which takes three things namely the name and the health and the speed and gives me an element of that set So now I pass one and that's two which are both elements of the character stats set Right there Alrighty, so We've constructed these things, but now we constructed elements into such character stats How are we going to extract out some stuff? That easy pattern it I'm gonna define a function called meme of which is We can go from the set character stats Do this at string It's gonna take something in characters that's In the name, I know I'm sorry in the first element. I'm gonna list that first element here I don't care about the second element of the product and I don't care about the third element of the product I'm gonna just be done or so there so many of those names and then over here the right hand side of the function I'm going to refer to the variables I introduce naming name. I'm just gonna return Is indentation significant here? Yes Here's where it is a white space that's in language. So indentation is simple So now I'm going to call name of on test one and I'm going to get back There you go This is the other way of running your script by the way inside your head Okay, so I've constructed elements of a new set of characters that's and I've extracted out elements of that You can sort of see how it works for the rest So we're gonna move on because we have a few more ever more interesting types to explore before we get to the heavy-duty stuff Comment characters here is going to be a dash dash. That's a single line comment But the multi-line comment is left early dash and then your comment followed by dash right So it's co-product types so This is allows us to create even more rich types of sets that we could base our functions on The co-product type We've already seen that actually seen that in almost the very first slide my definition of food and happiness we're both using sort of product in and co-product types and It's the pipe operator the pipe operator is used to create co-product and In this particular case, I'm creating a set called npc That's either gonna be one thing or another That I could be an over the non-player player character. It's gonna be an over who has a name and Location and maybe a health or it's gonna be a wolf who also has a name and location And every NPC is either going to be an overall wolf just like every food item my initial example Who's out of the egg or coffee and every happiness is either gonna be happy So that's the name of the type that I'm creating and in this case I'm not going to use that name as the name of any of my data constructors Because I want to introduce two data constructors because this is a co-product type So an NPC can either be an over or because the old wolf. It can't be both. It's one or the other so I'm going to use the names over and wolf as the name of my two data constructors So I'm introducing here two data constructors each one of which will give me an element in the set NPC So I use the over the instructor to give me an element in the NPC set That happens to me over and the wolf data instructor to get an element in the NPC set happens to be a wolf Could you also just create over and wolf as types and then data NPC equals over or wolf No Unfortunately that requires different types of But there are some programming languages that like And these are the constructor parameters just like you saw with the product when I call the wolf function to get myself an NPC I'm gonna have to supply three parameters. It's named its location It's not to get an NPC Do all constructors under the NPC have the same? You know, that's just sort of coincidence in this case But for example, maybe there's a big bad monster who doesn't need a name in my game Or who doesn't have a name and I just call the instructor big bad and that's it Or god god doesn't have a location. So just put it in here like god or over or wolf Okay, so that's how I constructed over or wolf But once I have an NPC and there's once I have an element in the NPC set How do they figure out what it is because they could be one of two things, right? And further like I might want to extract out one element of one pipe or at one branch Or a different element of a different branch the possibilities are endless and I do that can see pattern I've had pattern matching against the names of the data constructors So because I have two data constructors here, I create a function called name up. That's that's going to extract out the name From an old or horrible because they won't happen to have a name So similar syntax in this syntax that there is no easy way around you just have to sort of memorize it But do keep in mind that the syntax for The pattern I think is the same as the syntax for the construction So there's that synergy there. So whatever syntax you use specify the data constructors follow by all that junk Use over here that's by the data constructor and follow by all that junk And you get names of the slots inside of the project and keep in mind this is an example of something that is Either this or that's a co-product, but it's also a name and a location and numbers of each one of these are individual individually products And of course you can use this Monkey case NPC of expression type thing your switch if you will I'm supposed to do pattern catching They're both equivalent ways to do the same thing. You know C4 styles. You're sort of good basis Okay, we are ready to create some monsters here Because now we know some we have some time we make different types of monsters when we just do product types We were basically But now we have this wonderful thing called some type So we're gonna be different types of monsters and we're gonna make sure they share at least one common piece of information You can be wherever you want and we're gonna create a few monsters. So these different types of monsters And then we're gonna be a function that's going to extract that whatever it was We need common in all these different classes of monsters We're going to create a function to extract that let's go ahead and jump over here And the final function called monster it's gonna be either a werewolf And Or it's gonna be an amper and we'll say that amperes don't matter And then I'll create a function called extract man It's gonna map from the monster set The string set you give a monster. It's gonna spit out sort of being in the name I think this question was asked before but I'm not totally out of the answer So right now monster is a type and we have a type in structure called werewolf That takes a string and number what couldn't we also define a type called werewolf Whose type instructor was werewolf with a string and a number and then say data monster equals werewolf or a vampire string or Or just to clarify. Okay. I see what I see what you're saying Here's what we can do in this case. We could create a set called werewolf, right and maybe that werewolf Accepts a string and a number we have to provide that to the instructor. Yeah, and the set called vampire and A data instructor called the empire so he just called the empire to construct it and you just have to supply an amper And then down here we can do werewolf again remember This is where we're gonna run into some difficulty I'll call this make werewolf And I'll call this make vampire And you can sort of see the problem because I've already introduced a function called werewolf I'm gonna have to call one of these make werewolf or you know werewolf too or something like that And fundamentally You might do this when you're beginning just because I understand I used to do this myself but eventually you sort of Learn to embrace the idiomatic way of doing it. It cuts down on you, not the pattern of action. It doesn't really increase the types of But this is sort of the way we do this in an object-oriented program It's why I used to do this, you know, I would always back these things out and my instructor grammars and all the forms take one How long enough do you need to type? But you end up keeping up that pattern just because causing a lot of Yeah So in your original example, you're not Declaring a type on the right-hand side because it equals one period. That's correct Yes, these are functions. There's only one type here, and that is monster There's only one type and there are two ways to create that using the werewolf data to start through the vampire game Okay, and You try to build this here Yeah Yeah, if you need to be a multi-line mode if you're going to have to do a grapple Yeah, it's not the grapple. I just Usually it will do that if this is not the same as this That's what it's saying. They're origin type declaration. You need to do a pair of type which is a flat function for one minute Oh, yeah, so here's a type. There it is. Thanks Yep So you said it was able to improve that variable type, not variable, but the other type declaration Can they improve the function declaration as well? Yeah, it can only improve the type declaration and it improves it because if you can sort of improve yourself by Deleted this line here, and I said tell me what set grapple is an element out You look at this vampire here, and we go up and say oh vampires data constructed for the set a whole month Okay, so Yes, that's correct. Oh, yes Okay, so We'll briefly have one more thing and then we're going to take a break and come back in this writer types and If you're familiar with records in JavaScript, then you're gonna be right at home These are similar to structs in sort of C or C++ and similar to classes in object-oriented programming language So you're probably gonna have seen them before and pure scripts notion of records are actually matched with More with what a record is in those other programming languages That has to go through records which are really cool to take And and these records Here's your compiles just these records actually map into jobs or documents which makes very easy to the mirror up You can go through the code So here's how you introduce them the record type is technically everything including the curly braces And what you do in that record type is you define a world of pipes And you don't have to remember that probably gonna forget You don't even need to know it but technically everything right inside the parentheses But before you get to the even field to the record is called a world of cups and then you define pairs of things that look like this The pair of things in a label which is the name that appealed And that's great because up until now all our slots inside these data constructors have been anonymous and If I define like number and number in a row What's the first number? It could be elf or could be stamina or something the second number could be who knows what right? So what records allow you to do is have that same notion of That is you have all these different components at the supply of all the truck one But they are like to mean the individual components of that product And so here you give a label teach one of these and the type of the label So we say that name is an element of the set string and lock is an element of the set And help is an element of the set number and suddenly you can refer to all these things by names you construct them just using a Gromy Bray citation and We update this example Let me actually show you that here So let's say I want to give this Actually, let me just modify this. I'll give this werewolf the name and then I'll Give this a label so I can go for what we're a person and I can construct these things the syntax for construction It's gonna be almost certainly exactly what you expect to be if you're And as I use sort of Jason location here, and I'm constructing a value happens to be a record These two elements in it And that's how you do it and it allows you to clean them up You're suddenly able to get names for all different components of the product that is so actually a lot of people Prefer to use records, you know, I'm like here's great rather than Clients because here what's actually going on once you can get those individual slot names in Yeah, I was gonna ask So how does one decide or what are the advantages or the reasons why one might use a product rather than a record? So it mostly comes down to personal preference, but there is an advantage to using a product And I'll talk about that in the next section of it when it comes to partial application You don't actually have to supply all the parameters today I can structure at once you can supply sort of incrementally even into it You're familiar with query functions. That's what's going on here. That's really the only advantage and actually you can achieve something similar This will generate oh Yeah, the product as I say the reason to use records because the product will generate some of you And a record will generate pretty little in Dalas that other people can use that's a reason to use record Okay, so there's one more thing I want to show you this real quick and then we'll stop for a break and that is Okay, I can construct one of these things Well, what's the syntax that I use to extract out the elements once I have a record? And that's pretty straightforward and follows probably what you expect So what I'm saying here is The parentheses here what I'm saying is just like I created Dracula by building a record Using this syntax and using the data instructor vampire And what they're gonna look for See if a given monster is a vampire and then I use this pattern mentioned specifying the name of the data instructor here and also record the names here To the left of the colon operator have to be names inside the right They have to exist inside the right and then the names to the right are the things that you create So you're extracting up the name and you're giving it The name and you can refer to him on the right-hand side of the equals Yes If you try to leave this Yes You would complain before Oh, yes, yes, that's exactly right. So down here if I could try to really think bad and I forget it isn't the name then that's going to complain one because there's a discrepancy between the world data instructor accepts a Record that has an even health and I only provided it with a record that has health So the compiler is going to say we're going to feed that function something that's not in its domain You declare the domain to be the record that look like that you're feeding something. It's not it. Yes So it seems like when you define these extractor functions that they kind of it looks at a lot of repetitive typing It is there anything at all that can kind of reduce the repetition there while using No, not really However, there is for a record for the special case of a record there is a way to do that and Actually, that's the topic of the next section. I'll show you it's actually using the JavaScript operator So if you have a record and you can use stop me if you extract out the game or dot health They extract out that if you have a reference to a record But how do I imagine is how I did it here just to teach you how to use that? It has to be either a vampire or So if you if you just try to use like first off I have to You need something like our are not me. I think so Oh Yeah, because there's there's no way of You basically have to prove to the compiler that there is a name for each of these cases Theoretically, I think theoretically if we have constraints that I built we'd be able to I'm just trying to figure out what sort of type system in the it or feature of the type system allows right something like Oh Right, yeah, that's right. Yeah, so you could write a name up But here's here's the issue If I try to do the email you actually can't write this But if I try to do a name of and I'm passing that this is is like the actual type of this I'm going away. Actually, let's just declare break Right now Okay, we're gonna do a break back into it and What I'm going to show you now is a little bit syntax or working with record types So the first thing I want to show you is the dog right or and if you know Dallas You already know the dog or if you have a record You can extract out Different fields by using the dog So here I pattern match against my my NPC and my NPC is gonna be an overall wolf and I'm gonna call It's the value that I've supplied to the team of instructors. I'm gonna call it record Extract out the name deal the record in both cases by doing record dot So the dog operator we have a record the dog operator allows you to drill down into that record and extract out field Here's good also has some magical looking syntax or Updating records now I put updated quotes because your script is a pure political programming language which means that We call the function to give a value Terministically return the same value in total every single time you call it with that down And what that means is you can actually not a record you can't actually go into it and change its value Because to do that would violate the terminus It would violate the terminus because you could embed that function in another function and it mutates up for 30 different values every time you call So This version of updating records actually needs to create a copy with a certain modification or plot So in this particular case I Want to change the name of any NPC So I match against the two cases over a wall and if it's an over I'm going to construct a new over I Take event record and updating the name of each truck and the syntax is literally Your reference to the record space and then you put the fields you want to update in curly braces if you give them new values So everything's from over onward record the old Shrek is A record update syntax. It's a state the record called record in this case and Take the create a copy of it with the name change the track So this returns to the new record. It's completely identical to the old record Except for one change and that is the main deal has been changed In the same way for the second case down there. I take that record. It's a wolf and I I construct a new record with the name change today bad and then I Construct an NPC by feeding it to the wolf day of construction So I'm deconstructing on the pattern at the inside of the fence and I read Constructing on the definition side of the best the definition of that function I'm saying change the name of an over to an over I could have easily done it like change an over to be a wolf A wolf with an over and all kinds of other changes as well And finally I only get too much into depth right here But you're gonna see these weird looking underscores when you look at your script code And I don't even want to talk too much about what they do But basically there are shorthand ways for creating functions To either update a given field or update a given record or even update both the record and appeal at the same time and so when when you See one of these underscores base in the definition Just make a mention of yourself go look on like the piercer wiki or the piercer Now figure out what that syntax means that actually pretty straightforward So now what we're going to do is rework some of these examples because the early examples that you've created and you've been following along Have none use records and since we're hard to tell what's what's that slot number two You can have a game to give that slot number two five So now we have record types and we create records and again update records We have a means to more statistically Scribe these data types to names all the different fields and we're going to do that particularly the class called inventory item And let me walk you through this exercise. Basically. It's just create a Constructor that takes a single record and that record will have fields relative to inventory items that a player character Or a non-player character Timberbird inside a table. So that's the type That's not the name of my set and the name of my data constructor. It's gonna be But just to show you that these things really can't be different they're going to the head end of this What the heck oh, I'll call this looking by so the constructor is all invited by the set of values It's called inventory item And what should be inventory item now? We give a name, right? What else should we get a video weight? Maybe we add up the weights and slows our character down Maybe how many slots it takes up? If our character can only hold the equivalent of 20 slots then maybe some inventory out of take up one and something Okay, so leave her to support for you. This is that Called inventory item. This is a constructor called the invite That takes Something that has this type. What is this type? This is a record type Record type has three labels called being weight and slots, and they are up high string number in number Let me create a few inventory items. Yeah, I am bolder here It's gonna take all yours and Let's create like sword People is a they didn't call the this is actually a record and This actually has type This has this record type, but I don't want it to have that record type I wanted to be an inventory item So I have to call the inventory item in invited the structure on this record Get back a value of the inventory item type and the sword in the same way I've changed the map of the sword Okay, so that's record then if I want to take this sword and update it and I use the record updates syntax Actually, I'll have to do function like this. I'll say Make weakness My hope is called make weakness your mistakes Returns Not going to totally sketch out for you Just one case here Okay, I'll just do our when I'm asking for record I can do that. I don't have to manage against fields in the record I can give the whole record a name because records are first class thing in your trip I can just give the whole record a name called our And I can say for renewing for item By taking that record and updating the weight And then I would take my dime holder You can call that anything that you want I tend to use very short variable names And that's happened to probably eventually fall into if you stick with a static type programming language Like your script long after all actually you chore or variable names because you'll start to learn the read the types and rely more on the types Okay, so now I have this wonderful function that you need to do for item weakness and it can work with Any record in this one Right Yeah Yeah, first we'll infer it again. I heard you not being in management that feature because it's working through the thing will teach you It's you a lot of out from how your support was in force you to keep the slice of things But yeah, I don't actually have to do that It's probably how you do it for now You're super comfortable with that and then you can start omitting all these sites. I can like go with the leap all these sites here Your trip will be this is fine And I'm sort of like God was here if you do that, but oh my god It's your compiler to watch the time when you get something wrong Or at least certain classes Okay So now we're going to go back to something that You've seen all along and it's basic function types a function types I introduced in almost the very first line and You introduced them using that arrow It's that arrow which looks just like the illustration of a function that I had up there at the beginning and it basically says that is an element of of the set of functions for monsters of favorite food Yeah, I didn't talk about it that way before I before I talked about as fave is A function from monster to favorite food. That's true, too but another way to do this is that Monster to favorite food is a pipe And as you all know types are sets And therefore what I've just described here by writing this notation monster arrow favorite food is this set Of all functions That map from monsters to favorite food And I'm saying that fave is actually a value. It's a value That is an element of the set of functions that map from monster to favorite food So notice how subtle that is that's an extremely subtle difference that you might not even pick up on unless you're paying extreme attention but I've gone from describing fave as a function from monster to favorite food to being a value Of a set of functions for monster to favorite food And it seems seems simple, but if you can wrap your head around that concept that You have sets can't contain functions. They can't contain all kinds of functions crazy functions in there Like I said, we're building upon the complexity of the things that sets can't contain And we're we're we're going to have to do very very soon a nice slide or two Stop viewing fave as a function so much as a value of a set of functions. Does that make sense? Okay, so here it is in fact There is a way that you can Define functions Without sort of listing the elements in your domain on the left hand side of the equal up till now We've been doing things like fave of giants is humans and fave of alien is kittens And it's sort of like we List the name of the function and then the element in the domain and we say what element What that maps to as a codomate what the function maps it to the codomate and Thinking about this more thinking fave more as a value In the set of functions that map from all uncertainty food There's actually a syntax that allows you to create a function as a value And that's exactly the equivalent to This definition of fave That syntax is you use backslash And the backslash is a four man's landup Hence land up land up Be an inline functions that slide at the value level And that maps from monster and then I need the arrow sign and I'm going to list other stuff in here now How would I do this? Well, I have to use a case expression that's other way Out of magic that I showed you earlier on I'd have to say monster maps to case monster of And finally Define what the function was equal to in those cases And of course if you know JavaScript you already know how to do this in Kernberg you know JavaScript You just do a bar fave and then you assign it to this anonymous function This anonymous function thing is actually a lamp and it's a value. It is a function that is a value And So let's create a function from monster's total hit points Express the same function as a lambda and apply the function in various inputs We're gonna go super fast here because we need a bigger base to cover All the stuff I want to never express this same function as a lambda using that's an accident to show you Remember the other way of reading this hit points function. I'll call it hit points Is it's just a value it's a value that happens to be a function that is it's a value whose type Is this set of functions from monster the numbers if you picture a set here and lots of functions being jammed into the set And every function looks sort of the same. They all look like they accept the monster and they return them on And this set which contains all these functions We're saying hit points prime is an element of that set if one of those functions that maps from monster We're just going to use equals on peruse a m for monster And i'm going to do a case m of werewolf maps 10 maps 100 And then we're able to call Hit points is a value that happens to be All that on werewolf so The most important thing to remember From this lesson is that Functions are just values or values That happen to be elements of a different set of much more complicated Any set that we've seen today And those sets are about getting more complicated. They're fundamentally every every function is still a map from one set To another set it's just a structure of things inside those Sets in the simple type we've seen before it can be complex But fundamentally functional programming is all about mapping from one set to another We're going to cover this briefly because it allows you to clean up some of your stuff You've noticed that uh with a record type Actually, even with the product type i've had to repeat myself several times Like for example when i was talking about Ogre and wolf I decided to give them both names and what cables are not And that's where repetition And it gets old after a while and one of the ways that you can reduce that warwick life is you can give a name to a type And so here i'm giving a name to this type called char data It's just a type title is there's a different name to refer to the type i And every time the compiler sees a char data it's going to look over on the right hand side and say What does that rule mean? What does that mean? And here i've introduced a record type that has three fields called main lock welcome help And um now i can define ogre and wolf by saying well an mpc is either an ogre that accepts char data Or it's a wolf that accepts char data and char data is just a record and those record tabs will be the same So you can take out all that duplication that was there before and Back throughout they might go easier to understand and maintain Now when i add a new new type of thing to char data I don't have to update the definition of mpc and it will just be there So it's a good coding i've used type aliases wherever you have duplication at the level of types i need sets And then there's one more common thing that you're going to see in the code that i'll cover briefly And that's a new type A new type there's no difference honestly in a new type and a data while there's two differences, but they're very minor The differences are as follows New type Can only your constructor for new type health in this case can only accept a single parameter And the other difference is using new types as zero or unclined overhead Why is that important? Well it allows it to take something like a number and call that a health Without sort of having The runtime overhead Unboxing a number into a health data structure every single time And so it encourages you to just instead of passing around like number number number in your functions To give those types like health and strength and stamina itself, which are really just numbers Right, but so this It's not exactly an alias because new types actually do have a new type That is a compiler will treat them when it's compiling it down and checking for type barriers and stuff It's going to treat them as a thing out of a unique type that is a health is not a number Those are two different sets and I can't feed a health to something expecting the number And I can't feed a number to something expecting the health But at runtime that is after the compiler has has got done with feeding you over the head with a stick It's going to ultimately Represent this at runtime with an ordinary number and it's not going to have any additional runtime overhead You shouldn't be scared of using new types And then that's where their limitation Accepting a single parameter comes from because fundamentally whatever parameter they accept that's exactly how they're represented So here I create and I should have done this earlier and I would have if we had new types I create a new type for health because I honestly you go on just pass number around and I can just Create a new type all out and pass out around the way you go to maintain the code that I wrote You'll look at that and you'll say oh, that's a health. That's not a random number. It's not strange That's that's You cannot You cannot add to else because the addition operator expects two numbers And new types are humanly you types Now That's a topic for a different glass okay, so You can deconstruct them and you can pattern match on new types because if they were ordinary data in fact What I do when I'm backing stuff is I start off with a new type And and if it has if it ends up being more parameters than one then it ends up evolving into data But you don't really need to update your code That is you can take any new type and swap in data if you weren't there if your code worked just fine It would just be slow Yeah Why is it health supports things like Comparisons but doesn't support plus. I don't know why that would be So it actually does not support Comparisons either but that's excellent question What I do even is a live function is I'm extracting out that value in the first slot from health which happens to be in them So I pattern matching on that health data constructor And I'm extracting out the thing in its first slot and I'm saying call that v Extract it out and call it v and that that's a number and then I was saying v is greater than zero Okay, so I'm Comparing the number Against zero but if I were to just say, you know is a live v equals v is greater than zero and if your script go by over there Hey, hey, I don't know if you're talking about here health doesn't have any such operators greater than defined Okay, so Let's quickly run through this exercise. We're going to create a record Hi, so we're going to use everything we introduced today. We're going to create a type alias It's just going to be a name Remember type alias is different for new types and that type alias is they're just another name for the type and new types actually are new types um We're created a name For a record called magical light of wreck and it's going to have several fields. This is a magical light so they like Walk on or something And we're going to use this type alias to define a new type called magical light of whose constructor is called magical And we're going to create some values of this and maybe a few functions to extract out the fields and have natural light So what is this look like? You know ideal is magical item record Maybe it can poison someone So we're going to allow for that possibility. Maybe you can heal someone and maybe you can damage them So type alias or this record type here I mean, anytime I use this your script from college is going to say, oh, I know that's just an alias You know new type all magical item It's going to have a data constructor all magical item It's going to accept one parameter. That's the limitation of new type. Remember It's magical item right and now I'm going to create Create one of these things I'll say one Is a magical item and one I'd have to use Remember, there's the same as a data constructor except there's no runtime overhead and I'm really just the number of parameters I can have here I have to use this constructor called magical item and feed it what it expects. What does it expect? Well Look at that type alias. It's just a record of three fields So a one is not a one but say yields And a one can also do damage serious And uh That's all there is to creating one of these things and it's similar when I want to Extract things out. I extracted just an outer match on just like a little data Let me just show you that It's going to take a magical item And tell me how much poison is poison so If I am And then my record is r. I'll just call it r. I can actually extract down the pf that I want But that's too cumbersome. Don't you do that? I just want to do r dot I hope everyone does that Respond to the line Okay, higher kind of functions things are about to get real very real fast and The key thing keep in mind, you know, all old onto is tight as you can and you feel like getting lost is Everything's a function. Everything is a mapping from one set Just hold on that dot, but I'll complicate it Higher kind of functions. Well, I've already explained that sets can have functions that can contain functions Well, that means functions, which are mappings between sets in math from sets of functions to sets of functions Sort of a mind-blowing concept if you grew up as a cc programmer Like I did it's sort of a mind-blowing concept when you run into that. It's like It should be obvious that you've been programming a certain way for Many many years decades. You lose sort of sight of what is Intuitive and consistent anymore and you find this concept truly mind-blowing But funnily sets are mappings between or functions are mappings between sets so your domain can itself be a set of functions And your co-domain can be sets of functions. You can actually have functions that map between the functions to sets of functions Here's the example of a function that accepts a function So this function accepts a function like all that in this example And it's going to test that function. It's going to see if that function Accepts a string and returns a boolean. So if your co-domain is a set of all functions that accept a string and return a boolean and How can we interpret this? Well, here's the intuition the set of all functions that accept this string and return a boolean That's sort of like saying does that function like this string or not? Does it like it? Yeah, it returns to true. Does it not like it? No, it returns to false So, um, this is the set of all functions That are able to render a value judgment on whether or not they like to get a string. So, um, what I do here is I give this function following type signature It's going to accept a function. So I close this in parentheses and I say, um, this is a type Ordinary type. This is a type of set of functions that accept a string or a boolean And I'm going to say my function likes empty string picks one of those functions and it returns a boolean And it's actually what this is saying is, um, likes empty string is going to test You can feed it any function. That is, you can feed it any element of the set of functions from string to boolean It can feed any function at all that renders a value judgment on strings And likes empty string is going to test that function on the empty string to see if that function likes the empty string So how do I implement this? Well, let's pretty straightforward. I just call that function on the empty string Right away and I'm going to get back to or false. So if I want to test the function to see whether or not the likes or hates Uh, the empty string, I'm going to feed it to my likes empty String function and I'm going to get back either true or false to see whether or not I like it so This builds upon what we've learned so far, but it is possibly getting a little bit harder to understand here because when passing the likes empty string Is it's not strings anymore booleans or monsters or NPCs or magical items I'm actually passing functions to it and then it's returning a boolean Well, what is it doing with those functions? Well, in this case, it's testing it against the empty string so likes empty string It doesn't break the add and we want it so far It's a mapping from one set to another set. It's domain is a set of functions from string boolean so domain is boolean Yes, it's significant that these are called player clanded as opposed to higher order functions Sorry, it should be higher order functions It's similar, but I'll get into that in a second. It should be called higher order functions okay, so If a function The functions domain can be a set of functions. Well, so also functions co-loaning can be a set of functions In other words, I can return a function from a function And in this case, I create a function called matches that's going to take a string And it's going to return a function That tells me If another string matches that string that I forgot Does that make sense? So for example, I want to match her right that is on a function that's going to tell me if I give him a string matches some pattern And I want to match her for the phrase evil So I call my matches function with evil And matches the domain is a set of strings So I'm going to feed in this evil string to my function and it's going to take this and it's going to return another function That's going to tell me If a feed that I string it to matches evil So I create this matches evil function by passing in a string evil to this higher order function matches Which returns another function. So matches evil here is a function Matches evil is a function that takes a string and returns a movement out And then I test my function called matches evil against John and evil Donna returns false evil and returns So this was a function that told me that I accepted a function and returned a value of an ordinary simple value And this was a function that took ordinary simple value And returned a function and he has to be combined in arbitrary ways And yes, as you start combining them, they do get harder to understand and now We can see how pure script supports multi-turning their functions So a function like damage mpc means to take Number of hit points how much to damage the non-player character by or reduces health by that specified And it takes the mpc and returns a new mpc With that mpc damaged by the specified number of hit points So it takes two things right in Donna's script We would say this function takes two things it takes the hit points and the mpc and returns the mpc damaged by the hit points We would say that Donna's In pure script everyone says things multi-parameter functions This is damage mpc is a Function that includes a function And that generalizes to any number of parameters In fact, if we have a big old long function called f And and you see that someone's feeding an a b c d e Well, you can think of that as being one two three four five parameters fed to the function f But again pure script has has no answer for the multi-parameter functions Everything is a function that is a mapping from one set to another And how this happens to be is f of a into another function that you apply to b Which gets you another function that you apply to c which gets you another function to apply to b Which gets you another function that you apply to e and finally get that value And you're going to see type declarations that look like this f has after the preceding example has this type declaration it says a b c a b c d b In that order all separated by arrows How do you interpret that well if you want to think about it in multi-parameter terms you can think about it as This function f takes an a and a b and a c and a b in terms of e It takes four parameters to first one But what that really is and and how you will think about that sometimes is let that parentheses everywhere And apply over at the parentheses and we see that you feed out an a and you get back another function Or does that function where you feed a b and you get back another function? Or does that function where you feed it a c you get back another function? Feed that b finally you get back in So there's only one concept of function if you're there and it's a mapping between delay and code only Just that this sort of sets Involved here can give you sets of functions And these are all the different ways that you can write the function They have to be seen using lambda to see the word sort of pattern actually And they are many and you'll you'll see them all from time to time make different ways of writing this have certain pros and cons So we are unfortunately out of time. I mean a lot slower than I hoped to get through But we have covered almost Almost everything that you need to work on the example code Yeah, uh, yeah I would wait slower than I thought but we covered almost everything you can skip this off on higher kind of types for now We covered almost this up on polymorphism is important It's been a few minutes reading through that all the materials online. So you can go ahead and finish up this workshop on your own Parametric polymorphism is a very important concept And if you've only done programming and something like Ruby or or JavaScript, it's going to be totally boring for you So read that check that out and then download the code the code Actually requires that you can pull in a record that has this type signature here that I've shown here and Here's what you have to do to implement a game everything else is going to build around this So your only job is to implement this function here or implement a value of this type of record You have to specify the initial game state the game state thing Who did he want so you could put a map in there to put some characters in there or whatever you like You have to be able to describe the game state So you have to be able to determine that game state and do a string that the user will see And you have to be able to personally what actually I did that for you You want you don't have to do that and finally you have to be able to Give them an input from the user like maybe they want to quit or they want to move Move in order or they want to drop something or pick up something You have to be able to translate that into an either an error message Saying I don't know how to handle that or into a new value for that game state So the core of this game loop is essentially a function from game state to new game state Give it some input And you can put that function it's already implemented but it adds stuff to it You can actually build a very useful game without too much work and that's that's pure There was facts there. It's everything's a little complicated So thank you for attending my workshop. I'm sorry. You didn't get to all the material I'm going to let you see that on your own and please let me know If I owe you a copy or not because I will make good on that promise. Thank you very much