Submind YouTube summaries
Thumbnail for Anonymous Functions (and Other Ways to Annoy Your Coworkers) - Joe Kaufeld - 2026

Anonymous Functions (and Other Ways to Annoy Your Coworkers) - Joe Kaufeld - 2026

Watch on YouTube

Video summary

Joe Kaufeld opens his presentation by humorously acknowledging the common frustration developers feel regarding anonymous functions, or lambdas, in Python. He begins with a brief detour into his personal preference for using bitwise invert operators to handle list indexing, arguing that treating the right side of a list as negative one is unintuitive compared to using the tilde operator. After establishing this quirky syntax preference, he transitions to the core topic, defining lambdas as unnamed functions that theoretically perform a single operation. He traces the historical lineage of this concept from Alonzo Church's lambda calculus and Lisp to its adoption in Python, noting that while Guido van Rossum initially wanted to remove these features in favor of list comprehensions, they ultimately remained due to community resistance. Kaufeld clarifies that despite their limitations—such as being restricted to a single expression and lacking variable declarations—lambdas are fundamentally just functions without identifiers. The speaker then explores practical applications where lambdas are appropriate, such as sorting complex data structures like lists of actors by last name or filtering even numbers from a dataset. He highlights the utility of `map` and `filter` operations but notes that Python's list comprehensions often serve as a more readable alternative for these tasks. Kaufeld shares an advanced use case involving a Pokémon TCG companion app, where he utilized lambdas to dynamically generate data classes for thousands of cards. By leveraging the local scope of lambdas, he could create factory-like functions that pre-filled known data (like set IDs) while leaving other fields open for instantiation, resulting in code that was significantly more readable and maintainable than hardcoding every detail. In the spirit of his talk's title, Kaufeld proceeds to demonstrate how to "annoy coworkers" by breaking standard rules and creating multi-line lambdas through clever abuse of Python's list evaluation scope and the walrus operator. He shows how one can effectively create decorators or even re-implement timing utilities like `timeit` by wrapping logic inside a lambda that executes immediately upon definition, storing results back into the function name. While he admits these techniques are generally discouraged because they reduce code readability and violate best practices, he encourages the audience to experiment with such "cursed" code for fun, especially if they are the sole maintainers of the project. He concludes by reminding listeners that while lambdas are useful shorthand for simple, localized logic, relying on them excessively can lead to confusion, and he invites attendees to share their own examples of overly complex anonymous functions.
Read the full video transcript
So, uh this is Joe Corfeld, who is going to ah >> radio >> radio. Uh who's going to uh give us our last uh I guess Python technical talk of the conference this year. Uh talking about something that's very near and dear to my heart, which is doing the wrong thing with anonymous functions. Uh please make him welcome. >> Thank you very much. Before we get started, I am going to check in with our crew. So, welcome to anonymous functions or how I learned to stop worrying and love the lambda. I have changed the name of this talk because when I originally wrote the uh the outline, I had a thought for how this was going to go. And then I actually like started writing the talk for real. Um and it ended up that I submitted an outline for roughly an hour and a half worth of content for a 25-minute talk. So, um we have to switch this up a little bit. I think it'll be okay though. So, lambdas, more than you ever wanted to know about Python lambdas. Um my name is Joe Corfeld. I am a senior developer focusing on building really big applications for lots of people with really high availability and the former president of the Grafeas Group. So, if you uh were online and are familiar with Transcribers of Reddit, that was my project. And I am a maker, breaker, and professional eater of bread. You can find me at these places. Uh if you want to throw things metaphorically at me, uh please do it on Mastodon because that's the easiest place for me to get it. This slide will be up again at the end. So, before we really get into this, um I was talking to Sam before uh this event. And I said, "Hey, I have this weird Python thing that I do a lot and I realize now that I've written it into all of my examples. Do you know what this weird Python thing is?" And he was like, "No." So, um, they apologies. Um, so we're going to take a quick second and divert from the actual uh, purpose of our talk and we're going to talk about bitwise inverts. Um, so a bitwise invert is a really fun unary operation. We're not going to get into what literally anything I just said meant, um, but who can tell me what tilde zero equals? Minus one, exactly. The general rule for this is the two's complement. Again, we're not going to get into that either, but it is tilde n equals negative n minus one. This applies for roughly all numbers and I really like to use this when we're doing lists and specifically indexing doing negative indexing because in my mind the fact that the well, from your perspective, the left side of a list is indexed as position zero and the right side of the list is indexed as position negative one doesn't make any sense and I don't like it. So, instead I use uh, bitwise inverts so that the left side is zero and the right side is tilde zero. Inside one is one and inside one from the other side is tilde one. I think it makes a lot more sense. Um, and again, I accidentally wrote this into all of my examples. So, now you know what this piece of syntax is. Thank you very much for attending my TED Talk. So, time for lambdas. Join me on our descent into hell. So, uh, we have to make sure that everybody's is on the same page. So, we're going to start at the bare bottom. A An anonymous function is a function definition that is not bound to an identifier. Which, once you strip away the crap, just means that we have logic that doesn't have a name. That's all it is. We have logic that works on something in a way that is theoretically repeatable, but we didn't give it a name. In Python, this is a little bit different because we kind of want to name everything. Um so, we are going to do that anyway. Um But, in general, now we all know. So, a brief history lesson. In 1936, Alonzo Church gives us lambda calculus. I am not going to get into this. We're just going to look at this slide, and then we're going to move on because I barely passed business calc, otherwise known as calc for weenies. So, this is what we get. Um Alonzo Church gave us this particular setup in that we have four individual pieces. We have, ignoring the lambda part for a second, we have X, which is our variable, the thing that we want to act upon. Then, we have a period, which is our separator. It separates the thing that we want to act upon and the way that we are going to act upon it. And then, we have the function body, which is our operation. In a normal function, you take these three things and you wrap them all in a name. And you have a function. This is how functions work at a very basic level. Um it's just those four pieces. The only functional difference between a lambda and a regular function is that you don't have that encapsulating name. So, we have lambda, the icon that shows we are about to launch into this process, the argument, the separator, and the body. In 1958, Lisp picked up the lambda as the first programming language to have uh this concept and it has very much the same structure. You have the lambda keyword, the argument, you have the separator, the parentheses and the space, and then the operation that you are going to perform on the argument. It is also worth noting um that both in the original and in Lisp, we have an implicit return. There is no point where we have to state that the result of the operation that we perform will be returned. It just simply will be returned. The implicit return is important because we don't actually have to specify that we get that information back. It's just going to come back. This is in stark difference to well, JavaScript. So, in JavaScript, we have an anonymous function. This is the the main way that you would create an anonymous function if you did it the long way. Again, JavaScript, we're going to be skipping over a little bit, but we have function, the way that we define a function, then we would normally have a name and then the parentheses A B and then our logic. Note, we have an explicit return, which means that for many reasons, this violates our definition of what a lambda is and how a lambda works. They did end up fixing this kind of with arrow functions. So, now we have the arguments, we have the separator, the arrow, and we have the logic and an implicit return. So, we're making progress. Go JavaScript. Yay. Python's is a little bit similar, but it looks familiar for all the wrong reasons. We have a lambda, the actual keyword lambda that you have to type out every time. I'm sorry, Amanda. We have the argument that we work on. We have the separator, which is the colon, and then we have the the operation that we are going to perform on said argument. In this case, we're going to multiply the argument by two and then do an implicit return so that we get it back. So, lambdas are functions, they but they've got some rules to them. So, let's take a look at that real quick. Lambdas have one operation. They are one line. They return one thing. You cannot declare variables. And you cannot have shenanigans. >> Facts. All of that is >> All of these are wrong and we're going to disasso we're going to disassemble most of them. So, in order to talk about the fun stuff, we have to talk about ways that you are supposed to use a lambda. Okay. So, reasonable semi reasonable uses of lambdas. First off, this is the kind of uses that you're going to see most often. It's sorting things. When you sort a piece of data a data structure in this case, a list, then you have the ability to specify the a function by which you are going to sort the data. In this case, we want to sort the actors from Scrubs by last name. We can't just split it down the middle by space because of John C. McGinley here. So, we actually have to do a little bit of working. In this case, we have a lambda that takes in a name one name at a time. We split it by spaces. We grab the last element. That's the squiggly zero per, remember? That was invert, cool. And then we lower case it and then we return it can implicit return. So, that's going to give us all lower case the last names of each of these people. That's going to be put into a separate element or a separate uh data structure, sorted and then applied to this data structure. This is a totally reasonable use. You could, in fact, arguably should have this spread out into a different function so that you can, you know, unit test. Who does that? Anyway, um another one you may see pretty often is filtering. In this particular case, we want to filter by the even numbers out of a list. So, what we do is we take our uh our numbers here and we simply check each one of them to see if it's divisible by zero. If it's divisible by zero, we return true, so it gets added back into our our end result and we have it. Cool? Cool. The map function, rarely used in Python for good reasons. Um you can run a any given function over each individual piece of data in your iterable. In this case, we just want to multiply each number in our list by two. So, we're going to end up with a thing called X, which is 2 4 6. Cool? Cool. Now, something interesting that I actually ran across um that I haven't actually ever seen discussed anywhere is something that I ended up using lambdas for for a project. Um I wrote a companion helper app for a mobile game uh called Pokémon TCG Pocket. And as part of this, I needed to be able to track every card that is in the game. So, I decided to do this with a data class. It's just class C for card, the set ID that the card is in, the number of the card, name of the card, rarity, et cetera. It's just these four things, so I don't need to keep track of a lot, but uh there are like 2,100 cards and that is kind of a lot of data, especially if you're going to be integrating that, actually hard coding it into the code base, which I wanted to do for various reasons. So, I was looking at this and I thought I know some of this data ahead of time. But, I don't know all of it. So, every card set that comes out has between 80 and 220-ish cards that are attached to it. So, I know that, for example, this set of cards all have the same ID. I don't want to type out the same ID every time. But, you have to instantiate the data class with all of its data at instantiation time. Otherwise, it gets mad at you or you have defaults and I didn't want to screw with that. So, instead I took the harder route and we built this. So, lambdas, remember, can do one thing. They return one thing, but that one thing can be anything. So, what we have here is we have a lambda that takes in a set ID. This is the only piece of information that we know ahead of time. So, because lambdas have scopes internal, then I can return another lambda from my lambda that already has the first piece of information saved and ready to go because it's in that local scope. So, what I can do then is I can create variables, which are essentially functions, that have that pre-saved piece of data in them and then use that to construct my uh my data classes in a readable way. When you have, like, 2,000 of these elements, it's very clear looking at this what set is it, what card is it, what piece of information is it. And when I interact with this in the code base, this is a data class because the only thing that's changing is the order in which I am instantiating it. So, we have all of the information. It's easier to read well, a little bit of, uh, at the beginning, but actually, after it's assembled, I think this is much easier to read, and the folks who have worked on the app with me have also told me this is easier to read. So, you know, fun thing you can do with that. Now, let's take a second to think about our good options that we've seen here. We have sort, which, okay, that's you can't get around that. We have map, and we have filter, and we have whatever this is. So, map and filter and reduce and lambdas are all from Lisp. And there there is, unfortunately, a reason for that. It's because prior to Python 1, there was a guy who really missed them from Lisp and submitted a a patch request to add them into Python. For various reasons, Guido attempted to get rid of them for Python 3. In 2005, he wrote an impassioned blog post about why he thought we should ditch lambda, uh, map, filter, and reduce for the upcoming Python 3 release. Namely, the fact that, uh, list comprehensions are easier to read and, uh, do it just as well, and they're easier to read, and they're more Pythonic. Mhm. For various reasons, the crowd was unimpressed. Uh, so, unfortunately, we were unable to get rid of most of these, and reduce was the only one that was, in Guido's words from earlier today, demoted. The rest we're stuck with. Well, might as well break stuff. Okay. So, now we have some thoughts. We know what we can do with lambdas. We know what we should do with lambdas. So, let's see what we shouldn't do with lambdas. Ooh. Okay. So, we know that lambdas are just functions, right? They're They're functions that don't have names, but they can still do everything a function can. They hold one thing. And that one thing can be anything. So, we need to talk about lists for a second. Brief segue. This actually works for any data structure, but we're going to stick with lists because they're marginally more readable, and I'm about to throw some really horrific code at you. So, we're going to stick with lists. So, again, starting at the bare bottom, just to make sure we're all on the same page. Normally, when we have data, we just stick it in a list, declare it, and we're done. And congratulations, you have a list. It has these numbers in it. But, if we don't know the data that's going to go into the list when we assemble the list, we need to pass it a variable. Then, as we reference the list, it pulls the values, I'm simplifying a lot here, and inserts them into the list, and provides us with our end result, the thing that we actually wanted, right? Right. Okay. The important thing to take out of this is not that this Python 100-level lesson is possible, but to keep in mind that lists have their own scope, which means we can abuse that. So, lists not only have scopes, but they evaluate each cell, moving left from right, at the time that you create it. So, in this particular example, we have one, two, and one plus a variable. When we actually call the list, we don't know what the variable is, so we look inside the local scope, we pull that variable, and then we do math on it to get three. Now, we have everything we need. In Python 3.8, something very suspicious happened. And by suspicious, I mean mostly that the community was very upset, or at least a subset of the community was extremely upset, because we got the walrus operator. The walrus operator, colon equals, is also kind of informally known as the thing that lets you define variables in the local scope as part of a larger logical statement. Normally, we only use it in places like this, because frankly, this is the only good place to use it in something like this. But, I want to show you something, and this is a little bit of audience participation, because what will this output? Any guesses? What? >> A portal to hell. >> Well, yes, a portal to hell is a valid option, but it's not what this is going to output. What? Seven, eight. Exactly. So, what's going to happen is it's going to evaluate this by assigning seven to T, and then it's going to move on to the next cell, even though T has never been described before in our program. We have created it out of thin air, and now we can interact with it, and we can use it in the local scope of the data structure that we're interacting with. Now it gets fun. Okay, so Let's talk about decorators. A decorator is a function that wraps another function. Uh decorators, I would say, are maybe a 200-level things, so I'm not going to get really into it, but what happens if we just stick an at symbol in front of a lambda? Cuz it is a function, right? So So this is a really basic lambda. What this does is it takes in a function and then immediately returns it with no changes. But it's still a functional lambda, which means we can still do functional lambda things with it. Because what happens if we wanted to run a function as soon as it's loaded into the local scope? Well, that could look something like this. So let's step through this for a second. We have lambda. Okay, congratulations. Yay. Is my cursor in the middle? There we go. Let's move that. Sorry, I didn't know that was there. There we go. Okay. So we have lambda. We have F, that is our function, that is going to be Well, it's our argument, but because it's a decorator, we're going to be passing in the hello function. Then we have a list. The first element of the list is going to be calling the function that we passed in, which is then going to store the result in that array as the to replace the first element. And then we just give it a normal reference. And then we return the last element of the array, which gives us the normal reference. This is deliberate. I'm pointing out that we made this a little bit complicated specifically because we need to be able to call this function again. If we don't return a a a um If we don't return a route to the function originally, we're we're going to be able to call this again because it's actually going to overwrite the hello name in the local scope with the result of the function running. Which we can abuse. So, let's make this a little bit simpler. If we do overwrite it, in this case, we just have lambda F, our function, and then we immediately call the function that we passed in. This is simpler, but what it does is it returns the output to the name of the function. Which effectively means we have multi-line lambdas. I do want to shout out to Chris who pointed out that this was possible, and I I just took it one step further. I'm sorry. Um so, this actually does allow us to have multi-line lambdas. We can have a function of unlimited length. Stick that lambda on the top, and then it will immediately run and save the output to the name of the function as a regular variable. You're welcome. Okay, let's make this more complicated. Um Does anybody want to tell me what this does? Okay, cool. Uh this is a greenfield re-implementation of the timeit decorator. Because I thought it would be fun. Um I'm I'm not going to break this down into its component parts, but what I am going to explain is that we use lists to run each individual line of code as a stand-alone cell in the list. So, we start by aliasing time so that I can actually fit this on the slide. We get a start time as the second cell. The third cell is we run our function with all of the arguments that we originally passed in, and we store the result of that to R. The next cell is just R so that we can reference it more cleanly. Then the last cell is a print statement that reformats it into something that's generally readable. And then we have tilde one, which means it is the first one from the right, which is the result R. And you can stick this on top of any function you want and congratulations, you've re-implemented time it. This was more fun than it had any right to be. Okay. So, unfortunately, um as I said at the very beginning, I wrote like an hour and a half worth of content and I only have 25 minutes, which is very sad. So, maybe maybe we'll just have to do this again. Okay. So, there were many other things that I wanted to talk about like um recursive lambdas and uh decorator factories and other factories. Um yeah, all kinds of fun stuff. Oh man, there's so much cool stuff we can do. So, uh before I go, I am actually going to leave you with one more horrible thing um after the the takeaways. So, in general, lambdas are great when they're short and localized. Make sure that they're readable. Otherwise, your your co-workers will will hate you. Not will likely hate you, they will. It it's just a matter of time. You really shouldn't ever use them otherwise. There are so few actual real reasons to use a lambda, honestly. Just use functions. Uh lambdas are they're shorthand. Even the the Python documentation, I was actually going to submit a PR for this before my talk and I forgot. Even the Python documentation says that you should only use a lambda as a lazy way to define a function. Like straight up, look it up. So, however, doing things the right way is not necessarily the way that leads to learning. So, give yourself permission to write bad code because it's so much fun. And honestly, if you're the only person who's working on this code, then you are the person who's going to be mad at you in 6 months when they have to read this back, so you'll live. It'll be fine. Okay. And also, please send me cursed lambdas. So, I'm giving you the tools that I have uncovered over the past few months. Um my friends are really tired of me sending them code snippets and being like, "What does this do?" And them saying, "I have no clue. Who are you? Stop calling me." Well, that too. Okay, so uh one last thing, um have you ever looked at the core piece of Python boilerplate that we all have, if name equals main? And and thought, "This is so ugly. I wish I could replace it with something cooler." Um I I couldn't actually fit this into the presentation, but this does handle edge cases properly for both uh calling the file that this function is in and importing it afterwards and still being able to reference the function uh in both of those cases afterwards if you want to call it again. So, you could just like spam this wherever you want and it'll just work. Um I don't recommend it, but you can. I wrote this this morning because um it just kind of popped into my head and I was like, "I feel like I can do this." Not that I should do this, but I feel like I can. Anyway, uh that's what I've got. Thank you so much. I really appreciate it.