www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing a function as an argument to another function : what is this

reply "Derix" <derix dexample.com> writes:
Hello everyone,

So I'm "Getting Started With Gtkd" [1] and the tuto includes this
piece of code :

...

        DrawingArea da = new DrawingArea(590, 200);
        da.addOnDraw(&onDraw);
        layout.put(da, 5, 30);

        add(layout);  // Add the layout to our main window
        showAll();
     }

     bool onDraw(Context c, Widget w)
     {
        //draw things
        return true;
     }
}

and I'm a bit puzzled by the line
        da.addOnDraw(&onDraw);

I'm pretty sure I've met this construct before along with
relevant explainations, but I find myself a bit forgetful and in
need of a refresher. Hence questions :

1) What is the generic name for this kind construct ?

2) Any hint to some reading about the supporting theory or
rationale ?

3) When the onDraw function is actually called, whence does it
takes its arguments from ? What is that Context ? Does it float
around as some sort of implicit global object ? When was it
instanciated ?

4) Is &onDraw a predefined event belonging to the class
DrawingArea ? Is the name of the onDraw function thus constrained
?

5) What is the chain of events leading to the "onDraw" event
occuring ? I'd guess it's the 'showAll()' line, but by the way
where does this 'showAll()' come from ? In the documentation [2],
I don't see it as a method belonging to the class DrawingArea. Is
it inherited from a superclass ?



Thank you for the enlightment !



------------------------------------------------------------------------------------------------
[1] http://britseyeview.com/software/articles/gsgtkd102.html
[2] http://api.gtkd.org/src/gtk/DrawingArea.html
May 25 2014
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/25/2014 02:37 AM, Derix wrote:

         DrawingArea da = new DrawingArea(590, 200);
         da.addOnDraw(&onDraw);
         layout.put(da, 5, 30);

         add(layout);  // Add the layout to our main window
         showAll();
      }

      bool onDraw(Context c, Widget w)
      {
         //draw things
         return true;
      }
 }

 and I'm a bit puzzled by the line
         da.addOnDraw(&onDraw);

 I'm pretty sure I've met this construct before along with
 relevant explainations, but I find myself a bit forgetful and in
 need of a refresher. Hence questions :

 1) What is the generic name for this kind construct ?
Function pointer. What you are showing is a "callback function" usage.
 2) Any hint to some reading about the supporting theory or
 rationale ?
I have some documentation here: http://ddili.org/ders/d.en/lambda.html
 3) When the onDraw function is actually called, whence does it
 takes its arguments from ?
da.addOnDraw() simply stores the function pointer (onDraw in this case) for later use. Later, it satisfies the call parameters by passing necessary Context and Widget objects that are known at that later time.
 What is that Context ? Does it float
 around as some sort of implicit global object ? When was it
 instanciated ?
The library manages those objects. Ali
May 25 2014
prev sibling next sibling parent Rikki Cattermole <alphaglosined gmail.com> writes:
On 25/05/2014 9:37 p.m., Derix wrote:
 Hello everyone,

 So I'm "Getting Started With Gtkd" [1] and the tuto includes this
 piece of code :

 ...

         DrawingArea da = new DrawingArea(590, 200);
         da.addOnDraw(&onDraw);
         layout.put(da, 5, 30);

         add(layout);  // Add the layout to our main window
         showAll();
      }

      bool onDraw(Context c, Widget w)
      {
         //draw things
         return true;
      }
 }

 and I'm a bit puzzled by the line
         da.addOnDraw(&onDraw);

 I'm pretty sure I've met this construct before along with
 relevant explainations, but I find myself a bit forgetful and in
 need of a refresher. Hence questions :

 1) What is the generic name for this kind construct ?
In this case &onDraw is a pointer to a member function aka delegate. There is two types of pointers for code sections, function and delegates. A function is a raw pointer (essentially) and a delegate is a pointer to function + "this" pointer.
 2) Any hint to some reading about the supporting theory or
 rationale ?

 3) When the onDraw function is actually called, whence does it
 takes its arguments from ? What is that Context ? Does it float
 around as some sort of implicit global object ? When was it
 instanciated ?
