On Wednesday, 16 July 2014 at 04:10:13 UTC, Rikki Cattermole
wrote:
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.
Thanks. I wonder if functions could implicitly convert to
delegates...but toDelegate is OK.
Also, after another dig into the language docs, I found:
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.