Re: Template type deduction and specialization

2015-05-21 Thread Daniel Kozák via Digitalmars-d-learn

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




Re: Template type deduction and specialization

2015-05-21 Thread Steven Schveighoffer via Digitalmars-d-learn

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


Re: Template type deduction and specialization

2015-05-21 Thread Daniel Kozak via Digitalmars-d-learn

On Thursday, 21 May 2015 at 13:12:36 UTC, Daniel Kozák wrote:


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.


Not more, but it will be worst, because it could change behaviour 
of program without error message


Re: Template type deduction and specialization

2015-05-21 Thread Daniel Kozák via Digitalmars-d-learn

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.



Re: Template type deduction and specialization

2015-05-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/21/15 10:15 AM, Daniel Kozák via Digitalmars-d-learn wrote:


import std.stdio;

void f(T:T*)(T* t)
{
 writeln(before change this is not called);
}

void f(T)(T t)
{
 writeln(before change this is called);
}


void main() {
 int val;
 f(val);
 f!(int*)(val);
}

now it prints:
before change this is called
before change this is not called

but if we make change as you suggest this will be print:

before change this is not called
before change this is not called



Ugh, that was not what my reading of the docs seemed to suggest:

Function template type parameters that are to be implicitly deduced may 
not have specializations


I misread that to mean *templates* that have specializations cannot be 
used for IFTI. Now I see that the rule is talking not about templates 
but *template type parameters*.


But the more I look at this, the more I think this is a bad code smell. 
I can't see any logical reason to do something different with an 
implicit deduction vs. an explicit call. Especially in the face of other 
code that Can anyone come up a valid use case for this? Even one that is 
a hack?


I'll note that if you replace the specialization with:

f(T : int *)(T t)

it calls the specialized version twice. Clearly, the rule is not 
properly described or not properly implemented.


I would like to hear from Walter on this, what are the thoughts behind 
this rule?


-Steve


Re: Template type deduction and specialization

2015-05-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/21/15 9:14 AM, Daniel Kozak wrote:

On Thursday, 21 May 2015 at 13:12:36 UTC, Daniel Kozák wrote:


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.


Not more, but it will be worst, because it could change behaviour of
program without error message


How so? My understanding is that it's illegal to call a function with 
specializations when IFTI is involved. This means code that currently 
doesn't compile, will compile. But what working code base has 
non-compiling code? I guess some __traits(compiles) calls would change, 
but I don't see the harm in this? You can call the function with an 
explicit instantiation, calling it with an implicit one isn't going to 
change the semantic meaning of the call.


In other words, code that does this:

foo(x);

that doesn't compile, will start to compile as if you did:

foo!(typeof(x))(x).

How does this break code?

And how does it break more code than 2?

-Steve


Re: Template type deduction and specialization

2015-05-21 Thread Daniel Kozák via Digitalmars-d-learn

On Thu, 21 May 2015 09:58:16 -0400
Steven Schveighoffer via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 On 5/21/15 9:14 AM, Daniel Kozak wrote:
  On Thursday, 21 May 2015 at 13:12:36 UTC, Daniel Kozák wrote:
 
  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.
 
  Not more, but it will be worst, because it could change behaviour of
  program without error message
 
 How so? My understanding is that it's illegal to call a function with 
 specializations when IFTI is involved. This means code that currently 
 doesn't compile, will compile. But what working code base has 
 non-compiling code? I guess some __traits(compiles) calls would
 change, but I don't see the harm in this? You can call the function
 with an explicit instantiation, calling it with an implicit one isn't
 going to change the semantic meaning of the call.
 
 In other words, code that does this:
 
 foo(x);
 
 that doesn't compile, will start to compile as if you did:
 
 foo!(typeof(x))(x).
 
 How does this break code?
 
 And how does it break more code than 2?
 
 -Steve

import std.stdio;

void f(T:T*)(T* t)
{
writeln(before change this is not called);
}

void f(T)(T t)
{
writeln(before change this is called);
}


void main() {
int val;
f(val);
f!(int*)(val);
}

now it prints:
before change this is called
before change this is not called

but if we make change as you suggest this will be print:

before change this is not called
before change this is not called



Re: Template type deduction and specialization

2015-05-20 Thread Namespace via Digitalmars-d-learn

On Wednesday, 20 May 2015 at 06:31:13 UTC, Mike Parker wrote:
I don't understand why this behaves as it does. Given the 
following two templates:


```
void printVal(T)(T t) {
writeln(t);
}
void printVal(T : T*)(T* t) {
writeln(*t);
}
```

I find that I actually have to explicitly instantiate the 
template with a pointer type to get the specialization.


