Thread overview
Debug help - delegate from dlang Tour
1 day ago
Brother Bill
1 day ago
evilrat
1 day ago
Brother Bill
1 day ago
Brother Bill
1 day ago
Brother Bill
1 day ago
Brother Bill
1 day ago

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)
        ^
1 day ago

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.

1 day ago

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)
        ^
1 day ago

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);
	}

1 day ago

It works by making doSomething as a delegate.

1 day ago

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);
}
1 day ago

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.

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