Poll: what should this program do?

Ogion ogion.art at gmail.com
Wed Mar 19 10:31:36 UTC 2025


On Wednesday, 19 March 2025 at 03:40:28 UTC, Paul Backus wrote:

> **What SHOULD this program do?**
>
> **What do you think it ACTUALLY does?**

It should print “outer”, and it actually does.

Obviously, at first I expected it to print: “inner”. But when I 
saw the result and checked the spec, I think that it works 
correctly.

There are three non-obvious things ging in here.

Number one: `fun(T).fun(string)` is not a regular function, it’s 
a template. So it doesn’t collide with globally-defined 
`fun(string)`. This is why this program compiles.

Number two: inside eponymous template `fun`, `fun` refers to the 
template itself, not to its members. This gives a different 
result:
```D
template fun(T) {
     alias fun = f;
     string f(int) => f("hi");
     string f(string) => "inner";
}
string f(string) => "outer";

void main() {
     import std.stdio;
     writeln(fun!int(123)); // sorry, IFTI no longer works
}
```

Number three: using a type instead of template parameter (of the 
same type) is enough to break [implicit 
instantiation](https://dlang.org/spec/template.html#ifti-restrictions):

```D
template fun(T) {
     string fun(string) => "inner";
}

void main() {
     import std.stdio;
     writeln(fun("hi")); // error
     writeln(fun!string("hi")); // works
}
```
There are many other ways to break IFTI:
```D
template fun(T) {
     alias fun = fun;
     string f(T) => "inner";
}
```

```D
template fun(T) {
     template fun(T) {
         string fun(T) => "inner";
     }
}
```
I guess it can’t be helped. Usually, though, IFTI failure results 
in error. In this program, it leads to unforeseen behavior. But 
such is life on templates.



More information about the Digitalmars-d mailing list