Thread overview
Template Class With Default Values
Mar 04, 2018
bauss
Mar 04, 2018
Jonathan M Davis
Mar 04, 2018
bauss
Mar 04, 2018
Jonathan M Davis
Mar 04, 2018
Mike Parker
Mar 04, 2018
bauss
March 04, 2018
Why is the following not working?

class Foo(string baz = "baz")
{
    mixin("int " ~ baz ~ ";");
}

class Bar : Foo
{
}

Shouldn't it implicit do, without me having to do it manually?

class Bar : Foo!"baz"
{
}

...

What's the reason you can't specify default values for template parameters on a class? Is it intended behavior or is it a bug?

https://run.dlang.io/is/tnOtn3
March 04, 2018
On Sunday, March 04, 2018 11:35:23 bauss via Digitalmars-d-learn wrote:
> Why is the following not working?
>
> class Foo(string baz = "baz")
> {
>      mixin("int " ~ baz ~ ";");
> }
>
> class Bar : Foo
> {
> }
>
> Shouldn't it implicit do, without me having to do it manually?
>
> class Bar : Foo!"baz"
> {
> }
>
> ...
>
> What's the reason you can't specify default values for template parameters on a class? Is it intended behavior or is it a bug?
>
> https://run.dlang.io/is/tnOtn3

If it were allowed, it would be ambiguous. e.g. what would

alias Foobar = Foo;

mean? Would it be the default instantiation of Foo!"baz" or would it be the template itself? Right now, it's always the template itself, and in all cases except for functions, templates must be explicitly instantiated.

For function templates, we have IFTI (Implicit Function Template Instantiation) where the compiler tries to infer the template arguments based on the function arguments. It works because the function call syntax is unambiguous such that if you have

auto foo(T = string)(T t) {...}

alias foobar = foo;

it's guaranteed that foobar is the template foo and not an instantiation. It would certainly be possible to make the compiler implicitly instantiate templates that aren't functions under specific circumstances, but it can't be done in the general case, so rather than creating a situation with subtle rules about when it's necessary to explicitly instantiate a template and when it's not, it's simply always required to explicitly instantiate templates other than function templates. And based on Walter's comment in the associated enhancement request, he has concerns that allowing implicit template instantiations like this would cause serious problems.

https://issues.dlang.org/show_bug.cgi?id=1012

Really, this is one of those things that at first seems like it's crazy that it doesn't work, but as the details become clearer, it starts seeming a lot less reasonable to try to make it work.

- Jonathan M Davis

March 04, 2018
On Sunday, 4 March 2018 at 11:35:23 UTC, bauss wrote:
> Why is the following not working?
>
> class Foo(string baz = "baz")
> {
>     mixin("int " ~ baz ~ ";");
> }
>
> class Bar : Foo
> {
> }
>
> Shouldn't it implicit do, without me having to do it manually?
>
> class Bar : Foo!"baz"
> {
> }
>

class Bar : Foo!()
{
}
March 04, 2018
On Sunday, 4 March 2018 at 11:57:12 UTC, Jonathan M Davis wrote:
> On Sunday, March 04, 2018 11:35:23 bauss via Digitalmars-d-learn wrote:
>> Why is the following not working?
>>
>> class Foo(string baz = "baz")
>> {
>>      mixin("int " ~ baz ~ ";");
>> }
>>
>> class Bar : Foo
>> {
>> }
>>
>> Shouldn't it implicit do, without me having to do it manually?
>>
>> class Bar : Foo!"baz"
>> {
>> }
>>
>> ...
>>
>> What's the reason you can't specify default values for template parameters on a class? Is it intended behavior or is it a bug?
>>
>> https://run.dlang.io/is/tnOtn3
>
> If it were allowed, it would be ambiguous. e.g. what would
>
> alias Foobar = Foo;
>
> mean? Would it be the default instantiation of Foo!"baz" or would it be the template itself? Right now, it's always the template itself, and in all cases except for functions, templates must be explicitly instantiated.
>
> For function templates, we have IFTI (Implicit Function Template Instantiation) where the compiler tries to infer the template arguments based on the function arguments. It works because the function call syntax is unambiguous such that if you have
>
> auto foo(T = string)(T t) {...}
>
> alias foobar = foo;
>
> it's guaranteed that foobar is the template foo and not an instantiation. It would certainly be possible to make the compiler implicitly instantiate templates that aren't functions under specific circumstances, but it can't be done in the general case, so rather than creating a situation with subtle rules about when it's necessary to explicitly instantiate a template and when it's not, it's simply always required to explicitly instantiate templates other than function templates. And based on Walter's comment in the associated enhancement request, he has concerns that allowing implicit template instantiations like this would cause serious problems.
>
> https://issues.dlang.org/show_bug.cgi?id=1012
>
> Really, this is one of those things that at first seems like it's crazy that it doesn't work, but as the details become clearer, it starts seeming a lot less reasonable to try to make it work.
>
> - Jonathan M Davis

