15

I am reading the book programming in Lua. It said that

Closures provide a valuable tool in many contexts. As we have seen, they are useful as arguments to higher-order functions such as sort. Closures are valuable for functions that build other functions too, like our newCounter example; this mechanism allows Lua programs to incorporate sophisticated programming techniques from the functional world. Closures are useful for callback functions, too. A typical example here occurs when you create buttons in a conventional GUI toolkit. Each button has a callback function to be called when the user presses the button; you want different buttons to do slightly different things when pressed. For instance, a digital calculator needs ten similar buttons, one for each digit. Y ou can create each of them with a function like this:

function digitButton (digit)
  return Button{label = tostring(digit),
                action = function ()
                  add_to_display(digit)
                  end}
end

It seems that if I call the digitButton, it will return the action (this will create a closure), so, I can access the digit passed to digitButton.

My question is that:

Why we need call back functions? what situations can I apply this to?


The author said:

In this example, we assume that Button is a toolkit function that creates new buttons; label is the button label; and action is the callback closure to be called when the button is pressed. The callback can be called a long time after digitButton did its task and after the local variable digit went out of scope, but it can still access this variable.

according to the author, I think a similar example is like this:

function Button(t)
  -- maybe you should set the button here
  return t.action -- so that you can call this later
end

function add_to_display(digit)
  print ("Display the button label: " .. tostring(digit))
end

function digitButton(digit)
  return Button{label = tostring(digit),
                action = function ()
                           add_to_display(digit)
                           end}
end

click_action = digitButton(10)
click_action()

thus, the callback can be called a long time after digitButton did its task and after the local variable digit went out of scope.

1

10 Answers 10

45

Guy 1 to Guy 2: hey dude I wanna do something when a user clicks in there, call me back when that happens alright?

Guy 2 calls back Guy 1 when a user clicks here.

4
  • 1
    I like this call-back joke very much :-P
    – yanpengl
    Apr 23, 2013 at 15:28
  • 6
    Is it just me? I don't get how this explains why we need callback functions.
    – phant0m
    Apr 27, 2013 at 20:23
  • 2
    It's more like Guy 1 says to Guy 2 "when the time is right do this". Guy 2 goes about his day and when the time is right does that. If you meant Guy 1 to be the caller of Guy 2, then this is incorrect as Guy 2 doesn't call back Guy 1, he calls into the thing to do. In fact if Guy 1 is the caller of Guy 2 you'd have a hard loop on your hands in this scenario. If you meant Guy 1 to be the call back then this is incorrect as the callback has no idea who Guy 2 is and certainly doesn't ask him to call.
    – rism
    Jan 28, 2015 at 1:23
  • This is a horrible explanation.
    – insidesin
    Sep 29, 2017 at 6:59
21

No, it will never return the action. The button will execute it when the user clicks on it. And that is the answer. You need callback functions when you want to define actions that should happen in another component in reaction to an event you don't control (the event loop, which is part of the system, will execute a method of the button which will in turn execute the action).

4
  • I don't agree with you. I have edited my post and add some codes. I still think that the action isn't executed instantly.
    – yanpengl
    Apr 23, 2013 at 12:08
  • 2
    Tim, you're right - but so is Jan. "The button will execute it when the user clicks on it", not instantly. Apr 23, 2013 at 12:11
  • @AlexanderBrevig yeah, I still think Jan's reply is very useful for me. It lets me know what is call back and why we need call back.
    – yanpengl
    Apr 23, 2013 at 12:21
  • Callback is just a dirty name that someone added to a second function that works when the first is fired and maybe based on a criteria. Call your function well_done() and would not have difference. Callback is like to Verify, verify is a sequence of messages, usually two, and callback is a secuence of functions, usually two. If you chained more than 3 callbacks, congrats, you like to do things the hard way.
    – m3nda
    Jul 29, 2016 at 22:11
16

I think a better example for the use of callbacks is in asynchronous functions. I can't speak for Lua, but in JavaScript, one of the most common asynchronous action is contacting a server via AJAX.

The AJAX call is asynchronous, meaning if you do something like this:

var ajax = ajaxCall();
if(ajax == true) {
  // Do something
}

the contents of the if block will not reliably run correctly, and when it does, it's only because the ajaxCall() function happened to finish before the execution reached the if statement.

However, callbacks eliminate this issue, by ensuring the asynchronous call is finished before calling the required function. So, your code would change to something like this:

function ajaxCallback(response) {   
  if(response == true) {
    // Do something   
  }
}

ajaxCall(ajaxCallback);

The purpose of this is to allow you to do things like gather data, without interfering with other things, such as drawing the interface. If the data gathering was synchronous, then the interface would become unresponsive as the application waited to get the data. An unresponsive interface is very bad for user experience, because most users will think the application has "crashed" and will try to terminate the process.

To see this in action, you just need to look at any website that does any kind of updating without reloading the whole page. Twitter, LinkedIn, and the StackExchange sites are good examples. Twitter's "endless scrolling" of feeds, and SE's notifications (for both user notifications, and notifications that a question has new activity), are powered by asynchronous calls. When you see a spinner somewhere, that means that section has made an asynchronous call, and is waiting for that call to finish, but you can interact with other things on the interface (and even make other asynchronous calls). Once that call finishes, it will react and update the interface accordingly.

12

You asked the question

Why we need "call back functions"?

I will try to answer it in a concise and clear manner (if I fail at that, please refer to the wiki link at the bottom of this answer).

Callbacks are used to defer the specific implementation of something to the last possible moment.

The button example is a good illustration of this. Say you want to have a button in your application that prints a page to the printer, we could imagine a world where you would have to code an entire new PrinterButton class in order to do this.

