Thread overview
How can I express the type '(int) => int' where it is a function or a delegate
Jul 16, 2014
Puming
Jul 16, 2014
Rikki Cattermole
Jul 16, 2014
Puming
Jul 16, 2014
Kagamin
July 16, 2014
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]);

July 16, 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.
July 16, 2014
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.

July 16, 2014
The compiler would generate calls to toDelegate and toFunction automatically.