www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How can I express the type '(int) => int' where it is a function or a

reply "Puming" <zhaopuming gmail.com> writes:
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
parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
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
parent reply "Puming" <zhaopuming gmail.com> writes:
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.
Jul 15 2014
parent "Kagamin" <spam here.lot> writes:
The compiler would generate calls to toDelegate and toFunction 
automatically.
Jul 16 2014