On Thursday, 18 September 2025 at 18:10:13 UTC, Ali Çehreli wrote:
As stated by multiple people, most nested functions will be
'delegates'. However, a nested function is a 'function' if it
does not touch local scope:
```d
void main() {
int twice(int i) {
return i * 2;
}
// Not a delegate:
static assert(is (typeof(twice) == function));
}
```
You are mistaking the is expression for a function test with the
function pointer type.
In fact, the compiler treats this as a function with a context
pointer, because it's not static.
Only function literals can be infer as a function pointer.
Some demo code:
```d
void main() {
int x;
int couldBeStatic(int i) {
return i * 2;
}
int cantBeStatic(int i) {
return i * x;
}
static assert(is(typeof(couldBeStatic) == function));
static assert(is(typeof(cantBeStatic) == function));
// function pointer is not a function
static assert(!is(typeof(&couldBeStatic) == function));
static assert(!is(typeof(&cantBeStatic) == function));
// this one does not need a context pointer
static int isStatic(int i) {
return i * 2;
}
static assert(!__traits(compiles, {int function(int) fp =
&couldBeStatic;}));
static assert(!__traits(compiles, {int function(int) fp =
&cantBeStatic;}));
static assert( __traits(compiles, {int function(int) fp =
&isStatic;}));
static assert( __traits(compiles, {int delegate(int) dg =
&couldBeStatic;}));
static assert( __traits(compiles, {int delegate(int) dg =
&cantBeStatic;}));
static assert(!__traits(compiles, {int delegate(int) dg =
&isStatic;}));
// lambdas are more malleable
static assert(__traits(compiles, {int function(int) fp = (int
i) => i * 2;}));
static assert(__traits(compiles, {int delegate(int) dg = (int
i) => i * 2;}));
}
```
-Steve