Callback (computer programming)
In computer programming, a callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time. The invocation may be immediate as in a synchronous callback or it might happen at later time, as in an asynchronous callback. In all cases, the intention is to specify a function or subroutine as an entity that is, depending on the language, more or less similar to a variable.
The ways that callbacks are supported in programming languages differ, but they are often implemented with subroutines, lambda expressions, blocks, or function pointers.
Design
There are two types of callbacks: blocking callbacks (also known as synchronous callbacks or just callbacks) and deferred callbacks (also known as asynchronous callbacks). These two design choices differ in how they control data flow at runtime. While blocking callbacks are invoked before a function returns (in the C example below: main), deferred callbacks may be invoked after a function returns. The C example below is a blocking callback. Deferred callbacks are often used in the context of I/O operations or event handling. While deferred callbacks imply the existence of multiple threads[citation needed], blocking callbacks often (but not always) rely on a single thread. This means that blocking callbacks are not commonly used for synchronization or delegating work to another thread.
Callbacks are used to program applications in windowing systems. In this case, the application registers a callback function within the operating system and, later, the OS calls the application to signal events like mouse clicks or key hits. A major concern here is the management of privilege and security: whilst the function is called from the OS, it should not run with the same privilege as the system. A solution to this problem is using rings of protection.
Implementation
The form of a callback varies among programming languages.
- C, C++ and Pascal allow function pointers as arguments to other functions. Other 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, Smalltalk, 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, Smalltalk, PHP (since 5.3.0),[3] 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.
- In object-oriented programming languages without function-valued arguments, such as Java, 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. They are useful in implementing various design patterns such as Visitor, Observer, and Strategy.
- 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.
Use
JavaScript
Callbacks are used in the implementation of languages such as JavaScript, including support of JavaScript functions as callbacks through js-ctypes[4] and in components such as addEventListener.[5] However, a naive example of a callback can be written without any complex code:
function someAction(x, y, someCallback) {
return someCallback(x, y);
}
function calcProduct(x, y) {
return x * y;
}
function calcSum(x, y) {
return x + y;
}
// alerts 75, the product of 5 and 15
alert(someAction(5, 15, calcProduct));
// alerts 20, the sum of 5 and 15
alert(someAction(5, 15, calcSum));
First a function someAction is defined with a parameter intended for callback: someCallback
. Then a function that can be used as a callback to someAction
is defined, calcProduct
. Other functions may be used for someCallback
, like calcSum
. In this example, someAction()
is invoked twice, once with calcProduct
as a callback and once with calcSum
. The functions return the product and sum, respectively, and then the alert will display them to the screen.
In this primitive example, the use of a callback is primarily a demonstration of principle. One could simply call the callbacks as regular functions, calcProduct(x, y)
. Callbacks are generally useful when the function needs to perform actions before the callback is executed, or when the function does not (or cannot) have meaningful return values to act on, as is the case for Asynchronous JavaScript (based on timers) or XMLHttpRequest requests. Useful examples can be found in JavaScript libraries such as jQuery where the .each() method iterates over an array-like object, the first argument being a callback which is performed on each iteration.
C
Callbacks have a wide variety of uses. For example, imagine a function that reads a configuration file and associates values with options. If the options are identified by a hash, then writing the function so that it takes a callback makes it more flexible: its user can choose whatever hashing algorithm is desired and the function will continue to work, since it uses the callback to turn option names into hashes; thus, callbacks allow the user of a function to fine-tune it at runtime. Another use is in error signaling. A Unix program, for example, might not want to terminate immediately when it receives SIGTERM; to make sure things get taken care of, 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 code in C demonstrates the use of callbacks to display two numbers.
#include <stdio.h>
#include <stdlib.h>
/* The calling function takes a single callback as a parameter. */
void PrintTwoNumbers(int (*numberSource)(void)) {
printf("%d and %d\n", numberSource(), numberSource());
}
/* 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) {
PrintTwoNumbers(&rand);
PrintTwoNumbers(&overNineThousand);
PrintTwoNumbers(&meaningOfLife);
return 0;
}
This should provide output similar to:
125185 and 89187225 9084 and 9441 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>
typedef struct _MyMsg {
int appId;
char msgbody[32];
} MyMsg;
void myfunc(MyMsg *msg)
{
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);
}
/*
* Prototype declaration
*/
void (*callback)(MyMsg *);
int main(void)
{
MyMsg msg1;
msg1.appId = 100;
strcpy(msg1.msgbody, "This is a test\n");
/*
* Assign the address of the function 'myfunc' to the function
* pointer 'callback'
*/
callback = myfunc;
/*
* Call the function
*/
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 serialised communications and tabular data. [clarification needed]
Python
A classic usage of callbacks in Python (and other languages) is to assign events to UI elements.
Here is a very trivial example of the use of a callback in Python. First define two functions, the callback and the calling code, then pass the callback function into the calling code.
def my_callback(input):
print "function my_callback was called with %s input" % (input,)
def caller(input, func):
func(input)
for i in range(5):
caller(i, my_callback)
This results in the following output on standard out.
function my_callback was called with 0 input function my_callback was called with 1 input function my_callback was called with 2 input function my_callback was called with 3 input function my_callback was called with 4 input
See also
- Continuation-passing style
- Signals and slots
- Event loop
- Event-driven programming
- libsigc++, a callback library for C++
- Implicit invocation
- User exit
- Inversion of control
References
- ^ "Perl Cookbook - 11.4. Taking References to Functions". Retrieved 2008-03-03.
- ^ "Advanced Perl Programming - 4.2 Using Subroutine References". Retrieved 2008-03-03.
- ^ "PHP Language Reference - Anonymous functions". Retrieved 2011-06-08.
- ^ "Callbacks". Mozilla Developer Network. Retrieved 13 December 2012.
- ^ "Creating Javascript Callbacks in Components". Mozilla Developer Network. Retrieved 13 December 2012.
External links
- Style Case Study #2: Generic Callbacks
- Basic Instincts: Implementing Callback Notifications Using Delegates
- Implement Script Callback Framework in ASP.NET
- Implement callback routines in Java
- Interfacing C++ member functions with C libraries
- Callback interface implemented within the operational system