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