6

Callback functions are able to accept some parameters, but they are not explicitly declared when calling the function.

How does this actually work? What is going on that allows us to pass a function as a parameter to another function, and implicitly include a parameter in there?

For example:

Javascript

$.get('somefile.php', {func : 'getUserNames'}).done(function(data){
    if(data)
       console.log(data); // '{"0" : "billy", "1" : "bobby"}'
    // This is a js ajax call to a php file. 
    // How exactly am I retrieving "data" ?
}, 'json');

C#

private void BeginReadingData(){
    NetworkStream stream = tcpClient.GetStream();
    stream.BeginRead(buffer, 0, bufferSize, MyCallBack, tcpClient);
}

private void MyCallBack(IAsyncResult ar){
    // Now I can operate on 'ar'
    // why and how? 
}

This is something I understand how to use, just not how to explain or correctly describe the process.

2
  • Are you asking how to name a callback? If so, naming things questions tend to be closed as primarily opinion based and aren't considered constructive for the site. Are you instead really asking about the scope of variables that a callback has access to? That would be on-topic, but your question would be stronger if you focused on a specific aspect of that question.
    – user53019
    Aug 11, 2015 at 14:24
  • I am trying to understand how functions can work with implicit parameters. Aug 11, 2015 at 14:27

3 Answers 3

4

What do you call a callback function that accepts some parameters, but they are not explicitly declared when calling the function?

I'm not sure. In certain cases an object's method may be considered to have the object itself as an implicit parameter.

But there are no function calls with implicit parameters your examples. With a callback, you don't pass the result of calling the function, you pass the function itself.

stream.BeginRead(buffer, 0, bufferSize,
    MyCallBack, /* <- Not a function call, just a reference to a function. */
    tcpClient);

The function that you gave the callback, in these cases $.get and stream.BeginRead will call the callback function you gave them, and explicitly give it the parameters that it should take.

So what you're missing here is the definition of stream.BeginRead has something like:

public virtual ISyncResult BeginRead(
        byte[] buffer,
        int offset,
        int count,
        AsyncCallback callback,
        Object state
    ) {
    /* stuff */

    callback(ar); /* <-- called with explicit parameter */

    /* more stuff */
}
2
  • Thanks, that was what I was trying to explain. I guess it is really obvious - you are passing a function as an argument. It is just hard to see when the function is not your own, and you cannot inspect how the passed function will work. Aug 11, 2015 at 14:40
  • 1
    @BarryBones41 A little tip to see what parameters you need to declare for your callback in JavaScript: In your browser, set "debugger;" as the first statement in your callback. Run the code in your browser and when it halts on the breakpoint, use the "Watch"-option to inspect the "arguments" variable. This is a hidden JS variable that holds a (pseudo-)array of all arguments passed in the function, regardless of whether or not you defined them in your callback signature. Aug 12, 2015 at 11:02
2

What do you call a callback function that accepts some parameters, but they are not explicitly declared when calling the function?

I'm not sure what you're talking about.

function(data) explicitly declares a parameter named data for the anonymous function.

private void MyCallBack(IAsyncResult ar) explicitly declares a parameter named ar with the type IAsyncResult for the function named MyCallback.

They both make that identifier available to the body of the function, and the compiler/interpreter knows to translate that identifier resolution to "access the first argument of this function".

4
  • Maybe the js example is bad. But for C# I am saying they are not explicitly declared when **calling** the function. Look at the way MyCallBack is called. No arguments are passed to it. Aug 11, 2015 at 14:28
  • 1
    @BarryBones41 - of course not, that's because you're not calling MyCallBack - the function itself is the argument.
    – Telastyn
    Aug 11, 2015 at 14:31
  • MyCallback is not called by you, it is passed by you into the BeginRead method, which expects a callback that fits a certain pattern, in this case XYZ(IAsyncResult result). BeginRead somewhere calls your MyCallBack delegate with the IAsyncResult.
    – ElDuderino
    Aug 11, 2015 at 14:32
  • @Telastyn You're right - I really didn't know how use the correct terms here. Aug 11, 2015 at 14:38
0

In C#, the callbacks are mere delegates. Delegates wrap your callback method inside a object and that object is passed as a parameter. So, whenever you are passing a callback function, lets say an event handler, that event handler is wrapped in a delegate object. Now when the proper time of invocation comes, the corresponding element, in your example, the 'NetworkStream' object checks whether any callback is registered. If found (in your case - 'MyCallback' is registered), it then invokes the registered callback.

In JavaScript, by design, methods are nothing but objects itself. so, whenever you are passing a callback function, you are passing a object. As JavaScript does compile, it does not check the signature of the callback you are passing. If it has the proper signature (e.g. - having proper number of parameters) the callback will receive all the values, if the signature is mismatched, your callback will miss the result values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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