digitalmars.D.learn - delegate bug?
- Jack Applegame (22/22) Nov 09 2012 This code:
- Jack Applegame (1/1) Nov 09 2012 Windows dmd 2.060
- Jacob Carlborg (16/38) Nov 09 2012 This is expected behavior. Delegates do not perform any dynamic
- Manfred Nowak (10/11) Nov 09 2012 This changes the environment only. It does not change the function
- Jack Applegame (2/2) Nov 09 2012 Ok. Then how to implement in D this С++ std::function feature?
- Manfred Nowak (10/13) Nov 09 2012 That feature is among others defined here:
- Jack Applegame (5/9) Nov 09 2012 This is not only std::function feature. In C++ we can call
- Timon Gehr (6/14) Nov 09 2012 auto memberFunctionPointer = function(X receiver, A arg0, B arg1, C
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (39/45) Nov 09 2012 The following D program produces the same output as the C++ example ther...
- Jack Applegame (35/35) Nov 09 2012 Ok. I will try to explain what exactly i need.
- Timon Gehr (36/38) Nov 09 2012 The following works. You can also use a (scoped) delegate in order to
- Jack Applegame (5/7) Nov 09 2012 Wow! Great! Thanks.
- Jack Applegame (1/1) Nov 09 2012 I have found it. This is shorthand lambda syntax.
- Jacob Carlborg (5/9) Nov 09 2012 It's a delegate literal, or also known as a lambda.
- Timon Gehr (25/32) Nov 09 2012 It is a lambda function literal. It is as if you did
This code: import std.stdio; class A { void func() { writeln("A"); } } class B : A { override void func() { writeln("B"); } } void main() { A a = new A; B b = new B; auto dg = &a.func; dg(); dg.ptr = cast(void*)b; dg(); } outputs: A A but expected: A B
Nov 09 2012
On 2012-11-09 14:36, Jack Applegame wrote:This code: import std.stdio; class A { void func() { writeln("A"); } } class B : A { override void func() { writeln("B"); } } void main() { A a = new A; B b = new B; auto dg = &a.func; dg(); dg.ptr = cast(void*)b; dg(); } outputs: A A but expected: A BThis is expected behavior. Delegates do not perform any dynamic dispatch. The method that is called is chosen when the delegate is created, i.e. "auto dg = &a.func;" You can workaround this by calling another method in "A" that will call the actual method you want to call, something like this: class A { void resolveVirtualCall () { func(); } } auto dg = &a.resolveVirtualCall; -- /Jacob Carlborg
Nov 09 2012
Jack Applegame wrote:dg.ptr = cast(void*)b;This changes the environment only. It does not change the function called on the``dg()'-request---and the function called does not depend on the environment. But including a dependence on the environment may not change the output, because the compiler may instruct the executable to memoize the output. Hint: casting is equivalent to exclaiming: "I know what I am doing. Therefore: shut up compiler!" .manfred
Nov 09 2012
Ok. Then how to implement in D this С++ std::function feature? http://liveworkspace.org/code/01aa058901529f65cb9a3cc4ba605248
Nov 09 2012
Jack Applegame wrote:Ok. Then how to implement in D this С++ std::function feature? http://liveworkspace.org/code/01aa058901529f65cb9a3cc4ba605248That feature is among others defined here: http://en.cppreference.com/w/cpp/utility/functional/function As one might see it is a template, defined in a library. Therefore the first question is, wether D has a similar template in a library---and secondly: without such a template in a library: how to implement the base functionality in a non-generic case. Because this is a learning group and not a teaching group--and you did not report on your fruitless tries: go on. -manfred
Nov 09 2012
Because this is a learning group and not a teaching group--and you did not report on your fruitless tries: go on. -manfredThis is not only std::function feature. In C++ we can call member-function by combining potinter to object and pointer to function: http://liveworkspace.org/code/1fe3107cf3a311aa95cb9fc62b9117a7 I have no idea how to do somethink like that in D.
Nov 09 2012
On 11/09/2012 07:49 PM, Jack Applegame wrote:auto memberFunctionPointer = function(X receiver, A arg0, B arg1, C arg2)=>receiver.memberFunction(arg0, arg1, arg2); This strategy is also the best way for a C++ compiler to implement a standard conformant member function pointer behind the scenes, so you lose nothing.Because this is a learning group and not a teaching group--and you did not report on your fruitless tries: go on. -manfredThis is not only std::function feature. In C++ we can call member-function by combining potinter to object and pointer to function: http://liveworkspace.org/code/1fe3107cf3a311aa95cb9fc62b9117a7 I have no idea how to do somethink like that in D.
Nov 09 2012
On 11/09/2012 10:30 AM, Manfred Nowak wrote:Jack Applegame wrote:The following D program produces the same output as the C++ example there: import std.stdio : writeln; import std.functional : curry; struct Foo { int num; void print_add(int i) { writeln(num + i); } } void print_num(int i) { writeln(i); } void main() { // store a free function auto f_display = &print_num; f_display(-9); // store a lambda auto f_display_42 = { print_num(42); }; f_display_42(); // store a curried call alias curry!(print_num, 31337) f_display_31337; f_display_31337(); // store a call to a member function auto f_add_display = (Foo foo, int i) { return foo.print_add(i); }; auto foo = Foo(314159); f_add_display(foo, 1); } D has more features: // store a call to a member function on a particular object auto f_print_add_on_object = &foo.print_add; f_print_add_on_object(2); There is also std.functional.toDelegate: http://dlang.org/phobos/std_functional.html#toDelegate AliOk. Then how to implement in D this С++ std::function feature? http://liveworkspace.org/code/01aa058901529f65cb9a3cc4ba605248That feature is among others defined here: http://en.cppreference.com/w/cpp/utility/functional/function
Nov 09 2012
Ok. I will try to explain what exactly i need. import std.stdio; import std.stdio; class Figure { void draw(){} void erase(){} } class Circle : Figure { override void draw() { writeln("drawing circle"); } override void erase() { writeln("erasing circle"); } } class Square : Figure { override void draw() { writeln("drawing square"); } override void erase() { writeln("erasing square"); } } class Triangle : Figure { override void draw() { writeln("drawing triangle"); } override void erase() { writeln("erasing triangle"); } } void main() { Figure[] figures; createFigures(figures); doAction(figures, &Figure.draw); doAction(figures, &Figure.erase); } void doAction(Figure[] figures, void function() action) { foreach(Figure figure; figures) { // how to do action with figure??? } } void createFigures(ref Figure[] figures) { figures ~= new Circle; figures ~= new Square; figures ~= new Triangle; }
Nov 09 2012
On 11/09/2012 09:13 PM, Jack Applegame wrote:Ok. I will try to explain what exactly i need. ...The following works. You can also use a (scoped) delegate in order to allow the caller to close over his context. import std.stdio; class Figure { void draw(){} void erase(){} } class Circle : Figure { override void draw() { writeln("drawing circle"); } override void erase() { writeln("erasing circle"); } } class Square : Figure { override void draw() { writeln("drawing square"); } override void erase() { writeln("erasing square"); } } class Triangle : Figure { override void draw() { writeln("drawing triangle"); } override void erase() { writeln("erasing triangle"); } } void main() { Figure[] figures; createFigures(figures); doAction(figures, x=>x.draw()); doAction(figures, x=>x.erase()); } void doAction(Figure[] figures, void function(Figure) action) { foreach(Figure figure; figures) { action(figure); } } void createFigures(ref Figure[] figures) { figures ~= new Circle; figures ~= new Square; figures ~= new Triangle; }
Nov 09 2012
On Friday, 9 November 2012 at 20:22:40 UTC, Timon Gehr wrote:The following works. You can also use a (scoped) delegate in order to allow the caller to close over his context.Wow! Great! Thanks. But I can't understend this syntax: x=>x.draw() Where i can read about it?
Nov 09 2012
I have found it. This is shorthand lambda syntax.
Nov 09 2012
On 2012-11-09 21:31, Jack Applegame wrote:Wow! Great! Thanks. But I can't understend this syntax: x=>x.draw() Where i can read about it?It's a delegate literal, or also known as a lambda. http://dlang.org/expression.html#Lambda -- /Jacob Carlborg
Nov 09 2012
On 11/09/2012 09:31 PM, Jack Applegame wrote:On Friday, 9 November 2012 at 20:22:40 UTC, Timon Gehr wrote:It is a lambda function literal. It is as if you did static void action(Figure x){ return x.draw(); } doAction(figures, &action); which can also be written in any of the following ways. Because the types are mandated by the function that is called, you can leave them out: doAction(figures, function void(Figure x){ return x.draw(); }); // function literal doAction(figures, function(x){ return x.draw(); }); // infer types doAction(figures, (x){ return x.draw(); }); // infer 'function' doAction(figures, (x)=>x.draw()); // convenient lambda syntax doAction(figures, x=>x.draw()); // also without parentheses It is documented here (scroll up a bit, Lambda does not seem to have an anchor) http://dlang.org/expression.html#FunctionLiteral In this case, we used the feature to implement a member function pointer, but there are many more applications that such a shorthand syntax makes convenient. It might generally be helpful for your programming skills to get accustomed to functional programming a bit. So in case you are interested, I suggest you consult your search engine of choice about the subject. You could eg. look into Scheme and/or Haskell and try to reproduce some of the examples also in D.The following works. You can also use a (scoped) delegate in order to allow the caller to close over his context.Wow! Great! Thanks. But I can't understend this syntax: x=>x.draw() Where i can read about it?
Nov 09 2012