 with Scala in 2008. I mean, we didn't have even the book. I have to learn from the language specification. And after, I mean, after years of Java, that was, anyway, that was really cool, the new languages. And obviously, the object orientation part of Scala led better Java. It was fine by me. I can get it very easily. But the functional part, it was different, kind of complicated. But it was fascinating for me. I mean, I kind of fascinated by the functional programming. And when you start functional programming, you start, everybody starts mentioning Haskell. And we start looking into Haskell. You start seeing weird things. You never saw people talk about, like, things that sounds really weird. That's how people start mentioning category theory. And when you go anywhere, try to find out, I mean, any book or reference about category theory, especially like Wikipedia, you read Wikipedia. And if you don't know the, if you don't know what you're reading, you don't understand it. If you know it, it's perfect. It's easy. But if you're trying to learn, that is, like, totally unscrewdable. So, but for starters, what's the most important technique for programming, what do you think? But, yeah. But for me, I started with abstraction. And I will address composition later. Why, um, what is category theory? It's abstraction taken to the max. Extraction to 11. This is category theory. You remove everything. But something that is really, really abstract that Matichan's invented to get away from, you have the set theory, but you have this, like, the Russell paradoxes and they try to create, like, a new theory to explain the mathematics without getting those paradoxes. That's fine. But the stretching and the fascinating for me is, like, all this, this thing that they invented, like, direct application for programming. And obviously, if you go try to understand what is, what is around, having the basic vocabulary allows you to go a lot. I mean, like, starting from scratch, trying to crack that thing is, at least for me, it was really difficult until I had, I was lucky enough to take, like, one semester back in my university. And it wasn't, but that wasn't so difficult because somebody was explaining to me in words I can understand. Okay. This is, so the basic thing is what's a category? Yeah, the very abstract term is, like, things and connections means things. And that's it, that's it. And because we don't care about what real, really the things are, we really care about the connections, about the structure of the things. What we ask for a category, to have a category, is those connections, I have, I need to have two things. Identity, like, every object is connected by itself. And composition means if I have this connection and that connection, it's the same as having that connection. That's the only thing we want in a category. If you want to have that connection. So, formally, we have a, a category is a collection of objects and a collection of arrows or morphisms, morphisms, that for each pair of objects of the category, f from a to b means f belongs to the set of arrows from one object from a to b. That's basically, like, formally saying what I already say in other words. Composition, if I have one arrow that goes from one note, from a to b, another arrow that goes from b to c, then the composition goes from a to c and exists. Again, as for the identity, that means there exists an arrow that goes from any object to any other, to the same object. There's a couple of laws we had to, to abide. Basically, and this kind of moral laws are, like, it, from the definition, they, they can be easily deducted. But basically, if it doesn't matter where you compose the identity, you know, it always does anything, that's nothing. You always add f composed with identity, give you f or d, d in the other, in a, in b composed with f, also gives you the same f. And the composition is associative, it doesn't matter if you compose first one or the other, it's the same. But again, why does matter what is useful? And the thing is the most useful approach is, okay, this is my functional program. We have my types, high functions between those types. And the interesting idea is use a category to model, model that. It's kind of a flow. So I think the most interesting results from category theory are when we take the types as the objects and the functions as the arrows. They have, we have disclaimer. Some restriction may apply. It's valid only when the functions are total. Results are valid in the context of fast and loose reasoning is morally correct. What that means? All this applies when you ignore things like exceptions, non-termination, null. So it's an ideal world of pure functions that are total. But there is a paper that's called fast and loose reasoning is morally correct that takes the hard work of mapping, it's applied to Haskell. It takes the hard work of mapping like the ideal category and like a real world and trying to reason why the results are still valid. That's why this is the name of the paper and that's why you, sometimes you hear about the morally correct reasoning in functional programming. That's a little more. We have more things in our category. There is sometimes, not all categories, but some categories have initial objects. That means for every object they have in my category there's only one arrow that goes from that object to that, from the initial object to any other object. Conversely, I have the final object from every object that is a unique arrow that goes to the final object. That's why the name. And the interesting thing is in our previous category, in our category of types and functions, nothing is our initial object and unit is our final object. It means I cannot have a function, like a total function that goes, any function that goes from nothing to any type is unique. And again, all the functions that go to that end that results unique are unique. But I mean, there is not the only category we can build with our programs. Actually, I got this example yesterday when Stephen talked about this function. You can take the objects against our types. Our arrows are extends or width. Basically, it's like a hierarchy of types, the extension, like some types and objects. As a category, you have the entity that, again, a type is kind of, can be substituted by itself. And again, if I have the composition, means I have one type that can be replaced. If I have a key that can replace B and B can replace C, then A can replace C. And if you remember, the Scala object hierarchy or initial object will be any or no final object will be nothing. That makes sense? Yeah. That's what I think I wanted to show. If you are thinking of types and functions, your initial object is nothing. And your final object is a unit because you are in the categories, objects and functions. And basically, if you think a function, a total function cannot return nothing. You cannot build an arrow from A to zero. But this is a different category. So in this case, nothing is our final object that can replace the subtype of all the other objects. Also, it's interesting, if you take a category and reverse all the arrows, actually the result not only makes sense, the result is another category. And it's called the dual category. And usually they put code before. And it's the basic of understanding everything that says code, like code product, let's say. I have different examples. Well, monad and monad. I didn't want to mention monad because I didn't want to say much about that. But every time you see code, it means the same category, the dual category, you reverse the arrows. And again, it's another category. So all the category results apply. We have more things. And all of these things make sense because they are, first they are applied directly to our modeling of programming languages. And they are used a lot in the, like in the literature and everybody, if you start looking about functional programming, a product. Basically, you take two objects from the category, you match it together. And you get, to be a product, you need two functions to extract the values of that product. And there is, to be a real product, it has to certify this property. That means this arrow will be unique. And basically the composition of that unique arrow with the projections will give you the initial function. That's totally mathematical construct. But actually, any time you're using multiple parameters in a type, you're using a product. That's why it's called a product. Here it's like any P whatever. If you have two parameters, it's kind of what we're trying to do. But in Scala, the case class, P.A and P.B will be your projections. This is, I didn't say this is called projections. A tuple also is, even if you look around to the tuple, it's called problem. But also, I mean, because, I mean, adding to the list, it's also a problem because you have one type and one side, another type and the other side. Doesn't make sense? Okay. What part? Everything? Yeah, sorry. Projectors are just these two arrows. Like, you get the product and you have the one projection will extract one of your original values and their projection will suck the other value. Yeah. Okay, you can think. Yeah. I need to probably, I'm trying to not to say anything wrong, but if you think in the database relational model, a selection is a projection. Also the scope, even in the relational theorem, it's called a projection. Basically it's a product of A and B. A cross B. Yeah, A cross B, whatever. The cross B. I mean, this is really, really abstract. I mean, in the, I think if you, I don't know, model category, vectors with categories that you have the vector product or if you have numbers, this is like multiplication, but not exactly that, but basically anytime, I mean, in other languages like Topo, it's called a product also. Well, now, if I say now, after this, it comes the coproduct. What do you think it will look? Yes. That's the thing. Okay, let's say coproduct is called, do a category, let's reverse the arrows. Everything reverse. Will it make sense? I mean, let's see. Here we reverse everything. Out of the projections, we have the injections. These arrows are called injections. Again, we have F and G, but now they are reversed. Yeah, and then we have the, like the unique arrow that makes things. So again, we have our coproduct that is sometimes called zoom. With our injections, that satisfies that now the injection is in the other side to make, to match the types. So basically it's our unique arrow composed with an injection. It gives you your original. In Scala, it's, again, the, it can be either, in this case it's like our own implementation, but basically it's alternative. Either in this case it's our coproduct, one side holds the A and the other side holds the B. But it's how we represent, they call, even if you look in, like in other types, they call this some type. Sometimes you have heard the complaint that Scala doesn't support that proper some types. And also, again, in Scala C it's called the disjunction, because basically it's like a disjunction union. And the fine kind of, it's interesting that just by reversing across, you got something different that is really, that makes sense. Makes sense? Actually coproduct is more, kind of, it's more in the sense like you have, it's like the dual of the product. And probably I think some, I don't really know why they use some, probably it's my historical reasons. They try to explain this and this and this is the sum, but I don't have any. So now to the famous funders. How many hear about, hear about funders? How many know what they are? Okay, okay, at least lots of people hear about funders and, again, we have people like, they're sure what they are. So if you go and try to read about, like, what are funders in category theory, you can hear about the structure preserving mapping between categories. It's like, what? Yeah. So let's try to find out what that means. We have, in a category we have objects and functions, so if we have, we want to map, we need to map the objects and we need to map the functions. We need to present the structure, but what structure do we have in a category? We didn't say much about what, but we only have identity and composition. So, I mean, the mapping of any function must match, obviously, the types of the function, types. I mean, the initial, I mean, the mapping of the function, the mapping function must start in the initial object, the mapping of that object, and the mapping of the final of the other object. That's, I mean, I'm not going to move the arrows to any other place. The arrows will travel with the objects in the mapping, and I need to, my identity in any object must be the, the identity in the map as object, and I need also to keep the map of the composition. So the map of two composite functions must be the composition of the map of each function. This is kind of formally what the Fonter does, and you know, have you ever think, have you ever read about implementing a Fonter, especially if you read about Haskell, they talk about the Fonter laws, Fonter laws, and if you implement a Fonter, you basically need to comply with these two things, preserve the identity, preserve the composition. So, but if you start reading about Fonter, you have about end of Fonter, and how Amona is just a, Amona in the category of end of Fonter. The thing is, end of Fonter is just Fonter's where the source and target categories of Fonter, where the mapping goes to the same category. And if we're talking about programming and trying to model our programs with Fonter's, this is the monetizing Fonter's, because we apply a Fonter, and we still have programs and types. If not, we're just moving to, I don't know, to the world. Yeah, I mean, we're dealing, what I'm thinking is, you can model, you can create a Fonter from your category in your program to a category of chairs and connections between chairs and people that use the chairs, but it's not really interesting because you're already out of programming then. But here is when it gets interesting. Type constructor is actually end of Fonter. Basically, let's say I have my program, types, functions that go between types, and now I want to, instead of using the, instead of using just returning the direct types, now my functions are options because it might return known. And I want to write on my program using options instead of just using the types. Well, the structure is kind of the same. This is our, this is, you have already said that this is a category, and that looks like another category. There are two categories, I mean, there are the same category in types to types and functions. So, here we can use an end of Fonter. Or again, they want to use the future. Maybe all my functions are asynchronous. And I want that program when I have this. And I don't want to rewrite everything. So, category theory to the rescue. I want to use end of Fonter. I got, I need to create my Fonter. So, okay, I say that the option is that the type constructor is the mapping of the projects. But it makes sense if I take any type and apply the option constructor, I get option, the string and option the end from string and end. But now what we do with the function, I have a function that goes from string to end. I need one function that goes from option to string to option to end. Well, true, but I'm talking about the category where morphisms are the functions. Total functions, so I don't have any non-terminating problem. Our objects are the types. So, really, I have a function from A to B. And I want to create a function from option to A to option to B. Does anybody see where it's going, this? Really, if I put everything in one signature, I have one function A to B and I need to return a function that goes from option to A to option to B. So, if I generalize that, I get any, I have a function from again A to B and I need to return F to A to F to B. Doesn't anybody recognize this signature? Exactly. Bingo. F map. Well, in Scala, it's a little more horrible. But that's the famous F map where you take one function and something inside a type and it gets you, that applies the function to the object you have inside. And that's the good thing for me is, like, you have an F map, you know what you have to implement, but it has a whole explanation of why it has that signature. One second because when it comes later, it's more complicated. So, what do you think? Does it make sense for the map? Any questions? Complaints? Yeah, I only explained this F map, only maps the functions, right? What happened with the objects? Well, that's, again, if you see, like, the type class or whatever, nobody tells you. Actually, you are, if you have the type constructor, it's your mapping of the objects. I mean, if you have an option, the option already tells you how to create an option of any type. And this is your mapping of the object. What gets complicated is how you map the functions. And if you think, obviously, the Funtor type class, if you can instantiate that, if you want to go to create a special particular instance of that type class, that means you already have this one. You don't really need to provide the, how to map the functions. Actually, Funtors are one of the most interesting things, because with that, you move from one category to another. And if you are in the same category, we are in the Funtors. It's the one who allows you to work with type constructors. Like any, basically any higher-order type is a Funtor. Network transformations are really interesting too, because it allows you to move from Funtors to Funtors to Funtors. Obviously, it's kind of, you can create, if you think Funtors are your objects, network transformations are the arrows of that category. In category theory, everything forms a category and then you can reapply the same reasoning. This part is really abstract, but if you have like a family for any two Funtors that goes from one category to another, if you have a family of arrows that goes from one element of the Funtor to the other Funtor, that's called a natural transformation. And the really important thing is this part, that that diagram is called commute. Everything in category theory is kind of proved with diagrams. And if the diagram commutes, you have like an equality. And this is totally abstract, but if you have this, suppose you have at least a sequence of elements and you want the map about this, you want the map in that sequence. You have a function that goes to another Funtor, let's say head-option, that results, take a sequence that results in an option and you want to apply the same function, the same map. And then you start with a sequence of A and ends with an option of B. The important thing is that because it commutes because it's a natural transformation, you have that head-option of map of the sequence, of mapping the sequence. It's the same thing as mapping after getting the head-option. That means if you can basically that, in this one, you don't go through all the lists. This is like more efficient and is there equal? In a sense, it gives you the same result. I mean, you can have like the right rules about this. And the thing about natural transformations, it gives you something called parametricity that basically because the A and B are, I mean, really anything, you got to think of, basically the functions doesn't need to know about what is really happening inside. There's a paper that's called the free theorems that has many results about parametricity, kind of like if you take the reverse, I mean, if you map something and then do the reverse, it's the same that reversing and then map or map concatenation of two lists is the same of mapping in each list and concatenate. And it seems, the result seems like reasonable, but the real certification explanation is because of that kind of diagram, parametricity. Well, after all this, come question. It's called, even the people who do category theory, they go abstract nonsense, but it's really abstract. But if you start reading about functional programming, for me, the fascinating thing is like all those things are really, really abstract. Actually, you have to implement it straightforwardly in your code. And you get interesting results. When you say about the abstraction and composition, in category theory, it's so abstract, the only thing you have is composition. So that's why it's like also such an important thing. Well, if I haven't made you sleep, when you start, I've been looking at different books about category theory, and most of the times you start reading the first couple of pages and then start talking about very good stuff. I mean, all the examples are from mathematics, and it's fine, but sometimes you're looking for something really straightforward. One thing I found, this is like an undergraduate thesis from one guy. I thought that really goes directly to mapping, basically maps category theory to Haskell and Agda. I will read in this book, this is available also on the web. This is interesting, it's more like it goes more deep and has more examples, but it's kind of more complicated. There's a lot of books about category theory, but this is kind of my recommendations. Thank you. At least you did it right away.