As I said above, for a delegate, it includes a context pointer. So you can assume the arguments defined by the method, are required to call it. Method decl: bool onDraw(Context c, Widget w) Callable: bool delegate(Context, Widget) myEventFunc = ... bool res = myEventFunc(myContext, myWidget);
 4) Is &onDraw a predefined event belonging to the class
 DrawingArea ? Is the name of the onDraw function thus constrained
 ?

 5) What is the chain of events leading to the "onDraw" event
 occuring ? I'd guess it's the 'showAll()' line, but by the way
 where does this 'showAll()' come from ? In the documentation [2],
 I don't see it as a method belonging to the class DrawingArea. Is
 it inherited from a superclass ?



 Thank you for the enlightment !



 ------------------------------------------------------------------------------------------------

 [1] http://britseyeview.com/software/articles/gsgtkd102.html
 [2] http://api.gtkd.org/src/gtk/DrawingArea.html
May 25 2014
prev sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Sunday, 25 May 2014 at 09:37:46 UTC, Derix wrote:
 Hello everyone,

 So I'm "Getting Started With Gtkd" [1] and the tuto includes 
 this
 piece of code :

 ...

        DrawingArea da = new DrawingArea(590, 200);
        da.addOnDraw(&onDraw);
        layout.put(da, 5, 30);

        add(layout);  // Add the layout to our main window
        showAll();
     }

     bool onDraw(Context c, Widget w)
     {
        //draw things
        return true;
     }
 }

 and I'm a bit puzzled by the line
        da.addOnDraw(&onDraw);

 I'm pretty sure I've met this construct before along with
 relevant explainations, but I find myself a bit forgetful and in
 need of a refresher. Hence questions :

 1) What is the generic name for this kind construct ?

 2) Any hint to some reading about the supporting theory or
 rationale ?
It's basically passing an existing function via a pointer. Notice the ampersand (&)? That gets the underlying memory location (i.e. pointer). Normal procedural type functions can be passed like this as can methods of classes (if you have access to them). When passing a class method like this it can be referred to as passing a delegate. Delegates internally store another pointer to it's surrounding context. For example, a function can be passed like this: void foo() { // Do something. } bar.addFoo(&foo); Then in the addFoo method foo can be called as if it was a normal function. You can also write the above like this: bar.addFoo(function(){ // Do something. }); As function literals are passed via a pointer by default so no ampersand needed. The problem is that normal functions can not refer to anything outside of their scope. For this you need a delegate which contains a context pointer (which is a reference to it's surroundings). Here is an example if using a class method. class Foo { public void bar() { // Do something. } public void baz() { // Refers to bar outside of this method's scope. this.bar(); } } auto foo = new Foo(); // baz can refer to the instance of Foo (it's context) // so it can call bar. qux.addBaz(&foo.baz); You can also use the literal notation too: qux.addBaz(delegate(){ // I can now use things outside this scope. }); Like function literals, delegates are also passed by their pointer by default.
 3) When the onDraw function is actually called, whence does it
 takes its arguments from ? What is that Context ? Does it float
 around as some sort of implicit global object ? When was it
 instanciated ?
When passing functions or methods like this they need to be typed just like anything else you would pass as an argument. Like this: alias void delegate(string) MyCallback; Here we define the signature of a delegate using an alias. Once a method is defined taking this alias as a type then it will only accept a delegate with this signature. class Foo { // Only accept 'void delegate(string)' void bar(MyCallback baz) { // call conforming to the MyCallback signature. baz("hello world"); <-- } } auto foo = new Foo(); // Passed delegate conforms to the MyCallback signature. foo.bar(delegate(string x){ writeln(x); }); Functions are typed the same way: alias void function(string) MyCallback;
 4) Is &onDraw a predefined event belonging to the class
 DrawingArea ? Is the name of the onDraw function thus 
 constrained
 ?
onDraw will just be a method that accepts a delegate (or standard function).
 5) What is the chain of events leading to the "onDraw" event
 occuring ? I'd guess it's the 'showAll()' line, but by the way
 where does this 'showAll()' come from ? In the documentation
I've no idea you'll have to read the source to find that out.
 I don't see it as a method belonging to the class DrawingArea. 
 Is
 it inherited from a superclass ?
Probably.
May 25 2014