Callback (computer programming)
This article needs additional citations for verification. (September 2015) |

In computer programming, a callback is a function that is stored as data (a reference) and designed to be called by another function – often back to the original abstraction layer.
A function that accepts a callback parameter may be designed to call back before returning to its caller which is known as synchronous or blocking. It may be designed to call back after returning which is known as asynchronous, non-blocking or deferred.
Programming languages support callbacks in different ways such as function pointers, lambda expressions and blocks.
Analogy
To aid understanding the concept, the following is an analogy from real life.
A customer visits a store to place an order. This is like the first call.
The customer gives to a clerk a list of items, a check to cover their cost and delivery instructions. These are the parameters of the first call including the callback which is the delivery instructions. It is understood that the check will be cashed and that the instructions will be followed.
When the staff are able, they deliver the items as instructed which is like calling the callback.
Notably, the delivery need not be made by the clerk who took the order. A callback need not be called by the function that accepted the callback as a parameter.
Also, the delivery need not be made directly to the customer. A callback need not be to the calling function. In fact, a function would generally not pass itself as a callback. Some find the use of back to be misleading since the call is (generally) not back to the original caller as it is for a telephone call.
Use
A blocking callback runs in the execution context of the function that passes the callback. A deferred callback can run in a different context such as during interrupt or from a thread. As such, a deferred callback can be used for synchronization and delegating work to another thread.
Windowing system
Callbacks are often used to program the graphical user interface (GUI) of a program that runs in a windowing system. The application supplies a reference to a custom callback function for the windowing system to call. The windowing system calls this function to notify the application of events like mouse clicks and key presses.
Implementation
The form of a callback varies among programming languages:
- In assembly, C, C++, Pascal, Modula2 and similar languages, a machine-level pointer to a function may be passed as an argument to another (internal or external) function. This is supported by most compilers and provides the advantage of using different languages together without special wrapper libraries or classes. One example may be the Windows API that is directly (more or less) accessible by many different languages, compilers and assemblers.
- C++ allows objects to provide their own implementation of the function call operation. The Standard Template Library accepts these objects (called functors), as well as function pointers, as parameters to various polymorphic algorithms.
- Many dynamic languages, such as JavaScript, Lua, Python, Perl[1][2] and PHP, simply allow a function object to be passed through.
- CLI languages such as C# and VB.NET provide a type-safe encapsulating reference, a "delegate", to define well-typed function pointers. These can be used as callbacks.
- Events and event handlers, as used in .NET languages, provide generalized syntax for callbacks.
- Functional languages generally support first-class functions, which can be passed as callbacks to other functions, stored as data or returned from functions.
- Some languages, such as Algol 68, Perl, Python, Ruby, Smalltalk, C++11 and later, newer versions of C# and VB.NET as well as most functional languages, allow unnamed blocks of code (lambda expressions) to be supplied instead of references to functions defined elsewhere.
- In some languages, e.g. Scheme, ML, JavaScript, Perl, Python, Smalltalk, PHP (since 5.3.0),[3] C++11 and later, Java (since 8),[4] and many others, such functions can be closures, i.e. they can access and modify variables locally defined in the context in which the function was defined. Note that Java cannot, however, modify the local variables in the enclosing scope.
- In object-oriented programming languages without function-valued arguments, such as in Java before its 8 version, callbacks can be simulated by passing an instance of an abstract class or interface, of which the receiver will call one or more methods, while the calling end provides a concrete implementation. Such objects are effectively a bundle of callbacks, plus the data they need to manipulate[clarification needed]. They are useful in implementing various design patterns such as Visitor, Observer, and Strategy.
- In PL/I and ALGOL 60 a callback procedure may need to be able to access local variables in containing blocks, so it is called through an entry variable containing both the entry point and context information. [5]
Example code
C
Callbacks have a wide variety of uses, for example in error signaling: a Unix program might not want to terminate immediately when it receives SIGTERM, so to make sure that its termination is handled properly, it would register the cleanup function as a callback. Callbacks may also be used to control whether a function acts or not: Xlib allows custom predicates to be specified to determine whether a program wishes to handle an event.
The following C code demonstrates the use of callbacks to display two numbers.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* The calling function takes a single callback as a parameter. */
void PrintTwoNumbers(int (*numberSource)(void)) {
int val1 = numberSource();
int val2 = numberSource();
printf("%d and %d\n", val1, val2);
}
/* A possible callback. */
int overNineThousand(void) {
return (rand() % 1000) + 9001;
}
/* Another possible callback. */
int meaningOfLife(void) {
return 42;
}
/* Here we call PrintTwoNumbers() with three different callbacks. */
int main(void) {
srand((unsigned)time(NULL)); /* Initialize seed for random function. */
PrintTwoNumbers(&rand);
PrintTwoNumbers(&overNineThousand);
PrintTwoNumbers(&meaningOfLife);
return 0;
}
Example output:
7112 and 15618 9089 and 9739 42 and 42
Note how this is different from simply passing the output of the callback function to the calling function, PrintTwoNumbers() - rather than printing the same value twice, the PrintTwoNumbers calls the callback as many times as it requires. This is one of the two main advantages of callbacks.
The other advantage is that the calling function can pass whatever parameters it wishes to the called functions (not shown in the above example). This allows correct information hiding: the code that passes a callback to a calling function does not need to know the parameter values that will be passed to the function. If it only passed the return value, then the parameters would need to be exposed publicly.[example needed]
Another example:
/*
* This is a simple C program to demonstrate the usage of callbacks
* The callback function is in the same file as the calling code.
* The callback function can later be put into external library like
* e.g. a shared object to increase flexibility.
*
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef struct MyMsg {
int appId;
char msgBody[32];
} MyMsg;
void myFunc(MyMsg *msg) {
if (!msg) {
assert(0);
return;
}
if (strlen(msg->msgBody) > 0) {
printf("App Id = %d\nMsg = \"%s\"\n", msg->appId, msg->msgBody);
}
else {
printf("App Id = %d\nMsg = No Msg\n", msg->appId);
}
}
/*
* Variable declaration of a function pointer
*/
void (*callback)(MyMsg *);
int main(void) {
MyMsg msg1;
msg1.appId = 100;
strcpy(msg1.msgBody, "This is a test.");
/*
* Assign the address of the function "myFunc" to the function
* pointer "callback" (may be also written as "callback = &myFunc;")
*/
callback = myFunc;
/*
* Call the function (may be also written as "(*callback)(&msg1);")
*/
callback(&msg1);
return 0;
}
The output after compilation:
$ gcc cbtest.c
$ ./a.out
App Id = 100
Msg = "This is a test."
This information hiding means that callbacks can be used when communicating between processes or threads, or through serialized communications and tabular data. [clarification needed]
In C++, functor is also commonly used beside the usage of function pointer in C.
C#
A simple callback in C#:
public class Class1
{
static void Main(string[] args)
{
Class2 c2 = new Class2();
// Calling method on Class2 with callback method as parameter.
c2.Method(CallbackMethod);
}
// The callback method. This method prints the string sent in the callback.
static void CallbackMethod(string str)
{
Console.WriteLine($"Callback was: {str}");
}
}
public class Class2
{
// The method that calls back to the caller.
// Takes an action (method) compatible with Action<string> delegate as parameter.
public void Method(Action<string> callback)
{
// Calls back to method CallbackMethod in Class1 with the message specified.
callback("The message to send back");
}
}
Kotlin
In the following Kotlin code, function askAndAnswer
uses parameter getAnswer
as a blocking callback. askAndAnswer
is called with getAnswerToMostImportantQuestion
which acts as a callback function. Running this will tell the user that the answer to their question is "42".
fun main() {
print("Enter the most important question: ")
val question = readLine()
askAndAnswer(question, ::getAnswerToMostImportantQuestion)
}
fun getAnswerToMostImportantQuestion(): Int {
return 42
}
fun askAndAnswer(question: String?, getAnswer: () -> Int) {
println("Question: $question")
println("Answer: ${getAnswer()}")
}
JavaScript
In the following JavaScript code, function calculate
uses parameter operate
as a blocking callback. calculate
is called with multiply
and then with sum
which act as callback functions.
function calculate(a, b, operate) {
return operate(a, b);
}
function multiply(a, b) {
return a * b;
}
function sum(a, b) {
return a + b;
}
// outputs 20
alert(calculate(10, 2, multiply));
// outputs 12
alert(calculate(10, 2, sum));
The collection method .each()
of the jQuery library uses the function passed to it as a blocking callback. It calls the callback for each item of the collection. For example:
$("li").each(function(index) {
console.log(index + ": " + $(this).text());
});
Deferred callbacks are commonly used for handling events from the user, the client and timers. Examples can be found in addEventListener
, Ajax and XMLHttpRequest
.
[6]
In addition to using callbacks in JavaScript source code, C functions that take a function are supported via js-ctypes.[7]
Red and REBOL
The following REBOL/Red code demonstrates callback use.
- As alert requires a string, form produces a string from the result of calculate
- The get-word! values (i.e., :calc-product and :calc-sum) trigger the interpreter to return the code of the function rather than evaluate with the function.
- The datatype! references in a block! [float! integer!] restrict the type of values passed as arguments.
Red [Title: "Callback example"]
calculate: func [
num1 [number!]
num2 [number!]
callback-function [function!]
][
callback-function num1 num2
]
calc-product: func [
num1 [number!]
num2 [number!]
][
num1 * num2
]
calc-sum: func [
num1 [number!]
num2 [number!]
][
num1 + num2
]
; alerts 75, the product of 5 and 15
alert form calculate 5 15 :calc-product
; alerts 20, the sum of 5 and 15
alert form calculate 5 15 :calc-sum
Lua
A color tweening example using the Roblox engine that takes an optional .done callback:
wait(1)
local DT = wait()
function tween_color(object, finish_color, fade_time)
local step_r = finish_color.r - object.BackgroundColor3.r
local step_g = finish_color.g - object.BackgroundColor3.g
local step_b = finish_color.b - object.BackgroundColor3.b
local total_steps = 1/(DT*(1/fade_time))
local completed;
coroutine.wrap(function()
for i = 0, 1, DT*(1 / fade_time) do
object.BackgroundColor3 = Color3.new (
object.BackgroundColor3.r + (step_r/total_steps),
object.BackgroundColor3.g + (step_g/total_steps),
object.BackgroundColor3.b + (step_b/total_steps)
)
wait()
end
if completed then
completed()
end
end)()
return {
done = function(callback)
completed = callback
end
}
end
tween_color(some_object, Color3.new(1, 0, 0), 1).done(function()
print "Color tweening finished!"
end)
Python
In the following Python code, function calculate
accepts a parameter operate
that is used as a blocking callback. calculate
is called with square
which acts as a callback function.
def square(val):
return val ** 2
def calculate(operate, val):
return operate(val)
# outputs: 25
calculate(square, 5)
Julia
In the following Julia code, function calculate
accepts a parameter operate
that is used as a blocking callback. calculate
is called with square
which acts as a callback function.
julia> square(val) = val^2
square (generic function with 1 method)
julia> calculate(operate,val) = operate(val)
calculate (generic function with 1 method)
julia> calculate(square,5)
25
See also
References
- ^ "Perl Cookbook - 11.4. Taking References to Functions". 2 July 1999. Retrieved 2008-03-03.
- ^ "Advanced Perl Programming - 4.2 Using Subroutine References". 2 July 1999. Retrieved 2008-03-03.
- ^ "PHP Language Reference - Anonymous functions". Retrieved 2011-06-08.
- ^ "What's New in JDK 8". oracle.com.
- ^ Belzer, Jack; Holzman, Albert G; Kent, Allen, eds. (1979). Encyclopedia of Computer Science and Technology: Volume 12. Marcel Dekker, inc. p. 164. ISBN 0-8247-2262-0. Retrieved January 28, 2024.
- ^ "Creating JavaScript callbacks in components". Archive. UDN Web Docs (Documentation page). sec. JavaScript functions as callbacks. Archived from the original on 2021-12-16. Retrieved 2021-12-16.
- ^ Holley, Bobby; Shepherd, Eric (eds.). "Declaring and Using Callbacks". Docs. Mozilla Developer Network (Documentation page). Archived from the original on 2019-01-17. Retrieved 2021-12-16.