Bite-Sized Godot: Lambda functions


A lambda function, also sometimes called a function literal or anonymous function, is a function that isn’t declared and bound to a specific identifier (hence them being “anonymous”). Typically, these are short, inline functions designed to take care of a small task immediately where it’s needed, like sorting or filtering an array, without having to declare a bunch of functions in your class that are only needed in one spot.

In Godot

In Godot 4, the syntax looks like this:

# Declare the lambda
var my_lambda = func(): print('hello!')
# Call the lambda by invoking the generated Callable
my_lambda.call()
var my_longer_lambda = func(a, b):
    var c = a * b
    print('%s * %s = %s' % [a, b, c])
my_longer_lambda.call(5, 4)

Internally, lambda functions work by creating a Callable object representing the lambda function, meaning if you’re familiar with Callables or even FuncRefs in Godot 3, then you already largely know how to work with them. You just declare the lambda using the syntax above, and then call() it wherever needed. Alternatively, you can pass the function, or the generated Callable, directly to something that takes a Callable, such as a signal connection:

# Both ways are acceptable since lambda functions generate Callables automatically
var callback = func(): print('Button was pressed!')
my_button.pressed.connect(callback)

my_other_button.pressed.connect(func(): print('My other button was pressed!'))

So this is pretty neat, but when would you actually want to use a lambda? As mentioned above, working with arrays is a common use case, as you may often find yourself needing to do basic filtering or sorting and writing a one or two line function for each use case can be a bit tedious. Taking some of the new Array functions as an example, here’s how we can filter an array both with and without lambdas:

var some_array = [1, 2, 3, 4, 5]

# Without lambda
func is_number_even(n):
    return n % 2 == 0

var evens = some_array.filter(is_number_even)

# With lambda
var evens2 = some_array.filter(func(n): return n % 2 == 0)

Sure, it’s not a drastic difference, but with enough cases like this, the lines of code saved can really add up. The one thing you’ll want to watch is that you don’t let your lambda functions get too large. Being written inline like this can hurt readability, in my opinion, so just be mindful of how large you let them get and consider making them a regular function if needed.

A few closing notes

And that’s lambda functions in Godot 4 in a nutshell. As two final notes on their usage, be aware that it is possible to actually name your lambda functions for debugging purposes, and that variables declared outside of your lambda function, but used internally by it, are passed by value, not reference, meaning you won’t see updates to their values if you change them:

var named_lambda = func my_named_lambda(x): print(x)

var value = 100
# Prints 100
named_lambda.call(value)
value = 'Hello!'
# Prints 100 again
named_lambda.call(value)

Be sure to check out the docs for all the details on lambda functions.