 Hi everybody. I'm Anjana Vakil. Hello. You can find me on Twitter at Anjana Vakil. That has links to my various other online presences. And today we're gonna talk about lambdas. We're gonna get into why this is not going to be a programming talk, really. And it's definitely not an AWS talk. It's kind of a talk about a really, I think, really fun and really interesting and really beautiful theoretical construct that allows us to simulate computation. And yeah, it's gonna be kind of fun, kind of silly, not practical at all. So buckle up. Really quickly, I'm Anjana. Hello. I work for a company called Uber Research. No affiliation. And we work with data on science research funding, so kind of where the money goes in the process of science. And I work on building a domain-specific language to query that data. And we do lots of other cool stuff. And we're actually hiring right now for, especially for a web developer, if you like working with Pyramid, come talk to me. I'm also an alum of a couple really great organizations that have helped me wrap my head around both things like the Lambda Calculus and things like Python. One is the Recurs Center. It's a programming retreat, like a writer's retreat, but for coders in New York City. Absolutely fantastic, self-directed program. And another is Outreachee, which is a really incredible initiative to get more women and underrepresented folks involved in open source by offering paid remote internships at open source organizations like Mozilla, which is where I did my internship and I'm still involved with Mozilla as a volunteer with the Mozilla tech speakers. So I'm more than happy to chat about any of those things. If you're curious about any of the stuff I just mentioned, come grab me afterwards. One other important thing to know about me, I like emoji and I like writing silly code poems about the Lambda Calculus. I wrote you a poem. It goes, Mary had a little Lambda, a function pure as snow. For every program that Mary wrote, the Lambda was all she needed to know. Where's my thunderous applause? I'm just kidding. I'm just kidding. I know it's not a very good poem. That's why I write software for a living. But this is what's cool about the Lambda. And we're going to see in a minute how it works. But basically, the Lambda Calculus gives us a way of representing pretty much all computation, anything that like a Turing machine could do with just a tiny little pure function. So the Lambda Calculus, let me zoom out so you can see that. Okay, the Lambda Calculus. And if you've seen Lambda represented as this Greek symbol, that's because that's what the name of that Greek symbol is called. You might recognize it from the logo of every functional programming language ever. It's basically a kind of mathematical or perhaps logical formalism. It's kind of a system that this guy who looks super fun to hang out with Alonzo Church is his name. And starting in the early 1930s, he started developing this system as a way of trying to understand the theoretical foundations of logic and math. And he fell down a like crazy big wormhole with it. And we're only going to scratch the very, very surface of that wormhole. But there's like, you could spend your entire life playing with this stuff. So we're going to spend about 40 more minutes doing it. It's as I said, it can serve as a universal model of computation, meaning that it's Turing complete. So no big deal, whatever. We can just model pretty much anything computable with a tiny little Lambda, which we're going to explain what that is in a minute. And just as a side note, it comes in some varieties, you have options, there's an untyped variety and simply the typed variety, we're only going to be talking about untyped Lambda calculus today. Okay, so that's tiny. Can we see that better? Okay. So a quick note on the difference between Lambda in the Greek symbol Lambda calculus sense of the word and Lambda in the Python keyword that you probably all know and love sense of the word. So the Python keyword is great. It's really practical. We can use it in our Python to like write programs. The Lambda calculus is not for writing programs. This is why this is not actually a programming talk. It's for thinking. It's for reasoning and like trying to understand and get to the bottom of things and trying to make proofs and assertions about what we know about logic and math. And those are two very different things. So let's just keep that in mind. As I said, not a practical talk, you're not going to learn anything today that you can let go using your job tomorrow. So let's talk about pure functions. So a pure function is a function that has no side effects. In the Lambda calculus, there is like no way know how are you going to have a side effect in your function. A side effect is something that the function does that is other than just returning its return value. So for example, in lambdas in Python, you can do things like you could say, Lambda X print X, you could print it out to your screen. That's not returning anything useful. It's returning none. That's a side effect. And we cannot have that in the Lambda calculus, but it's fine with lambdas in Python. So we're going to ignore that feature of lambdas. Another thing is that lambdas in the Lambda calculus have exactly one input. It's like a pure function that takes exactly one input and returns exactly one output. Whereas as we know in Python, we can use Lambda with like multiple variables, we can return like a tuple of multiple outputs. So we have a lot more flexibility there. When we make a function in both the Lambda calculus and in Python, it looks kind of similar. It's just that the syntax is different. So in the Lambda calculus, we'd call function abstraction, the act of sort of what we would in Python say declaring a function. In the Lambda calculus, if you see on the left hand side, that's represented by the Lambda symbol. And then a symbol that stands for the input variable. So in this case, X. Then you have a dot. And that's kind of like the colon in Python between Lambda X and the body of the function. And the body of the function comes to the right of the dot. So Lambda symbol X dot X is equivalent to in Python, Lambda space X colon X on board so far. Cool. Okay. If we as we said, the Lambda calculus functions can only take one input. So if we want a function that like we want to pretend takes more than one input, we have to basically take the first input, let's say X, and then return a new function because everything is functions, return a new function that takes the second input Y and then does something with both of them. So this the second row after making one abstraction there on the left hand side, this would be a way of representing kind of a two parameter function in the Lambda calculus, Lambda X dot Lambda Y dot body. So X plus Y, for example. And in Python, remember, we have options, we can actually create a single Lambda that takes two arguments and does something with them. But here we're going to be restricting ourselves to just one argument per Lambda. So we're going to be writing functions like this, Lambda X colon Lambda Y colon body. Yeah. And then once we've got a function, we've made one by abstraction or by definition in Python, we can use it by application, which is what we would call in programming like calling the function. And this looks pretty similar. It's just got an extra pair of parentheses on the Python side of things. In the Lambda calculus function application is just the function that you want to apply and then the argument you want to apply it to with a space between them. In Python, we use brackets to indicate that we're calling something on arguments. Sorry, parentheses to indicate that we're calling something on arguments. Okay, so yes, and I guess I didn't mention that the Lambda in Python is just an anonymous function. It just doesn't have a name. But we're going to be cheating a little bit. We're going to be naming some of our lambdas just for sanity. All right, so the game that we're going to be playing here, zoom back out, is if we were to pretend that Python's Lambda was like Lambda calculus Lambda, what could we do with it? And as I said, this is going to be an experimental, fun, silly, learning oriented talk, not a programming practical, let's do useful things talk. So please take this opportunity to get off the train. If you were like want to go learn something practical, there's a bajillion other talks on right now that I'm sure way more useful than this one. But this one hopefully will be fun. Alrighty, don't worry, I won't feel bad. So what can we make? How about some numbers? Numbers are cool. We like numbers. Numbers help us do things like count. One thing, two things, three things. But what could we count if we're in a world where all we have is a Lambda all we have is a tiny little pure one argument in one result out function. So all we know how to do is like create functions and then call them, apply them. What could we do with that? Well, we could think of applying a function as like counting one and applying it again as like counting another one and applying it again as counting more. So we could think of counting as like counting calls to a function or counting function applications. So if we had if we wanted a couple of numbers, zero and one, can everybody read this? Okay. Awesome. What would those look like? Well, okay, bear with me here, we're going to get a little little freaky with our definition of numbers. But if we need to count things by applying functions, then a number is going to need to be something that takes a function as an input. And it's going to return something that is another function, because everything is a function. And that function is going to take some argument. Okay, so if you'll allow me here, we're going to think of all numbers as being something that like takes a function and returns a function that takes an argument and does something. And the thing that it's going to do is apply the function f n times for whatever number it's supposed to represent. So like one would apply the function once. And zero would apply the function zero times exactly, which would mean we would just return. Cool. Okay, let's see if live coding works. Probably not. Let's find out. I think I also forgot to clear all the inputs in this thing. So that'll be interesting. So two then would be, oh, come on, y'all help me out. We calling f twice, right? So it'd be like applying x f to f of x. And three similarly would be f of f of f of x, I think. Look good. Okay, let's see what happens. Now, so far, I've been asking you to just trust me. But you probably want some kind of proof. So we're going to make it we're going to cheat just to do some sanity checks here. We make like an int converter that'll take a lambda number and convert it to a Python int. So what we're going to do is we're going to take the number n, and we're going to pass it a function that adds one to some integer i. And we're going to start it off with the integer zero. So zero should call this function here zero times, right? So that should give us zero. And one should call it once, which should add one to zero, which is one and so on and so forth. You with me? Is this acceptable? All right, let's see what happens. Oh, no, I forgot to clear the inputs. Okay, so do it to zero. It works. It was zero. And similarly, one, if you believe me, I'll do it live here. It's one. I think you see where I'm going with this. Yeah, convinced. You look so convinced I have never seen a more convinced looking group of people in my life. Okay. And three, yeah, whatever. Same difference. Okay, so now how do we get a higher number given a particular number? This would be what's called a successor function. We want we're going to need to be able to like take a number and see what the next one is. And in order to do that, whoa, hi. Okay, in order to do that, we need a function that takes what as input and a number cool and gives us another number, right? And a number is a thing that takes a function. Oh, that's not how you spell that. And then that returns a function that takes an x. And so if I wanted just n, like the original number that I gave it, I would call it like this, right? I apply n to f and then I apply that to x. But I want one more loop. I want one more application of f. So if I'm not super duper tired, I should be able to wrap that whole thing and apply f to it one extra time. I see skeptical puzzled and completely uninterested faces. Okay, so let's see what happens. If you believe me here, okay, so four would be the successor of three, right? And that should be and is four. And similarly, five should be the successor of four. And I should be able to get seven by applying like successor to the successor to the successor of four, right? Three extra successors. That gives me seven. I see how excited you are by this. It is really exciting. I know. Okay, but where can we go from here? So just a note, these numbers that we have, they're called church numerals. Can you guess who they're named after? That dude from the beginning Alonso, he's my BFF. No, not really, but I wish. Anyway, so just if you want something to Google, you can Google that. Okay, what about arithmetic? Can we like add two numbers? So if we have an n loops and an m loops, and we want to add them together, we could just loop n times and then loop and more times, right? So if I had like n was two, and m is three, I could do like one, two, and then one, two, three, and then that would give me five, right? Cool. So how do we represent that? So add is going to take an n and an m. And it's going to loop n times first of all. So that means we apply n to f. Oh, sorry, these, it's going to return a number, which looks like that as we've seen a couple of times. It's going to apply n to f and then to x. But then we're going to add on a couple of extra loops. So we're going to apply f again, m times to the result that we got from looping n times. I think this is right. Everybody on board? Maybe we'll find out. Okay, let's see. I don't know. Maybe I'm just super tired. Okay, so I should be able to get this. I should be able to add eight and two and get a thing called 10. And it should convert to this. All right, it worked. Yay. Nothing exploded. And I should then be able to zoom out a little. Can you still read that? Okay. I should then be able to add them in the opposite order and it should work. And I should be able to mess with this, right? Like this should give me yay. Yay. Good job, everybody. Okay, so subtraction is way harder. We're not going to do that. But multiplication, multiplication is not so hard. So what about multiplying n and m? How do we do that? So basically, if we're multiplying like two times three, we're going to do like one, two, that's counter one, then we're going to do another one, two, and then we're going to do another one, two, and that should give me two, two, two, six, right? So we're basically going to loop n times m times over. Okay. Oh, geez. That's what it looks like when you don't enter anything in. Cool, we're going to fix it. So multiply is going to take an n and an m and it's going to give us another number, which looks like this. Okay, so first we're going to loop n times. And if applied to f gives us a function that applies f n times, then if we apply m to that, that should apply that function m times. So we have like a loop within our loop. I see your faces all look like my face look the first time I played with this. Feel free to follow along if you've got your laptop in front of you open up an interpreter. Okay. So if I apply m to a function that loops n times, then I should get a function that loops n times m times is how I'm trying to think about this thing. Let's see what happens. All right, it didn't explode. Does it give us the right thing? This is what I'm expecting. I should be able to multiply four and three and get 12. Let's see what happens. Yay. Okay, and I should be able to, oops, I should be able to do something else like two int multiply, I don't know, two and three. Okay, let's see if it works the other direction. And again, dividing is super hard. No more divided. Okay, so what about powers? What about raising n to the power of m? Huh? I'm going to take a sip of water while you think about that one. Yeah, everyone looks at the ceiling like the answer is going to be written there. Okay. This one's going to get a little weird. Let's see what happens. Okay, I want a power function that takes an n and an m. And it's going to give me a number. Right? Okay, let's imagine let's let's take like a simple example. Let's imagine n is like two. So if I wanted to apply and like this would be like, two n is two. If I wanted n squared, I could multiply two by two, right? And we saw in the last example that that means calling like this part. This one was our m before. So imagine n was two. And now we're just now we've got like two squared. It's a little okay. And then for like three, it would be like, calling that again, two to the power of three. So this would be like two times two times two. Imagine n is two. Okay, so what we're doing is we're applying n m times to f, right? If only we had a way of telling the computer to apply a function a certain number of times. Oh, wait, that's what numbers do. So I should be able to take this n get rid of these extra things and apply m to it. And this would give me a function that calls an m times on this function, which should then give me like the power that I want. Maybe let's find out. Okay, so this is what I would expect, right? If I raise two to the power of three, I should get three to the power of three, right? Perhaps? Moment of truth? Yay! Okay, wait, I don't know. Maybe I could have just faked that. What if I raise it to four? We did it! We did it! Okay, but actually we can even simplify this because this is getting ugly. Now we've got like four things in here. We said a number is just a thing that takes a function and takes an argument and like applies to both of those. We can then just consider that if we clear all this out, since that's what a number does anyway, and clear all this out, we should still have a valid definition of the power function. So let's see if that still works. Okay, so that's even more elegant than like adding and multiplication. So this is some arithmetic. This is pretty fun. People are looking me like you said this was going to be interesting. But we did really, really basic math with something super complicated. Isn't that what all programmers love to do? Okay, meanwhile, I'm like, hey, BFF Alonzo, Mr. Church, sir. He's like, yeah, I'm Jenna. I'm speaking to you from beyond the grave. What do you want? Could you tell me the answer to life, the universe and everything, please? Commutation! No, just kidding. But I don't know. I thought this was pretty cool. Because if you think about it, the way we've been taught to think about like, addition, multiplication, exponentials, it's completely different than all of this. And yet, it totally works out in this Lambda formalism. So I think that's pretty fun. Feel free to disagree. Okay, so we've done math. That's cool. But that's not all our jobs entail as programmers. What else do we need? Oh, somebody said conditionals, because I planted them there in the audience beforehand. No, I didn't. But yes, we do need conditionals. And in order to do conditionals, we need Boolean values, right? Because these sort of go hand in hand. So, um, oh, good. Okay, this is what happens. Just ignore that. The, when we when we work with a conditional, it has some kind of form like this, right? We say if a condition is true, and where the condition is a Boolean, so it could be true or false. If it's true, then we do some stuff in the then block. And if the condition is false, then we do some stuff in the else block. Yes? On board? Okay. So we kind of need to define all of these things together so that they work out. So that we can do things like this. We can test if a condition is true and then do the then thing. And if it's not true, do the if the else thing. So if then else is going to be a function, because everything is a function, it's going to take a few different things. Well, it's always going to take one thing, but we're going to line up a bunch of arguments in sequence so that it looks like it takes multiple things. So it's going to take a condition, first of all. And then we're going to need to tell it like a then do, like a then block. And then we're going to need to tell it like an else do, else block, and then something. Okay, let's forget about what the something is for now and go back to Booleans. So Booleans, and I'm just naming them true and false here, so as not to like mess with our Python words, even though the lower case shouldn't mess with it. But anyway, it's also more fun to spell things wrong. Okay, so true should be a thing that when it sits here, it should pick this branch, right? And false should be a thing that when it sits here, it should pick this branch. So true is going to be a thing function, because everything is a function, that we're going to give it a then and an else block. And it's going to pick the then block, right? Just like that's how we want to be able to use Booleans. So let's just define it in terms of how we want to be able to use it. And similarly, if we give a then and an else to false, then we should get the else thing out. Okay, on board so far, I see like one or two nods. I'll assume that applies to everyone. Now, what about the rest of our if statement? We didn't finish it. What we're going to do if true and false are like choosers here, and they take a then and else, then we can just take our condition, which is going to be a Boolean, and apply it to the then and the else, and it should choose the right one for us, if we've done everything right. So I'm going to call the condition on the then, oops, apply it to the then typing is so hard, and then the else. And if it's true, it should pick the then and if it's false, it should pick the else. Maybe let's see. Okay, at least our little ugly thing went away, because clearing Python notebooks is hard. Let's see what happens. Okay, so I am tired. That is true. And the number of coffees that I'm going to drink today depends on whether or not I'm tired. So if I'm tired, I'm going to drink three coffees. And if I'm not tired, I'm going to just drink one coffee, because I'm in Italy, and I have to drink coffee. Okay, so this is what we would expect, right? If I'm tired, then coffees today should give me three. Yes? Okay, let's see what happens. Run. Okay. Okay. All right, all right. But I don't entirely believe this, because again, I could have rigged this. So what if I'm not tired? We did it! We programmed! We programmed! Look at that. We have conditionals now. I see you're all so excited like me. Okay. Moving on. So with truth values, we can do logic. That's fun. Okay. I'm just going to, we're just going to power through these kind of logic things, so in the interest of time. So if I want to not function, and again, I'm just going to use a different word so as not to override Python words. I'm going to call it opposite, because that's, I don't know, longer. Anyway, it's going to take a Boolean. And a Boolean is a thing that takes a then and an else, right? And a Boolean that's true is going to choose the then, and a Boolean that's false is going to choose the else. So if we wanted to do opposite day, we could just switch the else and the then, and apply the Boolean to it, and it would pick the wrong one, because we switched them, because we're sneaky that way. Do you believe me? You're like, yeah. Okay. So we should expect this, right? If I have, if I make a little cheating function that just applies a Boolean to Python's true and false, just so that we can see what Python thinks it is, instead of having to do something complicated, and again, this is cheating because we can't do side effects, and we don't have true and false in any other way except these functions that we created. If I convert true to Boolean, I should get true. Okay. And if I convert the opposite of true to a Boolean, I should get false. Oh, that worked. But let's make sure if I convert the opposite of false, I should get, yay. Okay. Logic. Step one. But we need more logic. Oh, no, we'll get to more logic in a second. First, we need predicates. So we want to be able to apply a function to a thing and get a Boolean out. That's like a predicate function, yeah? Where we test that something is or is not conforming to some high standard we're holding it to, like, for example, being zero. So if I wanted an is zero function that would take a number and give me a Boolean that tells me whether that number is zero or not, I could do it like this. I could apply that number, which again, takes a function and applies that function n times to a value. And I could pass it a function that takes whatever we give it and returns false always. Then if I pass that whole that n times application of this function to true, the only time that we're going to get true out is if we don't call this function on true at all, zero times. Whereas if we call it once, true will get turned into false. If we call it twice, false will still say false and so on and so forth. So I should be able to do this and get false for two. And I should be able to try it with zero and get true on board. So we have to be a little tricky now that we're in Lambda world on how we think about like functions like predicates. We have to start thinking in a totally different way where we're thinking about the number of times we would have to apply a function to things to understand something about the number of times that we have applied that function to the thing. This is why you could like spend your whole career thinking about this stuff. We're not going to. Okay, similarly, we could like as another example, we could have an is even function that starts off with true, because zero will call even and applies opposite n times. So we alternate back and forth. So one is the opposite of true is false. Two is the opposite of the opposite of true, which is true, etc. So I should be able to get eight is even seven is not even one is not even four is even. Yeah. Programmers. Don't clap for me clap for Alonzo. Okay. We're running out of time here. Let's see if we can power through this logic part. Okay, this is where things get a little crazy. So I'm just going to show this to you and let you think about it for a second while I take a sip of water and then we're going to talk about it. First, I have to open the water. Okay, so this is a this is like our and function. I'm calling it both because and is a special word in Python. Okay, so an operator like and or both, in my case, is going to take two booleans right boolah and bullb. No, bull a and bull b. How do we get to a place where we can use the fact that booleans choose either the first thing or a second thing to tell us whether both of them are true or one or more of them is false. Okay, this is the answer, but let's try to figure out why. So if bull a is true, then I can sort of continue and check bull b. If bull a is not true, then I already know that the whole thing is going to be false, right? Bull a is false. So if I were to set up two things where the first thing is I don't know what and the second thing is false because we've hypothesized that bull a is false, then false chooses the second thing, right? So it will choose false. So already just by knowing that bull a is false, I know that this whole thing is going to be false. I see faces like, feel free to play with this on your own time. I think that's the only way to like wrap your head around it. Okay, if bull a is true, though, then we'll pick bull b and see what bull b does. And if bull b is also true, then whatever comes here will be like the second thing that it would have chosen. But if bull b is true, then it'll choose the first thing. It won't choose this second part, it'll choose the first thing, which is bull a, but we already said that bull a is true. So this means we'll get true. I see like one nod and a couple of like amused chuckles. Okay, I don't know, let's try it out. Maybe we can convince ourselves by like, actually applying it to stop. So I should be able to do both true, true, and that should be true, right? Let's see what happens. Okay. All right, what if I change it? This should give me. It did. Okay, what about this? Oh, one more to check. Okay. Are we convinced? All right, I'm going to skip these were just more examples. Okay. And similarly, we could do the like or, which I'm just going to call inclusive or, where if bull a is true, it doesn't really matter what bull b is. So bull a is going to choose the first thing. And we already know that bull a is true. So we're just going to make it choose true. If bull a is false, then it's going to choose the second thing, which is bull b. And then the value of the whole thing just depends on whether bull b is true or false. Right? This is how truth tables work. Okay, let's see what happens. So I should be able to get true for this and true for this. And this should be false. Ha ha. And this should be true. Right? Yay. Okay, one person is like thinks this is cool. So if you don't understand why it's cool, you can go talk to him later. All right. Yeah, this is just more examples. Okay. I have like three minutes left. Don't know how much you'll be able to get through this. But let's try. Oh, oh, oh, we're being flexible with me. Nice. All right. So we've got some data. We got like numbers. We got Booleans. But what about structures of that data? Could we do that? Spoiler alert. Okay, everybody's favorite data structure is a sweet list, especially in functional programming land, we love lists, right? Um, what what is a list? It's a thing that contains stuff. What kind of stuff could it contain? So it could contain nothing could be empty, which is often called nil the empty list. It could contain one thing, or it could contain more than one thing. Yes. Have I forgotten any possibilities? Hopefully not. So we're going to try to represent these things by building lists out of pairs of two things. It's going to get a little weird, but we're going to try to get through it. Okay, we're going to have a make pair function that takes a left thing and a right thing and returns a pair of those two. Now, what is a pair of those two? We're just going to represent a pair as being some thing, some function that takes a function and then calls that function, whatever function you pass into it, on the left and then the right. It like applies some function to the left thing and the right thing. Okay, then we need a function to like get the left thing and get the right thing. And we already have a really nice function for choosing either the first thing or the second thing. It's called a Boolean. So we're going to take the get left function is going to take a pair and then pass the true function to that pair, which is going to call true on the left and the right and true chooses the first thing. So it's going to choose left. Yeah, and similarly for right. So if I make a pair of one and two, and I choose the left thing, then I should get one. And if this were different, okay, and if this were right, okay, with me, cool. All right, now, an empty list, we're just going to like by convention represent as a pair of true and true. And we'll see why that's helpful for lists, because we're going to represent lists, not as a pair of just two things, but as a kind of special pair, where the first thing in a list is going to tell us whether or not the list is empty. And then the, the right thing in that pair is going to be the actual like content of a non empty list. And if the list is empty, then we don't care about what's on the right hand side, because it's empty, there's nothing in it. So we could just put whatever we want there like true. It's a little bit more complicated than that, but close enough. So the only type of list that will have true as the left element will be the empty list. So we can use for our like is empty predicate function, we can just get the left thing in the list. So is empty nail should be true. Okay, cool. Then just powering through, we can create a prepend function, which takes an existing list L takes an item and a prepends it to an existing list L, which is non empty. Sorry, and gives us a list which is non empty. So is empty is going to be false. The left item is going to be false. So we're going to make a pair where the first thing, the left thing is false. And then the right hand side is going to be a pair itself of the new item and the old contents of the list. See people doing like this, which I think means my chin really gets this. Yeah, your chin does get it. Okay, so what we can do then is undo that with a head and tail function that get us the stuff in the right hand of the list where head is like the first thing in the list and tail is like everything else. So just take my word for this because we're almost out of time. So okay, on the first day of Europe Python, I had had like one cough two coffees. So I'm going to prepend to to an empty list. And this is how we get a list that just has one thing in it. So we already have the empty list, we needed a list with one thing in it. This is how we could do it, we could prepend to to the empty list. So if I were to get the head of let's say coffees, I don't know if this is going to work. Let's see. This should be. Nope. Nope. Sorry. Ah, thank you. Haha. Great. Okay. And then if I were to prepend more stuff to that, I could get a more complicated list that had other things. So if I had coffees per day, and I took the head of that I should get the first thing of the list. And then I took the coffees on day one, which is two, I prepended one, and then I prepended three. So the first thing should be three, which it is. And if I were to take the first thing of the rest of the list, that should be the head of the tail of the list, which should be. Ah, okay. So we got data. We've got numbers, booleans, lists, we got arithmetic, we got logic and control whole. And representing the data that we did here is called church encoding. So you can go Google that. And I know we're like super out of time. So I'm not going to go through these slides. But it turns out that this what we've been doing representing data this way is kind of like object oriented programming. Unfortunately, we don't have time to talk about why that is. But I'm going to post the rest of this. And there's like explanation of how that works. So I just want to say these are some some cool places to go read more about these things. Again, I will tweet out the location of this Python notebook. And I just want to say thank you to the research to Europe Python and all the people who like helped me and inspired me to do this. Yeah, and I would say we thank you. Awesome talk really. Great. I learned a lot. Maybe I would not have dropped out of my computer science studies when I had such an introduction to these kinds of things. I didn't understand it. So thank you. And yeah, unfortunately, no time for questions. But I think she's over there. You can come grab me afterwards. Thank you. Okay, thank you again.