```
void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);// prints the address
printVal!(int*)(px)  // prints 100
}
```

Intuitively, I would expect the specialization to be deduced 
without explicit instantiation. Assuming this isn't a bug (I've 
been unable to turn up anything in Bugzilla), could someone in 
the know explain the rationale behind this?


What about:

import std.stdio;

void printVal(T)(T t) {
static if (is(T : U*, U))
printVal(*t);
else
writeln(t);
}

void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);
}



Re: Template type deduction and specialization

2015-05-20 Thread jklp via Digitalmars-d-learn

On Wednesday, 20 May 2015 at 06:31:13 UTC, Mike Parker wrote:
I don't understand why this behaves as it does. Given the 
following two templates:


```
void printVal(T)(T t) {
writeln(t);
}
void printVal(T : T*)(T* t) {
writeln(*t);
}
```

I find that I actually have to explicitly instantiate the 
template with a pointer type to get the specialization.


```
void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);// prints the address
printVal!(int*)(px)  // prints 100
}
```

Intuitively, I would expect the specialization to be deduced 
without explicit instantiation. Assuming this isn't a bug (I've 
been unable to turn up anything in Bugzilla), could someone in 
the know explain the rationale behind this?


---
import std.stdio;

void printVal(T)(T t) {
writeln(t);
}

void printVal(T: T)(T* t) {
writeln(*t);
}

void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);
}
---

here it's selected correctly without explicit instantiation. But 
honestly i don't know why since the  asterisk is removed from the 
T it looks quite incorrect.




Re: Template type deduction and specialization

2015-05-20 Thread Mike Parker via Digitalmars-d-learn

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.


Re: Template type deduction and specialization

2015-05-20 Thread Mike Parker via Digitalmars-d-learn

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


Re: Template type deduction and specialization

2015-05-20 Thread Daniel Kozák via Digitalmars-d-learn

On Wed, 20 May 2015 06:31:11 +
Mike Parker via Digitalmars-d-learn digitalmars-d-learn@puremagic.com
wrote:

 I don't understand why this behaves as it does. Given the 
 following two templates:
 
 ```
 void printVal(T)(T t) {
   writeln(t);
 }
 void printVal(T : T*)(T* t) {
   writeln(*t);
 }
 ```
 
 I find that I actually have to explicitly instantiate the 
 template with a pointer type to get the specialization.
 
 ```
 void main() {
   int x = 100;
   printVal(x);
   int* px = x;
   printVal(px);// prints the address
  printVal!(int*)(px)  // prints 100
 }
 ```
 
 Intuitively, I would expect the specialization to be deduced 
 without explicit instantiation. Assuming this isn't a bug (I've 
 been unable to turn up anything in Bugzilla), could someone in 
 the know explain the rationale behind this?

Because it cannot deduce type T:

try this:

void printVal(T : T*)(T* t) {
writeln(*t);
}

void main() {
int x = 100;
int* px = x;
printVal(px);
}

It will print error.

My advise is not to use T:T* or T:T[] it works only when explicitly
instantiate. Is better use T:M*,M or T:M[], M because it works
automaticly and you have both types available.

import std.stdio;

void printVal(T)(T t) {
writeln(t);
}

void printVal(T:M*,M)(T t) {
writeln(*t);
}

void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);// prints the 100
}


Re: Template type deduction and specialization

2015-05-20 Thread Daniel Kozak via Digitalmars-d-learn

On Wednesday, 20 May 2015 at 09:24:28 UTC, Daniel Kozák wrote:


On Wed, 20 May 2015 06:31:11 +
Mike Parker via Digitalmars-d-learn 
digitalmars-d-learn@puremagic.com

wrote:

I don't understand why this behaves as it does. Given the 
following two templates:


```
void printVal(T)(T t) {
writeln(t);
}
void printVal(T : T*)(T* t) {
writeln(*t);
}
```

I find that I actually have to explicitly instantiate the 
template with a pointer type to get the specialization.


```
void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);// prints the address
 printVal!(int*)(px)  // prints 100
}
```

Intuitively, I would expect the specialization to be deduced 
without explicit instantiation. Assuming this isn't a bug 
(I've been unable to turn up anything in Bugzilla), could 
someone in the know explain the rationale behind this?


Because it cannot deduce type T:

try this:

void printVal(T : T*)(T* t) {
writeln(*t);
}

void main() {
int x = 100;
int* px = x;
printVal(px);
}

It will print error.

My advise is not to use T:T* or T:T[] it works only when 
explicitly

instantiate. Is better use T:M*,M or T:M[], M because it works
automaticly and you have both types available.

import std.stdio;

void printVal(T)(T t) {
writeln(t);
}

void printVal(T:M*,M)(T t) {
writeln(*t);
}

void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);// prints the 100
}


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


