5

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.

  • 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. – GlenH7 Aug 11 '15 at 14:24
  • I am trying to understand how functions can work with implicit parameters. – BarryBones41 Aug 11 '15 at 14:27
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 */
}
  • 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. – BarryBones41 Aug 11 '15 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. – Céryl Wiltink Aug 12 '15 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".

  • 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. – BarryBones41 Aug 11 '15 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 '15 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 '15 at 14:32
  • @Telastyn You're right - I really didn't know how use the correct terms here. – BarryBones41 Aug 11 '15 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, privacy policy and cookie policy

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