May 20, 2015
On 5/20/2015 6:35 PM, Daniel Kozak wrote:

> DOCS: http://dlang.org/template.html#function-templates
> says: Function template type parameters that are to be implicitly
> deduced may not have specializations:

Thanks. For the record, the example there is the exact same case.

void Foo(T : T*)(T t) { ... }

int x,y;
Foo!(int*)(x);   // ok, T is not deduced from function argument
Foo(&y);         // error, T has specialization

I was looking for the answer in higher up the page in the Specializations section under Argument Deduction. Didn't think to look for it under Function Templates.
May 20, 2015
On 5/20/2015 6:35 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

> I'm using a fairly recent version of dmd master, and it prints out the
> address for px in both cases when I compile your code. So, if it's printing
> out 100 for you on the second call, it would appear to be a bug that has
> been fixed at some point since 2.067 (or whatever version you're using) was
> released.
>
> - Jonathan M Davis
>
I'm using 2.067.0, but according to the section of the docs Daniel pointer me to[1], printing 100 is the correct behavior in the second call.

[1] http://dlang.org/template.html#function-templates
May 20, 2015
On Wednesday, 20 May 2015 at 09:35:43 UTC, Daniel Kozak wrote:

> DOCS: http://dlang.org/template.html#function-templates
> says: Function template type parameters that are to be implicitly deduced may not have specializations:

OK, having reread this, I'm not clear at all what's going on. Here, I'm instantiating the templates such that the types are implicitly deduced from the function arguments and they pick up the specializations just fine.

```
T sum(T : ulong)(T lhs, T rhs) {
    writeln("Integrals");
    return cast(T)(lhs + rhs);
}

T sum(T : real)(T lhs, T rhs) {
    writeln("Floating Point");
    import std.math : round;
    return round(lhs + rhs);
}

void main() {
    writeln(sum(10L, 20L));
    writeln(sum(10.11, 3.22));
}
```

If the documentation is correct, then this shouldn't work, but it does. It breaks only when specializing on pointers and arrays, in which case I have to implicitly instantiate.
May 20, 2015
DOC say  `may not have` not `must not have` ;-)

On Wed, 20 May 2015 13:24:22 +0000
Mike Parker via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> On Wednesday, 20 May 2015 at 09:35:43 UTC, Daniel Kozak wrote:
> 
> > DOCS: http://dlang.org/template.html#function-templates says: Function template type parameters that are to be implicitly deduced may not have specializations:
> 
> OK, having reread this, I'm not clear at all what's going on. Here, I'm instantiating the templates such that the types are implicitly deduced from the function arguments and they pick up the specializations just fine.
> 
> ```
> T sum(T : ulong)(T lhs, T rhs) {
>      writeln("Integrals");
>      return cast(T)(lhs + rhs);
> }
> 
> T sum(T : real)(T lhs, T rhs) {
>      writeln("Floating Point");
>      import std.math : round;
>      return round(lhs + rhs);
> }
> 
> void main() {
>      writeln(sum(10L, 20L));
>      writeln(sum(10.11, 3.22));
> }
> ```
> 
> If the documentation is correct, then this shouldn't work, but it does. It breaks only when specializing on pointers and arrays, in which case I have to implicitly instantiate.
May 20, 2015
On Wednesday, 20 May 2015 at 13:46:22 UTC, Daniel Kozák wrote:
> DOC say  `may not have` not `must not have` ;-)
>

OK, if that's the intent, it needs to be reworded. As it stands, it looks more like it's saying specialization is not permissible, rather than what "might" be possible. As in:

"Employees may not bring unauthorized individuals into the work space."

It's very rare to use "must not" when denying permission.
May 21, 2015
On 05/20/2015 04:10 PM, Mike Parker wrote:
> On Wednesday, 20 May 2015 at 13:46:22 UTC, Daniel Kozák wrote:
>> DOC say  `may not have` not `must not have` ;-)
>>
>
> OK, if that's the intent, it needs to be reworded. As it stands, it
> looks more like it's saying specialization is not permissible, rather
> than what "might" be possible.

That's the only meaning that I get: The doc means "must not". Yet, as you've shown, the behavior does not match the doc.

Ali