Re: Template type deduction and specialization

2015-05-20 Thread Mike Parker via Digitalmars-d-learn

On 5/20/2015 4:36 PM, Namespace wrote:


What about:

import std.stdio;

void printVal(T)(T t) {
 static if (is(T : U*, U))
 printVal(*t);
 else
 writeln(t);
}


Thanks, but I'm not looking for alternatives. I'm trying to figure out 
why it doesn't work as expected.




Re: Template type deduction and specialization

2015-05-20 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 20, 2015 06:31:11 Mike Parker via Digitalmars-d-learn wrote:
 I don't understand why this behaves as it does. Given the
 following two templates:

 ```
 void printVal(T)(T t) {
   writeln(t);
 }
 void printVal(T : T*)(T* t) {
   writeln(*t);
 }
 ```

 I find that I actually have to explicitly instantiate the
 template with a pointer type to get the specialization.

 ```
 void main() {
   int x = 100;
   printVal(x);
   int* px = x;
   printVal(px);// prints the address
  printVal!(int*)(px)  // prints 100
 }
 ```

 Intuitively, I would expect the specialization to be deduced
 without explicit instantiation. Assuming this isn't a bug (I've
 been unable to turn up anything in Bugzilla), could someone in
 the know explain the rationale behind this?

Well, if

printVal!(int*)(px);

prints 100, then that's a bug. It should print the address. In fact, it
should be _impossible_ for the second overload of printVal to ever be
instantiated. Think about it. What does T : T* mean? It means that T is
implicitly convertible to T*. And when is a type ever implicitly convertible
to a pointer to itself?

int x = 100;
int y = x;

isn't going to compile, so neither should that second overload ever end up
being used. Use std.traits.isPointer if you want to test for whether a type
is a pointer or not.

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



Re: Template type deduction and specialization

2015-05-20 Thread Daniel Kozak via Digitalmars-d-learn

On Wednesday, 20 May 2015 at 07:27:53 UTC, jklp wrote:


---
import std.stdio;

void printVal(T)(T t) {
writeln(t);
}

void printVal(T: T)(T* t) {
writeln(*t);
}

void main() {
int x = 100;
printVal(x);
int* px = x;
printVal(px);
}
---

here it's selected correctly without explicit instantiation. 
But honestly i don't know why since the  asterisk is removed 
from the T it looks quite incorrect.


No it is correct it is same as:
void printVal(T: int)(T* t) {
writeln(*t);
}


Re: Template type deduction and specialization

2015-05-20 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 20, 2015 07:36:21 Namespace via Digitalmars-d-learn wrote:
 What about:
 
 import std.stdio;

 void printVal(T)(T t) {
  static if (is(T : U*, U))
  printVal(*t);
  else
  writeln(t);
 }

 void main() {
  int x = 100;
  printVal(x);
  int* px = x;
  printVal(px);
 }
 

That mostly works, but you it runs the classic risk of running into problems
with alias this (which is why checking for implicit conversions in static if
or template constraints is so incredibly dangerous if you're not _very_
careful). std.traits defines isPointer as follows:

enum bool isPointer(T) = is(T == U*, U)  !isAggregateType!T;

which avoids the alias this problem. Regardless, it's more idiomatic to just
use isPointer.

- Jonathan M Davis



Re: Template type deduction and specialization

2015-05-20 Thread Daniel Kozak via Digitalmars-d-learn

On Wednesday, 20 May 2015 at 09:35:48 UTC, Jonathan M Davis wrote:


Well, if

printVal!(int*)(px);

prints 100, then that's a bug. It should print the address. In 
fact, it
should be _impossible_ for the second overload of printVal to 
ever be

instantiated


IMHO thats not true, it should print 100. This is what spec say.

void printVal(T : T*)(T* t) {
writeln(*t);
}

T is deduce to be int so we have

void printVal(int* t) {
writeln(*t);
}

which will print value not address


Re: Template type deduction and specialization

2015-05-20 Thread Mike Parker via Digitalmars-d-learn

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.


Re: Template type deduction and specialization

2015-05-20 Thread Daniel Kozák via Digitalmars-d-learn
DOC say  `may not have` not `must not have` ;-)

On Wed, 20 May 2015 13:24:22 +
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.


Re: Template type deduction and specialization

2015-05-20 Thread Ali Çehreli via Digitalmars-d-learn

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



Re: Template type deduction and specialization

2015-05-20 Thread Mike Parker via Digitalmars-d-learn

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.


Re: Template type deduction and specialization

2015-05-20 Thread Jonathan M Davis via Digitalmars-d-learn
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