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:
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:
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