See all glossary terms

Function Call vs Function Reference

Function references can be tricky.

Syntax

What's the difference between:
func _ready() -> void:
  launch_rockets()

func launch_rockets() -> void:
  print("Launching rockets!")
And:
func _ready() -> void:
  launch_rockets

func launch_rockets() -> void:
  print("Launching rockets!")
In the first example, launch_rockets() is called, and the function executes. In the second example, launch_rockets refers to the function, and it's not called. It's just the function's name.
Remember, a function is like a recipe in a cooking book. For example, if the book has a recipe for a chocolate cake, I could tell you to "make the cake". That's like calling the function. But if I say "chocolate cake", that's like just giving you the recipe's name.
The () at the end of a function name is a shortcut for "call this function". It is actually a shortcut for .call(). launch_rockets() is the same as launch_rockets.call().
  • launch_rockets() means "execute the function launch_rockets"
  • launch_rockets means "the function launch_rockets"

Functions can be substituted for their results

Do you remember how you used to reduce a math equation?
y = (2 + 3) * (5 * (1+1) )
y = 5 * (5 * 2)
y = 5 * 10
y = 50
You first resolve internal parenthesis. Programming languages do the same with functions.
In the example below, five() and three() are functions that return numbers. When you call them, you get the number they return. They get evaluated by Godot before print() is called:
func five() -> int:
  return 5

func three() -> int:
  return 3

func _ready() -> void:
  print(five() + three())
Note that print(five + three) wouldn't work, as you can't add function references together.

Use cases

Where do you use function references? One everyday use is in connect().
When connecting a signal to a function, you reference the function's name. For example:
tween.finished.connect(launch_rockets)
This tells the tween to call launch_rockets when it's finished. Using the cake example again, it'd be like saying, "When the tween finishes, make the recipe called chocolate cake".
In contrast, if you use parentheses, you're calling the function, and that's probably not what you want:
tween.finished.connect(launch_rockets())
Because launch_rockets() finishes first and returns void, the expression becomes:
tween.finished.connect(null)
In plain language, that'd be like saying: "Make the cake. When the tween finishes, cake", which doesn't make sense since "cake" is not an action.

The problem of arguments

Sometimes, you want to use a function reference, but you want to give it arguments.
For example, the Button's pressed signal doesn't give you any arguments. But what if you want to pass the button's name to the function?
One way is to use lamba functions. They're like mini-functions that you can define on the spot. For example:
button.pressed.connect(func() -> void:
  launch_rockets(button.name)
)
Another is to use the bind() function. bind creates a new function that calls the original function with the arguments you provided:
button.pressed.connect(launch_rockets.bind(button.name))
In this case, bind creates a new function that calls launch_rockets with the button.name argument. It's similar to using the lambda function, but it's more concise.

See Also

Related terms in the Glossary