Uncallable delegates
Walter Bright
newshound2 at digitalmars.com
Tue May 12 23:18:30 UTC 2026
I think of the issue completely differently. Allow me to try again, starting
with something simpler, like function pointers:
```
pure int f();
int g();
void test()
{
auto dgf = &f;
auto dgg = &g;
dgg = dgf; // works
dgf = dgg; // error, cannot convert
}
```
This shows that we cannot add function attributes, in this case adding `pure`.
The same applies to every other function attribute. This is not a design
decision, it's an inevitable deriviation from the other rules of the language.
Another case:
```
const(int)* f();
int* g();
void test()
{
auto dgf = &f;
auto dgg = &g;
dgg = dgf; // error, cannot convert
dgf = dgg; // works
}
```
This is an example of contra-variance.
```
void f(const(int)*);
void g(int*);
void test()
{
auto dgf = &f;
auto dgg = &g;
dgg = dgf; // works
dgf = dgg; // error, cannot convert
}
```
and that's an example of covariance.
Let's extend the notion to inheritance in a class:
```
class A
{
void f();
pure void g();
}
class B : A
{
override pure void f();
override void g();
}
```
Unfortunately, this compiles without error. Impure function B.g cannot override
pure A.g. Maybe this is a cause of one of the problems you've discovered.
https://github.com/dlang/dmd/issues/23125
Moving on to covariance:
```
class A
{
void f(int*);
void g(const(int)*);
}
class B : A
{
override void f(const(int)*); // compiles correctly
override void g(int*); // errors correctly
}
```
and contravariance:
```
class A
{
int* f();
const(int)* g();
}
class B : A
{
override const(int)* f(); // errors correctly
override int* g(); // compiles correctly
}
```
What this has to do with delegates is straightforward:
```
class A
{
const(int)* f();
}
class B : A
{
override int* f();
}
void foo()
{
A a;
B b;
auto dga = &a.f;
auto dgb = &b.f;
dga = dgb;
}
```
In other words, the behavior of delegate assignments behaves exactly like how an
overriding function behaves in a class hierarchy. If the behaviors diverge, then
there is a bug in the language implementation.
Delegates are not some unique construct with their own semantics. They are
constrained by co- and contra- variance eggzactly like function pointers and
class inheritance. Intuition has nothing to do with it.
More information about the dip.development
mailing list