digitalmars.D.learn - How can I express the type '(int) => int' where it is a function or a
- Puming (62/62) Jul 15 2014 I'd like to have a Command class, where their is a name and a
- Rikki Cattermole (17/78) Jul 15 2014 Or using std.functional toDelegate you could convert the function into a...
I'd like to have a Command class, where their is a name and a handler field: ```d class Command { string name; string delegate(string[]) handler; } ``` this is ok, but sometimes I want the handler also accept a function (lambdas are init to functions if no capture of outer scope variables are present), but it can't. So I'd like to generalize the Command to a template, the best I've got sofar: ```d alias string delegate(string[]) HandlerDele; alias string function(string[]) HandlerFunc; class Command(T) if (is (T HandlerDele) || is (T HandlerFunc)) { immutable { string name; T handler; } this(string name, T handler) { this.name = name; this.handler = handler; } } void main() { HandlerFunc f = xs => xs[0]; // just a test auto cmd = new Command!HandlerFunc("echo", f); } ``` I've got several questions about this: 1. I cant ignore `HandlerFunc` when initiating cmd: ```d auto cmd = new Command("echo", f); // Error: class dshell.command.Command(T) if (is(T HandlerDele) || is(T HandlerFunc)) is used as a type ``` Can DMD automatically infer the type here? 2. Is this the right way to do this? 3. I'd like a unified description of `a function pointer or a delegate`, and from the experience of lambda, it seems the syntax of lamdba is really useful here, if we have that, then instead of: ```d void execute(T)(Context cxt, T handler) if (is (T HandlerFunc) || is (T HandlerDele)) { //... } we could define a function that accepts a function/delegate like this: ```d void execute(T : string[] => string)(Context cxt, T handler) { //... } // in main ctx.execute(xs => xs[0]);
Jul 15 2014
On 16/07/2014 3:50 p.m., Puming wrote:I'd like to have a Command class, where their is a name and a handler field: ```d class Command { string name; string delegate(string[]) handler; } ``` this is ok, but sometimes I want the handler also accept a function (lambdas are init to functions if no capture of outer scope variables are present), but it can't. So I'd like to generalize the Command to a template, the best I've got sofar: ```d alias string delegate(string[]) HandlerDele; alias string function(string[]) HandlerFunc; class Command(T) if (is (T HandlerDele) || is (T HandlerFunc)) { immutable { string name; T handler; } this(string name, T handler) { this.name = name; this.handler = handler; } } void main() { HandlerFunc f = xs => xs[0]; // just a test auto cmd = new Command!HandlerFunc("echo", f); } ``` I've got several questions about this: 1. I cant ignore `HandlerFunc` when initiating cmd: ```d auto cmd = new Command("echo", f); // Error: class dshell.command.Command(T) if (is(T HandlerDele) || is(T HandlerFunc)) is used as a type ``` Can DMD automatically infer the type here? 2. Is this the right way to do this? 3. I'd like a unified description of `a function pointer or a delegate`, and from the experience of lambda, it seems the syntax of lamdba is really useful here, if we have that, then instead of: ```d void execute(T)(Context cxt, T handler) if (is (T HandlerFunc) || is (T HandlerDele)) { //... } we could define a function that accepts a function/delegate like this: ```d void execute(T : string[] => string)(Context cxt, T handler) { //... } // in main ctx.execute(xs => xs[0]);Or using std.functional toDelegate you could convert the function into a delegate. class Command { string name; string delegate(string[]) handler; this(string name, string delegate(string[]) handler) { this.name = name; this.handler = handler; } this(string name, string function(string[]) handler) { import std.functional : toDelegate; this.name = name; this.handler = toDelegate(handler); } } Just keep in mind, you can't go the opposite way.
Jul 15 2014
On Wednesday, 16 July 2014 at 04:10:13 UTC, Rikki Cattermole wrote:On 16/07/2014 3:50 p.m., Puming wrote:Thanks. I wonder if functions could implicitly convert to delegates...but toDelegate is OK. Also, after another dig into the language docs, I found:I'd like to have a Command class, where their is a name and a handler field: ```d class Command { string name; string delegate(string[]) handler; } ``` this is ok, but sometimes I want the handler also accept a function (lambdas are init to functions if no capture of outer scope variables are present), but it can't. So I'd like to generalize the Command to a template, the best I've got sofar: ```d alias string delegate(string[]) HandlerDele; alias string function(string[]) HandlerFunc; class Command(T) if (is (T HandlerDele) || is (T HandlerFunc)) { immutable { string name; T handler; } this(string name, T handler) { this.name = name; this.handler = handler; } } void main() { HandlerFunc f = xs => xs[0]; // just a test auto cmd = new Command!HandlerFunc("echo", f); } ``` I've got several questions about this: 1. I cant ignore `HandlerFunc` when initiating cmd: ```d auto cmd = new Command("echo", f); // Error: class dshell.command.Command(T) if (is(T HandlerDele) || is(T HandlerFunc)) is used as a type ``` Can DMD automatically infer the type here? 2. Is this the right way to do this? 3. I'd like a unified description of `a function pointer or a delegate`, and from the experience of lambda, it seems the syntax of lamdba is really useful here, if we have that, then instead of: ```d void execute(T)(Context cxt, T handler) if (is (T HandlerFunc) || is (T HandlerDele)) { //... } we could define a function that accepts a function/delegate like this: ```d void execute(T : string[] => string)(Context cxt, T handler) { //... } // in main ctx.execute(xs => xs[0]);Or using std.functional toDelegate you could convert the function into a delegate. class Command { string name; string delegate(string[]) handler; this(string name, string delegate(string[]) handler) { this.name = name; this.handler = handler; } this(string name, string function(string[]) handler) { import std.functional : toDelegate; this.name = name; this.handler = toDelegate(handler); } } Just keep in mind, you can't go the opposite way.The .ptr property of a delegate will return the frame pointer value as a void*.The .funcptr property of a delegate will return the function pointer value as a function type.Future directions: Function pointers and delegates may merge into a common syntax and be interchangeable with each other.Wonder how that would happen.
Jul 15 2014
The compiler would generate calls to toDelegate and toFunction automatically.
Jul 16 2014