www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Debug help - delegate from dlang Tour

reply Brother Bill <brotherbill mail.com> writes:
https://tour.dlang.org/tour/en/basics/delegates

This is so simple.  What is D complaining about?
Should this also work with a Template, as shown?

```
import std.stdio;

void main()
{
	// auto add(T)(T lhs, T rhs)
	// {
	// 	return lhs + rhs;
	// }

	int add(int lhs, int rhs) {
		return lhs + rhs;
	}

	int doSomething(int function(int, int) doer)
	{
		// call passed function
		return doer(5, 6);
	}

	doSomething(&add);

}

```

Console output:
```
c:\dev\D\D_templates_tutorial\toy1\source\app.d(20): Error: 
function `doSomething` is not callable using argument types `(int 
delegate(int lhs, int rhs) pure nothrow  nogc  safe)`
     doSomething(&add);
                ^
c:\dev\D\D_templates_tutorial\toy1\source\app.d(20):        
cannot pass argument `&add` of type `int delegate(int lhs, int 
rhs) pure nothrow  nogc  safe` to parameter `int function(int, 
int) doer`
c:\dev\D\D_templates_tutorial\toy1\source\app.d(14):        
`app.main.doSomething(int function(int, int) doer)` declared here
     int doSomething(int function(int, int) doer)
         ^
```
Sep 08
parent reply evilrat <evilrat666 gmail.com> writes:
On Monday, 8 September 2025 at 14:32:32 UTC, Brother Bill wrote:
 https://tour.dlang.org/tour/en/basics/delegates

 This is so simple.  What is D complaining about?
 Should this also work with a Template, as shown?

 ```
 import std.stdio;

 void main()
 {
 	// auto add(T)(T lhs, T rhs)
 	// {
 	// 	return lhs + rhs;
 	// }

 	int add(int lhs, int rhs) {
 		return lhs + rhs;
 	}

 	int doSomething(int function(int, int) doer)
 	{
 		// call passed function
 		return doer(5, 6);
 	}

 	doSomething(&add);

 }

 ```

 Console output:
 ```
 c:\dev\D\D_templates_tutorial\toy1\source\app.d(20): Error: 
 function `doSomething` is not callable using argument types 
 `(int delegate(int lhs, int rhs) pure nothrow  nogc  safe)`
     doSomething(&add);
                ^
 c:\dev\D\D_templates_tutorial\toy1\source\app.d(20):        
 cannot pass argument `&add` of type `int delegate(int lhs, int 
 rhs) pure nothrow  nogc  safe` to parameter `int function(int, 
 int) doer`
 c:\dev\D\D_templates_tutorial\toy1\source\app.d(14):        
 `app.main.doSomething(int function(int, int) doer)` declared 
 here
     int doSomething(int function(int, int) doer)
         ^
 ```
probably because you have declared nested function `add` inside `main`, this creates a delegate closure capturing `main` scope, if you don't want that just mark `add` static.
Sep 08
next sibling parent reply Brother Bill <brotherbill mail.com> writes:
On Monday, 8 September 2025 at 14:42:01 UTC, evilrat wrote:
 probably because you have declared nested function `add` inside 
 `main`, this creates a delegate closure capturing `main` scope, 
 if you don't want that just mark `add` static.
Marking add static works. Still don't understand why this doesn't work. ``` import std.stdio; void main() { foo(); } void foo() { int addMyInts(int lhs, int rhs) { return lhs + rhs; } int doSomething(int function(int, int) doer) { // call passed function return doer(5, 6); } doSomething(&addMyInts); } ``` Console output ``` c:\dev\D\D_templates_tutorial\toy1\source\app.d(19): Error: function `doSomething` is not callable using argument types `(int delegate(int lhs, int rhs) pure nothrow nogc safe)` doSomething(&addMyInts); ^ c:\dev\D\D_templates_tutorial\toy1\source\app.d(19): cannot pass argument `&addMyInts` of type `int delegate(int lhs, int rhs) pure nothrow nogc safe` to parameter `int function(int, int) doer` c:\dev\D\D_templates_tutorial\toy1\source\app.d(13): `app.foo.doSomething(int function(int, int) doer)` declared here int doSomething(int function(int, int) doer) ^ ```
Sep 08
next sibling parent reply Brother Bill <brotherbill mail.com> writes:
This works:
```
import std.stdio;

void main()
{
	foo();
}

void foo() {
	int addMyInts(int lhs, int rhs) {
		return lhs + rhs;
	}

	int doSomething(int delegate(int, int) doer)
	{
		// call passed function
		return doer(5, 6);
	}

	doSomething(&addMyInts);
}
```

Is there another way to have this work other than making 
addMyInts static?
```
	int doSomething(int function(int, int) doer)
	{
		// call passed function
		return doer(5, 6);
	}

```
Sep 08
parent Brother Bill <brotherbill mail.com> writes:
It works by making doSomething as a delegate.
Sep 08
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Monday, 8 September 2025 at 16:23:23 UTC, Brother Bill wrote:
 On Monday, 8 September 2025 at 14:42:01 UTC, evilrat wrote:
 probably because you have declared nested function `add` 
 inside `main`, this creates a delegate closure capturing 
 `main` scope, if you don't want that just mark `add` static.
Marking add static works. Still don't understand why this doesn't work.
The easiest thing to do here is to declare it static, so the compiler will reject any requirement of a context pointer. I believe the case where it will infer a function vs. delegate is when passing a literal lambda. Other than that, you have to be explicit. ```d void main() { int foo1() { return 1; } static int foo2() { return 1; } int function() p; p = &foo1; // error p = &foo2; // ok p = () { return 1; }; // ok, inferred to be a function, not delegate } ``` -Steve
Sep 08
prev sibling parent Brother Bill <brotherbill mail.com> writes:
On Monday, 8 September 2025 at 14:42:01 UTC, evilrat wrote:
 probably because you have declared nested function `add` inside 
 `main`, this creates a delegate closure capturing `main` scope, 
 if you don't want that just mark `add` static.
Yep, as a nested function, this is a delegate, not a function, so incompatible. The following code works: ``` import std.stdio; void main() { foo(); } // Global function. Doesn't work if nested non-static function int add(int lhs, int rhs) { return lhs + rhs; } void foo() { int doSomething(int function(int, int) doer) { // call passed function return doer(5, 6); } doSomething(&add); } ```
Sep 08