Thread overview
First Draft: Implicit Type Template Instantiation via Constructors
Mar 12
Meta
Mar 12
jmh530
Mar 12
Meta
5 days ago
12345swordy
March 12

This DIP is a partial resurrection of DIP 40 (https://wiki.dlang.org/DIP40) by me and Dennis Korpel. Dennis is working on the implementation (https://github.com/dlang/dmd/pull/16910) while I am writing the DIP.

The purpose of this DIP is to propose a new avenue for Implicit Template Instantiation (ITI) via constructors. Currently (that I'm aware of) D only does Implicit Function Template Instantiation (IFTI); the proposal is to extend this implicit instantiation to types as well, via their constructors.

Before this DIP:

struct Pair(T, U)
{
    T t;
    U u;

    this(T t, U u)
    {
        this.t = t;
        this.u = u;
    }
}

void main()
{
    auto p1 = Pair(1, "asdf"); // Error: struct `Pair` is not callable using argument types `!()(int, string)`
                               // Candidate is: `Pair(T, U)`
}

After this DIP:

struct Pair(T, U)
{
    T t;
    U u;

    this(T t, U u)
    {
        this.t = t;
        this.u = u;
    }
}

void main()
{
    auto p1 = Pair(1, "asdf"); // Okay, T is deduced as int and U as string
}

The DIP:
https://github.com/MetaLang/DIPs/blob/dip1050/DIPs/DIP1050.md

March 12

On Wednesday, 12 March 2025 at 00:20:55 UTC, Meta wrote:

>

This DIP is a partial resurrection of DIP 40 (https://wiki.dlang.org/DIP40) by me and Dennis Korpel. Dennis is working on the implementation (https://github.com/dlang/dmd/pull/16910) while I am writing the DIP.

[...]

Glad to see someone working on this problem.

How would this apply to template aliases (e.g. DIP1023)?

March 12

On Wednesday, 12 March 2025 at 02:37:06 UTC, jmh530 wrote:

>

On Wednesday, 12 March 2025 at 00:20:55 UTC, Meta wrote:

>

This DIP is a partial resurrection of DIP 40 (https://wiki.dlang.org/DIP40) by me and Dennis Korpel. Dennis is working on the implementation (https://github.com/dlang/dmd/pull/16910) while I am writing the DIP.

[...]

Glad to see someone working on this problem.

How would this apply to template aliases (e.g. DIP1023)?

From my understanding, it should work the same way as IFTI, i.e., if eventually this code compiles:

struct TemplateType(T) { }
alias TemplateAlias(T) = TemplateType!T;
void templateFunction(T)(TemplateAlias!T arg) { }

void main()
{
    TemplateAlias!int ta;
    templateFunction(ta);
}

Then this code should as well:

struct TemplateType(T) { }
alias TemplateAlias(T) = TemplateType!T;
struct AnotherTemplateType(T)
{
    this(TemplateAlias!T arg) {}
}

void main()
{
    TemplateAlias!int ta;
    auto att = AnotherTemplateType(ta); // Currently does not compile, even if you add AnotherTemplateType!(TemplateAlias!int)(ta)
}
5 days ago

On Wednesday, 12 March 2025 at 00:20:55 UTC, Meta wrote:

>

This DIP is a partial resurrection of DIP 40 (https://wiki.dlang.org/DIP40) by me and Dennis Korpel. Dennis is working on the implementation (https://github.com/dlang/dmd/pull/16910) while I am writing the DIP.

The purpose of this DIP is to propose a new avenue for Implicit Template Instantiation (ITI) via constructors. Currently (that I'm aware of) D only does Implicit Function Template Instantiation (IFTI); the proposal is to extend this implicit instantiation to types as well, via their constructors.

Before this DIP:

struct Pair(T, U)
{
    T t;
    U u;

    this(T t, U u)
    {
        this.t = t;
        this.u = u;
    }
}

void main()
{
    auto p1 = Pair(1, "asdf"); // Error: struct `Pair` is not callable using argument types `!()(int, string)`
                               // Candidate is: `Pair(T, U)`
}

After this DIP:

struct Pair(T, U)
{
    T t;
    U u;

    this(T t, U u)
    {
        this.t = t;
        this.u = u;
    }
}

void main()
{
    auto p1 = Pair(1, "asdf"); // Okay, T is deduced as int and U as string
}

The DIP:
https://github.com/MetaLang/DIPs/blob/dip1050/DIPs/DIP1050.md

You spell "Changes" wrong, you better fixed that.

It is a straight up massive miss opportunity to not handle Partial template parameter deduction here. C++ doesn't even handle that edge case which due to that you had to resort to an all or nothing in C++, which can be very annoying at times.