 | Callback computer science: Encyclopedia II - Callback computer science - Motivation
Callback computer science - Motivation
To understand the motivation for using callbacks, consider the problem of performing an arbitrary operation on each item in a list. One approach is to obtain an iterator over the list, and then operate on successive objects obtained from the iterator. This is the most common solution in practice, but it is not ideal; the code to manage the iterator must be duplicated at each point in the code where the list is traversed. Furthermore, if the list is updated by an asynchronous process, the iterator might skip over items or become corrupt during the traversal.
An alternative might be to create a new library function that performs the desired operation with appropriate synchronization. This approach still requires each new library function to contain the code to traverse the list. This solution is not acceptable for libraries intended for broad applications; the library developer cannot anticipate every application need, and the application developer should not need to know the details of the library implementation.
Callbacks solve these shortcomings. One procedure is written to traverse the list, and this procedure uses application-provided code to operate on each item. There is a clear distinction between the library and the application without sacrificing flexibility.
The following code in C demonstrates the use of callbacks for the specific case of searching an array for an item (namely, the first integer greater than 5). First, the iteration approach:
for(i = 0; i < length; i++) {
if(array[i] > 5)
break;
}
if(i < length) {
printf("Item %d\n", i);
} else {
printf("Not found\n");
}
Next, the callback approach:
/* LIBRARY CODE */
int traverseWith(int array[], size_t length,
int (*callback)(int index, int item, void *param),
void *param)
{
int exitCode = 0;
for(i = 0; i < length; i++) {
exitCode = callback(i, array[i], param);
if(exitCode) {
break;
}
}
return exitCode;
}
/* APPLICATION CODE */
int search(int index, int item, void *param)
{
if(item > 5) {
*(int *)param = index;
return 1;
} else {
return 0;
}
}
/* (in another function) */
int index;
int found;
found = traverseWith(array, length, search, &index);
if(found) {
printf("Item %d\n", index);
} else {
printf("Not found\n");
}
In this example the callback receives an extra parameter so that it can access data from the calling scope (a form of closure). Other languages, particularly functional programming languages, can provide this access automatically. Synchronization concerns have been omitted from these examples, but they can easily be addressed in the traverseWith function. More importantly, they can be addressed, or ignored, by changing only that function.
Other related archivesBoolean, C, C++, Interrupt handlers, ML, Observer, Scheme, Standard Template Library, Strategy, Visitor, callback (telecommunications), closure, closures, code reuse, computer science, design patterns, eval, event handlers, function pointers, functional programming languages, generic programming, idempotent, interpreted languages, iterator, library, modems, object-oriented programming languages, operating system, polymorphism, process, programming languages, scope, side-effects, signal handlers
 Adapted from the Wikipedia article "Motivation", under the G.N U Free Docmentation License. Please also see http://en.wikipedia.org/wiki |