It wouldn't be ambiguous if it had same behavior as every other templates.

Ex.

void foo(string a = "a")() { writeln(a); }

alias foo2 = foo; // Error ... The class situation should be the same.

Which forces you to do

alias foob = foo!"b";

Which means that the following would work properly:

    foo;
    foo!"b";
    foob;

Which is why it doesn't seem right that classes can't work the same way.


March 04, 2018
On Sunday, 4 March 2018 at 11:59:52 UTC, Mike Parker wrote:
> On Sunday, 4 March 2018 at 11:35:23 UTC, bauss wrote:
>> Why is the following not working?
>>
>> class Foo(string baz = "baz")
>> {
>>     mixin("int " ~ baz ~ ";");
>> }
>>
>> class Bar : Foo
>> {
>> }
>>
>> Shouldn't it implicit do, without me having to do it manually?
>>
>> class Bar : Foo!"baz"
>> {
>> }
>>
>
> class Bar : Foo!()
> {
> }

Still seems unneccessary.
March 04, 2018
On Sunday, March 04, 2018 14:43:41 bauss via Digitalmars-d-learn wrote:
> On Sunday, 4 March 2018 at 11:57:12 UTC, Jonathan M Davis wrote:
> > On Sunday, March 04, 2018 11:35:23 bauss via
> >
> > Digitalmars-d-learn wrote:
> >> Why is the following not working?
> >>
> >> class Foo(string baz = "baz")
> >> {
> >>
> >>      mixin("int " ~ baz ~ ";");
> >>
> >> }
> >>
> >> class Bar : Foo
> >> {
> >> }
> >>
> >> Shouldn't it implicit do, without me having to do it manually?
> >>
> >> class Bar : Foo!"baz"
> >> {
> >> }
> >>
> >> ...
> >>
> >> What's the reason you can't specify default values for template parameters on a class? Is it intended behavior or is it a bug?
> >>
> >> https://run.dlang.io/is/tnOtn3
> >
> > If it were allowed, it would be ambiguous. e.g. what would
> >
> > alias Foobar = Foo;
> >
> > mean? Would it be the default instantiation of Foo!"baz" or would it be the template itself? Right now, it's always the template itself, and in all cases except for functions, templates must be explicitly instantiated.
> >
> > For function templates, we have IFTI (Implicit Function Template Instantiation) where the compiler tries to infer the template arguments based on the function arguments. It works because the function call syntax is unambiguous such that if you have
> >
> > auto foo(T = string)(T t) {...}
> >
> > alias foobar = foo;
> >
> > it's guaranteed that foobar is the template foo and not an instantiation. It would certainly be possible to make the compiler implicitly instantiate templates that aren't functions under specific circumstances, but it can't be done in the general case, so rather than creating a situation with subtle rules about when it's necessary to explicitly instantiate a template and when it's not, it's simply always required to explicitly instantiate templates other than function templates. And based on Walter's comment in the associated enhancement request, he has concerns that allowing implicit template instantiations like this would cause serious problems.
> >
> > https://issues.dlang.org/show_bug.cgi?id=1012
> >
> > Really, this is one of those things that at first seems like it's crazy that it doesn't work, but as the details become clearer, it starts seeming a lot less reasonable to try to make it work.
> >
> > - Jonathan M Davis
>
> It wouldn't be ambiguous if it had same behavior as every other templates.
>
> Ex.
>
> void foo(string a = "a")() { writeln(a); }
>
> alias foo2 = foo; // Error ... The class situation should be the same.
>
> Which forces you to do
>
> alias foob = foo!"b";
>
> Which means that the following would work properly:
>
>      foo;
>      foo!"b";
>      foob;
>
> Which is why it doesn't seem right that classes can't work the same way.

Except that aliasing templates of any kind is legal. So,

alias foo2 = foo;

is legal just like

alias bar = isInputRange;

is legal. And in all cases, it aliases the template, not the instantiation, whether there are default template arguments or not. It only aliases the instantiation if the template is explicitly instantiated in the alias.

There's nothing special about class or struct templates here, and the only thing special about function templates is that we have IFTI, which only kicks in when a function template is called.

- Jonathan M Davis