Content deleted Content added
Phillipw12 (talk | contribs) Made the random function actually work, as the function did not set a seed value before running the example code |
Added missing space. |
||
(98 intermediate revisions by 59 users not shown) | |||
Line 1:
{{Short description |A function reference passed to and called by another function}}
{{For |a discussion of callback with computer [[modem]]s |Callback (telecommunications)}}
{{More references |date=September 2015}}
[[File:Callback-notitle.svg|thumb|370px|A callback is often back on the level of the original caller.]]
In [[computer programming]], a '''callback''' is [[programming pattern]] in which a [[Function (computer programming)|function]] [[reference (computer science)|reference]] is passed from one context (consumer) to another (provider) such that the provider can call the function. If the function accesses [[state (computer science)|state]] or [[function (computer programming)|functionality]] of the consumer, then the call is ''back'' to the consumer; backwards compared to the normal [[flow of control]] in which a consumer calls a provider.
A function that accepts a callback [[Parameter (computer programming)|parameter]] may be designed to call back before [[Return statement |returning]] to its caller. But, more typically, a callback reference is stored by the provider so that it can call the function later; as ''deferred''. If the provider invokes the callback on the same [[thread (computer programming)|thread]] as the consumer, then the call is ''blocking'', a.k.a. ''[[Synchronization (computer science)|synchronous]]''. If instead, the provider invokes the callback on a different thread, then the call is ''[[Non-blocking algorithm |non-blocking]]'', a.k.a. ''asynchronous''.
A callback can be likened to leaving instructions with a tailor for what to do when a suit is ready, such as calling a specific phone number or delivering it to a given address. These instructions represent a callback: a function provided in advance to be executed later, often by a different part of the system and not necessarily by the one that received it.
The difference between a general function reference and a callback can be subtle, and some use the terms interchangeably but distinction generally depends on programming intent. If the intent is like the [[callback (telecommunications)|telephone callback]] {{endash}} that the original [[called party]] communicates back to the original [[calling party |caller]] {{endash}} then it's a callback.
== {{Anchor |TYPES}}Use ==
A blocking callback runs in the [[Execution (computing)|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 (computing)|thread]]. As such, a deferred callback can be used for synchronization and delegating work to another thread.
=== Event handling ===
A callback can be used for event handling. Often, consuming code registers a callback for a particular type of event. When that event occurs, the callback is called. 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 [[computer mouse|mouse]] clicks and [[computer keyboard|key]] presses.
=== Asynchronous action ===
A callback can be used to implement asynchronous processing.
A caller requests an action and provides a callback to be called when the action completes which might be long after the request is made.
=== Polymorphism ===
A callback can be used to implement [[Polymorphism (computer science)|polymorphism]]. In the following pseudocode, {{code|say_hi}} can take either {{code|write_status}} or {{code|write_error}}.
<syntaxhighlight lang="python">
def write_status(message: str):
write(stdout, message)
def write_error(message: str):
write(stderr, message)
def say_hi(write):
write("Hello world")
</syntaxhighlight>
== Implementation ==
The callback technology is implemented differently by [[programming language]].
In [[Assembly language|assembly]], [[C (programming language)|C]], [[C++]], [[Pascal (programming language)|Pascal]], [[Modula2]] and other languages, a callback function is stored internally as a [[function pointer]]. Using the same storage allows different languages to directly share callbacks without a [[program lifecycle phase|design-time or runtime]] [[interoperability]] [[Abstraction layer|layer]]. For example, the [[Windows API]] is accessible via multiple languages, compilers and assemblers.C++ also allows objects to provide an implementation of the function call operation. The [[Standard Template Library]] accepts these objects (called ''[[function object|functors]]'') as parameters.Many [[Dynamic programming language|dynamic languages]], such as [[JavaScript]], [[Lua (programming language)|Lua]], [[Python (programming language)|Python]], [[Perl]]<ref>{{cite web |url=http://www.unix.org.ua/orelly/perl/cookbook/ch11_05.htm |title=Perl Cookbook - 11.4. Taking References to Functions|date=2 July 1999 |accessdate=2008-03-03}}</ref><ref>{{cite web |url=http://www.unix.org.ua/orelly/perl/advprog/ch04_02.htm |title=Advanced Perl Programming - 4.2 Using Subroutine References |date=2 July 1999 |accessdate=2008-03-03}}</ref> and [[PHP]], allow a function object to be passed.[[List of CLI languages|CLI languages]] such as [[C Sharp (programming language)|C#]] and [[VB.NET]] provide a [[type safety|type-safe]] encapsulating function reference known as [[Delegate (CLI)|delegate]]. Events and [[event handlers]], as used in .NET languages, provide 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.
Many languages, including Perl, Python, [[Ruby (programming language)|Ruby]], [[Smalltalk]], [[C++]] (11+), C# and VB.NET (new versions) and most functional languages, support [[lambda (programming)|lambda expressions]], unnamed functions with inline syntax, that generally acts as callbacks..In some languages, including [[Scheme (programming language)|Scheme]], [[ML (programming language)|ML]], JavaScript, Perl, Python, Smalltalk, PHP (since 5.3.0),<ref>{{cite web |url=https://secure.php.net/manual/en/functions.anonymous.php |title=PHP Language Reference - Anonymous functions | accessdate=2011-06-08}}</ref> C++ (11+), Java (since 8),<ref>{{cite web |url=http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html|title=What's New in JDK 8|work=oracle.com}}</ref> and many others, a lambda can be a [[Closure (computer science)|closure]], i.e. can access variables locally defined in the context in which the lambda is defined.In an [[object-oriented programming]] language such as [[Java (programming language)|Java]] versions before function-valued arguments, the behavior of a callback can be achieved by passing an object that implements an interface. The methods of this object are callbacks.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. <ref>{{cite book |editor1-last=Belzer |editor1-first=Jack |editor2-last=Holzman |editor2-first=Albert G |editor3-last=Kent |editor3-first=Allen |title=Encyclopedia of Computer Science and Technology: Volume 12 |date=1979 |publisher=Marcel Dekker, inc. |isbn=0-8247-2262-0 |page=164 |url=https://books.google.com/books?id=IFmaqTI9-KsC&pg=PA164 |access-date=January 28, 2024}}</ref>
==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.In the following [[C (programming language)|C]] code, function <code>print_number</code> uses parameter <code>get_number</code> as a blocking callback. <code>print_number</code> is called with <code>get_answer_to_most_important_question</code> which acts as a callback function. When run the output is: "Value: 42".
<syntaxhighlight lang="c">
#include <stdio.h>
#include <
void print_number(int (*get_number)(void)) {
int
printf("Value: %d\n", val);
}
int get_answer_to_most_important_question(void) {
return 42;
}
int main(void) {
print_number(get_answer_to_most_important_question);
return 0;
}
</syntaxhighlight>
=== C++ ===
In C++, [[Function object|functor]] can be used in addition to function pointer.
=== C# ===
In the following [[C Sharp (programming language)|C#]] code,
method <code>Helper.Method</code> uses parameter <code>callback</code> as a blocking callback. <code>Helper.Method</code> is called with <code>Log</code> which acts as a callback function. When run, the following is written to the console: "Callback was: Hello world".
<syntaxhighlight lang="c#">
public class
{
static void Main(string[] args)
{
helper.Method(Log);
}
static void Log(string str)
{
Console.WriteLine($"Callback was: {str}");
Line 163 ⟶ 98:
}
public class
{
public void Method(Action<string> callback)
{
}
}
</syntaxhighlight>
===
In the following [[Kotlin (programming language)|Kotlin]] code, function <code>askAndAnswer</code> uses parameter <code>getAnswer</code> as a blocking callback. <code>askAndAnswer</code> is called with <code>getAnswerToMostImportantQuestion</code> which acts as a callback function. Running this will tell the user that the answer to their question is "42".
<syntaxhighlight lang="kotlin">
fun main() {
print("Enter the most important question: ")
val question = readLine()
askAndAnswer(question, ::getAnswerToMostImportantQuestion)
}
fun getAnswerToMostImportantQuestion(): Int {
return
}
fun askAndAnswer(question: String?, getAnswer: () -> Int) {
println("Question: $question")
println("Answer: ${getAnswer()}")
}
</syntaxhighlight>
=== JavaScript ===
In the following [[JavaScript]] code, function <code>calculate</code> uses parameter <code>operate</code> as a blocking callback. <code>calculate</code> is called with <code>multiply</code> and then with <code>sum</code> which act as callback functions.
<syntaxhighlight lang="javascript">
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));
</syntaxhighlight>
The collection method {{code|.each()}} of the [[jQuery]] [[JavaScript libraries|library]] uses the function passed to it as a blocking callback. It calls the callback for each item of the collection. For example:
<syntaxhighlight lang="javascript">
$("li").each(function(index) {
console.log(index + ": " + $(this).text());
});
</syntaxhighlight>
Deferred callbacks are commonly used for handling events from the user, the client and timers. Examples can be found in {{code|addEventListener}}, [[Ajax (programming)|Ajax]] and <code>[[XMLHttpRequest]]</code>.
<ref>{{cite web |url=https://udn.realityripple.com/docs/Mozilla/Creating_JavaScript_callbacks_in_components#JavaScript_functions_as_callbacks |title=Creating JavaScript callbacks in components |department=Archive |website=UDN Web Docs |at=sec. JavaScript functions as callbacks |language=en |type=Documentation page |accessdate=2021-12-16 |url-status=live|archive-url=https://web.archive.org/web/20211216020616/https://udn.realityripple.com/docs/Mozilla/Creating_JavaScript_callbacks_in_components |archive-date=2021-12-16 }}</ref>
In addition to using callbacks in JavaScript source code, C functions that take a function are supported via js-ctypes.<ref>{{cite web |url=https://developer.mozilla.org.cach3.com/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks<!--This page is not properly rendered--> |title=Declaring and Using Callbacks |editor1-last=Holley |editor1-first=Bobby |editor2-last=Shepherd |editor2-first=Eric |department=Docs |website=[[Mozilla Developer Network]] |language=en |type=Documentation page |accessdate=2021-12-16 |url-status=live |archive-url=https://web.archive.org/web/20190117092921/https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks |archive-date=2019-01-17}}</ref>
=== Red and REBOL ===
* 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.
Line 242 ⟶ 199:
; alerts 20, the sum of 5 and 15
alert form calculate 5 15 :calc-sum
</syntaxhighlight>
=== Rust ===
[[Rust (programming language)|Rust]] have the {{Code|Fn}}, {{Code|FnMut}} and {{Code|FnOnce}} traits.<ref>{{cite web |title=Fn in std::ops - Rust |url=https://doc.rust-lang.org/std/ops/trait.Fn.html |website=doc.rust-lang.org |access-date=18 January 2025}}</ref>
<syntaxhighlight lang="rust">
fn call_with_one<F>(func: F) -> usize
where F: Fn(usize) -> usize {
func(1)
}
let double = |x| x * 2;
assert_eq!(call_with_one(double), 2);
</syntaxhighlight>
===Lua===
In this [[Lua]] code, function {{code|calculate}} accepts the {{code|operation}} parameter which is used as a blocking callback. {{code|calculate}} is called with both {{code|add}} and {{code|multiply}}, and then uses an [[anonymous function]] to divide.
<syntaxhighlight lang="lua">function calculate(a, b, operation)
return operation(a, b)
end
function
return a * b
end
function add(a, b)
return a + b
end
print(calculate(10, 20, multiply)) -- outputs 200
print(calculate(10, 20, add)) -- outputs 30
-- an example of a callback using an anonymous function
print(calculate(10, 20, function(a, b)
return a / b -- outputs 0.5
end))</syntaxhighlight>
=== Python ===
In the following [[Python (programming language)|Python]] code, function {{code|calculate}} accepts a parameter {{code|operate}} that is used as a blocking callback. {{code|calculate}} is called with {{code|square}} which acts as a callback function.
<syntaxhighlight lang="python">
def square(val):
return val ** 2
def calculate(operate, val):
return operate(val)
calculate(square, 5) # outputs: 25
</syntaxhighlight>
===
In the following [[Julia (programming language)|Julia]] code, function {{code|calculate}} accepts a parameter {{code|operate}} that is used as a blocking callback. {{code|calculate}} is called with {{code|square}} which acts as a callback function.
<syntaxhighlight lang="
square (generic function with 1 method)
julia> calculate(operate, val) = operate(val)
calculate (generic function with 1 method)
julia> calculate(square, 5)
25
</syntaxhighlight>
Line 319 ⟶ 282:
== External links ==
* [https://
* [https://web.archive.org/web/20080916192721/http://www.javaworld.com/javaworld/javatips/jw-javatip10.html Implement callback routines in Java]
* [https
*
* [http://gotw.ca/gotw/083.htm Style Case Study #2: Generic Callbacks]
[[Category:Articles with example C code]]
[[Category:Articles with example C++ code]]
[[Category:Articles with example C Sharp code]]
[[Category:Articles with example JavaScript code]]
[[Category:Articles with example Julia code]]
[[Category:Articles with example Python (programming language) code]]
[[Category:Articles with example Rust code]]
[[Category:Subroutines]]
|