Luckily, we have the notion of callbacks (inheritence and the use of the template pattern is also a kind of callback semantic) so we do not need to do that.

Instead of re-implementing every aspect of a button, what we do is to add to the implementation of the button. The Button has the concept of doing something when it's pressed. We simply tell it what that something is.

That mechanism of injecting behavior into frameworks is called callbacks.

Example:

Let's inject some behavior into an HTML button:

<button onclick="print()">Print page through a callback to the print() method</button>

In this instance, onclick points to a callback, which for this example is the print() method.


http://en.wikipedia.org/wiki/Callback_(computer_programming)

2
  • Thanks, after reading your illustration, I go to read the wiki whose examples are only synchronous callbacks.
    – yanpengl
    Apr 24, 2013 at 1:59
  • tell a function the answer every time it has a problem and you have to listen for problems; teach a function to solve a problem it takes care of itself.
    – Joe
    Sep 11, 2016 at 11:36
8

Why we need call back functions? what situations can I apply this to?

Callback functions are very useful in event-driven programming. They allow you to set up your program in such a way that events will trigger the correct code. This is very common in programs with GUIs where users can click on any element on the UI (such as buttons or menu items) and the appropriate code will be run.

2
  • 1
    + That's what callbacks are good for, but I hate having to write them :-) Apr 23, 2013 at 15:07
  • When I was only a freshman, my teacher teached us how to program in MFC, but he never told us what is callback :-(
    – yanpengl
    Apr 24, 2013 at 2:01
2

What happens without callbacks:

Guy 1: Okay, I'm waiting for that thing to happen. (whistles, twiddles thumbs)

Guy 2: Dammit! Why is Guy 1 not showing me stuff? I want to see stuff happening!! Where's my stuff? How is anybody supposed to get anything done around here?

1

Firstoff, the term callback refers to a closure that is being used for something.

For example, suppose you create a closure function and just store it in a variable. It isn't a callback, because it isn't being used for anything.

But, suppose you create a closure and store it somewhere that it will get called when something happens. It is now termed a callback.

Usually, callbacks are created by different parts of the program than the parts that call them. So it's easy to imagine that some parts of the program are "calling back" the other parts.

Simply put, callbacks allow one part of the program to tell another part to do something (anything) when something happens.

As for variables being kept alive due to being used in a closure, that's a completely different feature called upvalues (a.k.a. "extending the lifetime of local variables" among those who don't speak Lua). And it's quite useful as well.

2
  • yeah, Extending the lifetime of local variables is also to say the term upvalue.
    – yanpengl
    Apr 24, 2013 at 7:03
  • Hmm, interesting. The term upvalue seems to be specific to Lua, although a quick Google search shows that it has occasionally been used to describe other languages. I'll add it to my answer. Apr 24, 2013 at 8:02
1

Callbacks have been around since the early days of Fortran, at least. For example, if you have an ODE (ordinary differential equation) solver, such as a Runge-Kutta solver, it might look like this:

subroutine rungekutta(neq, t, tend, y, deriv)
  integer neq             ! number of differential equations
  double precision t      ! initial time
  double precision tend   ! final time
  double precision y(neq) ! state vector
  ! deriv is the callback function to evaluate the state derivative
  ...
  deriv(neq, t, y, yprime) ! call deriv to get the state derivative
  ...
  deriv(neq, t, y, yprime) ! call it several times
  ...
end subroutine

It enables the caller to customize the behavior of the subroutine by passing it a special-purpose function to be called when necessary. This allows the ODE solver to be used to simulate a wide variety of systems.

1

Stumbled upon this and wanted to provide a more up to date answer...

Callback functions allow us to do something with data at a later time, allowing the rest of our code to run, instead of waiting for it. The asynchronous code allows us this luxury of executing anything later. The most readable example of callback functions I have come across are Promises in JavaScript. In the example below every time you see function(result) or (newResult) or (finalResult)... these are callback functions. The code within their curly brackets is executed once the data comes back from the server. Only at this point would it make sense to execute these functions since now the data they need is available.

doSomething().then(function(result) {
  return doSomethingElse(result);
})
.then(function(newResult) {
  return doThirdThing(newResult);
})
.then(function(finalResult) {
  console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);

the code is taken from... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

Hopefully, this helps someone. This is what helped ME understand callbacks :)

2
  • 1
    this doesn't seem to offer anything substantial over points made and explained in prior 9 answers
    – gnat
    Mar 27, 2018 at 8:32
  • 1
    Maybe for you but this is what really made callbacks clear for me so I thought I would share. IMO the readability of the example is what makes it worthwhile. I'm sure we can agree readability of code goes a long way, especially for beginners.
    – NRV
    Mar 27, 2018 at 9:40
-2

I don't know lua but in general callback methods some what like multithreading. For example in mobile application development programming most of the applications are functioning like sending request to the server and playing with UI with the data came as response from the server. When the user sends a request to server, it will take time to get response from server but for best UX UI should not stuck.

Because of this we use multiple thread to do parallel operations. When we get the response from the server we need to update UI. we have to notify from that thread to update. from the functional world. This type of function calls are called callback methods. When you call these methods the controle should have return to the main thread. For example callback methods are blocks in objective-C.

2
  • yeah, what you said is consistent with my understanding after reading the book.
    – yanpengl
    Apr 24, 2013 at 1:16
  • 2
    Callback methods are nothing like multithreading. Callback methods are simply function pointers (delegates). Threads are about CPU context switching / utilisation. A highly simplified contrast would be that threading is about CPU optimisation for UX whereas callbacks are about memory switching for polymorphism. Simply because threads might execute callbacks does not mean that threading and callbacks are similar. Threads also execute static methods on static classes but threading and static types are not similar.
    – rism
    Jan 28, 2015 at 1:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.