May 21, 2015
On Wednesday, May 20, 2015 19:20:19 Mike Parker via Digitalmars-d-learn wrote:
> On 5/20/2015 6:35 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
>
> > I'm using a fairly recent version of dmd master, and it prints out the address for px in both cases when I compile your code. So, if it's printing out 100 for you on the second call, it would appear to be a bug that has been fixed at some point since 2.067 (or whatever version you're using) was released.
> >
> > - Jonathan M Davis
> >
> I'm using 2.067.0, but according to the section of the docs Daniel pointer me to[1], printing 100 is the correct behavior in the second call.
>
> [1] http://dlang.org/template.html#function-templates

Hmmm. It looks like when : is used directly in the template parameter list, it doesn't mean the same thing as when it's used in an is expression. I _never_ use : directly in the template parameter list, so I misunderstood what it did. And looking over what it says, your printVal(T : T*) should be used when explicitly calling printVal!(int*) but that printVal(px) will print the address, because for whatever reason, IFTI doesn't work with the : syntax directly in the template parameter list (I have no idea why, but that section in the spec is pretty clear about that). So, the fact that it's printing the address for me in both cases is bug. But if you're seeing it print 100 for printVal!(int*)(px) and the address for printVal(px), then that would be correct per the spec.

Personally, I wish that template specializations like this just didn't exist in the language, because they're redundant with template constraints and just add more complication to the language, but it's not like we're going to get rid of them at this point, unfortunately. But because I think that they're pointless, I never use them, and clearly am not familiar enough with how they work.

- Jonathan M Davis

May 21, 2015
On Wed, 20 May 2015 17:23:05 -0700
Ali Çehreli via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> On 05/20/2015 04:10 PM, Mike Parker wrote:
> > On Wednesday, 20 May 2015 at 13:46:22 UTC, Daniel Kozák wrote:
> >> DOC say  `may not have` not `must not have` ;-)
> >>
> >
> > OK, if that's the intent, it needs to be reworded. As it stands, it looks more like it's saying specialization is not permissible, rather than what "might" be possible.
> 
> That's the only meaning that I get: The doc means "must not". Yet, as you've shown, the behavior does not match the doc.
> 
> Ali
> 
1.) we could fix just doc - easiest, but inconsistent

2.) remove implicit deduction even for fun(T:char)(T c) and all other
specialization - code breakage so imho not good

3.) fix doc and allow even fun(T:T*)(T* p) - same as 2


May 21, 2015
On 5/21/15 2:35 AM, Daniel Kozák via Digitalmars-d-learn wrote:
>
> On Wed, 20 May 2015 17:23:05 -0700
> Ali Çehreli via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
>> On 05/20/2015 04:10 PM, Mike Parker wrote:
>>> On Wednesday, 20 May 2015 at 13:46:22 UTC, Daniel Kozák wrote:
>>>> DOC say  `may not have` not `must not have` ;-)
>>>>
>>>
>>> OK, if that's the intent, it needs to be reworded. As it stands, it
>>> looks more like it's saying specialization is not permissible,
>>> rather than what "might" be possible.
>>
>> That's the only meaning that I get: The doc means "must not". Yet, as
>> you've shown, the behavior does not match the doc.
>>
>> Ali
>>
> 1.) we could fix just doc - easiest, but inconsistent

Before doing this, we have to understand what works and what doesn't. It's not clear to me.

> 2.) remove implicit deduction even for fun(T:char)(T c) and all other
> specialization - code breakage so imho not good

I don't think this is possible, this would break lots of existing code.

> 3.) fix doc and allow even fun(T:T*)(T* p) - same as 2

I agree with this fix. I don't understand why specialization should disqualify IFTI. Can someone explain this rationale besides "because the docs say so"?

A possible explanation is that the specialization doesn't resolve to a *specific type* but instead resolves to a *flavor of type*.

For example, does this work?

foo(T : int*)(T t)

That would make some sense at least, but I don't understand why this rule is in place.

-Steve
May 21, 2015
On Thu, 21 May 2015 08:54:54 -0400
Steven Schveighoffer via Digitalmars-d-learn
<digitalmars-d-learn@puremagic.com> wrote:

> On 5/21/15 2:35 AM, Daniel Kozák via Digitalmars-d-learn wrote:
> >
> > On Wed, 20 May 2015 17:23:05 -0700
> > Ali Çehreli via Digitalmars-d-learn
> > <digitalmars-d-learn@puremagic.com> wrote:
> >
> >> On 05/20/2015 04:10 PM, Mike Parker wrote:
> >>> On Wednesday, 20 May 2015 at 13:46:22 UTC, Daniel Kozák wrote:
> >>>> DOC say  `may not have` not `must not have` ;-)
> >>>>
> >>>
> >>> OK, if that's the intent, it needs to be reworded. As it stands, it looks more like it's saying specialization is not permissible, rather than what "might" be possible.
> >>
> >> That's the only meaning that I get: The doc means "must not". Yet, as you've shown, the behavior does not match the doc.
> >>
> >> Ali
> >>
> > 1.) we could fix just doc - easiest, but inconsistent
> 
> Before doing this, we have to understand what works and what doesn't. It's not clear to me.
> 
> > 2.) remove implicit deduction even for fun(T:char)(T c) and all
> > other specialization - code breakage so imho not good
> 
> I don't think this is possible, this would break lots of existing code.
> 
> > 3.) fix doc and allow even fun(T:T*)(T* p) - same as 2
> 
> I agree with this fix. I don't understand why specialization should disqualify IFTI. Can someone explain this rationale besides "because the docs say so"?
> 

But this will break more code than 2. So it is impossible to fix it.