December 27, 2012 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 Kenji Hara <k.hara.pg@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull --- Comment #9 from Kenji Hara <k.hara.pg@gmail.com> 2012-12-27 01:34:31 PST --- https://github.com/D-Programming-Language/dmd/pull/1409 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 25, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 Kenji Hara <k.hara.pg@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords|pull | --- Comment #10 from Kenji Hara <k.hara.pg@gmail.com> 2013-02-24 21:32:10 PST --- (In reply to comment #9) > https://github.com/D-Programming-Language/dmd/pull/1409 By implementing it, I found some corner cases. How should these behave? int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } // vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } // vs deduced parameter + template constraint (1) int f5(int a) { return 1; } int f5(T)(T b) if (is(T == int)) { return 2; } // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } void main() { f1(1); // ambiguous error f1(1L); // ambiguous error f2(1); // ambiguous error f2(1L); // ambiguous error f3(1); // ? f3(1L); // ? f4(1); // ? f4(1L); // ? f5(1); // ? f5(1L); // ? f6(1); // ? f6(1L); // ? } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 25, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 --- Comment #11 from Walter Bright <bugzilla@digitalmars.com> 2013-02-24 21:54:47 PST --- (In reply to comment #10) > f3(1); // 1 > f3(1L); // 2 > > f4(1); // ambiguous > f4(1L); // ambiguous > > f5(1); // 1 > f5(1L); // 1 > > f6(1); // 1 > f6(1L); // 2 > } The more specialized overload always wins. The constraint is not considered when evaluating which is "more specialized". (Because in general we cannot evaluate that.) The constraint only determines if an overload is to be considered - it does not determine ordering. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 25, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 --- Comment #12 from Kenji Hara <k.hara.pg@gmail.com> 2013-02-24 22:30:26 PST --- (In reply to comment #11) > The more specialized overload always wins. > > The constraint is not considered when evaluating which is "more specialized". (Because in general we cannot evaluate that.) The constraint only determines if an overload is to be considered - it does not determine ordering. Thanks for quickly answer. So, the resolution result of f5 and f6 should be same as f3, because they are identical when hide their constraints. Right? But, there is still questionable. How to calculate "The more specialized overload" between function template and non-template one? For example, try to consider case for f3(1). That is: 1. Normal function version f3(int) will match exactly to one int argument. 2. Function template version will deduce T <- int, and then instantiated function f3!(int) == void f3(int) will match _exactly_ to one int argument. But, in general, template version is less specialized than non-template version. So, there is something necessary for ordering. --- Consider one another case for f4(1L). That is: 1. Normal function will match to one long argument with conversion (MATCHconvert). 2. Function template version will deduce T <- long and then instantiated function f4!long will match exactly to one long argument. Which is specialized? In general, template version would be intended to pick up non-exact matching for generic cases. But, as far as I infer from current dmd implementation, f4(1L) will be ambiguous (template type parameter deduction without specialization always be MATCHconvert). Therefore, I'd ask question again to Walter: how does above cases behave? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 25, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 timon.gehr@gmx.ch changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |timon.gehr@gmx.ch --- Comment #13 from timon.gehr@gmx.ch 2013-02-25 02:15:54 PST --- (In reply to comment #12) > ... > > Therefore, I'd ask question again to Walter: how does above cases behave? I have implemented it in accordance with TDPL, and the following behaviour results: int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } // vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } // vs deduced parameter + template constraint (1) int f5(int a) { return 1; } int f5(T)(T b) if (is(T == int)) { return 2; } // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } void main(){ f1(1); // error: ambiguous f1(1L); // error: ambiguous f2(1); // error: ambiguous f2(1L); // error: no match static assert(f3(1)==1); static assert(f3(1L)==2); static assert(f4(1)==1); static assert(f4(1L)==1); static assert(f5(1)==1); static assert(f5(1L)==1); static assert(f6(1)==1); static assert(f6(1L)==1); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 27, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 monarchdodra@gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |monarchdodra@gmail.com --- Comment #14 from monarchdodra@gmail.com 2013-02-27 04:39:08 PST --- (In reply to comment #13) > I have implemented it in accordance with TDPL, and the following behaviour results: > > // vs deduced parameter + template constraint (2) > int f6(int a) { return 1; } > int f6(T)(T b) if (is(T : int)) { return 2; } > > void main(){ > static assert(f6(1)==1); > static assert(f6(1L)==1); > } How does that work though, because here, you statically know that 1L will fit in your int. But what about: static assert(f6(1L) == 1); static assert(f6(ulong.max) == 2); // (a) ??? ulong ul = runtime(); static assert(f6(ul) == 2); // (b) ??? How would these resolve? I am not really comfortable with the fact that a call can statically resolve to two different functions depending on the static information of the *value* of a parameter: int f7(ubyte a) { return 1; } int f7(T)(T b) if (is(T : int)) { return 2; } void main(){ static assert(f6(200u)==1); //Calls first static assert(f6(400u)==2); //Calls second (!?) //Run-time variable with TDPL-like range knowledge uint a = 400; static assert(f6(a) == 2); //Calls second ? a = 200; static assert(f6(a) == 1); //But now calls first !? } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 27, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 --- Comment #15 from timon.gehr@gmx.ch 2013-02-27 06:29:43 PST --- (In reply to comment #14) > ... > > static assert(f6(1L) == 1); > static assert(f6(ulong.max) == 2); // (a) ??? > No match. > ulong ul = runtime(); > static assert(f6(ul) == 2); // (b) ??? > No match. > How would these resolve? > > I am not really comfortable with the fact that a call can statically resolve to two different functions depending on the static information of the *value* of a parameter: > Well, that is how the language is specified. int f8(byte){ return 1; } int f8(long){ return 2; } void main(){ static assert(f8(1)==1); // calls first static assert(f8(256)==2); // calls second int x=1; f8(x); // calls second } > int f7(ubyte a) { return 1; } > int f7(T)(T b) if (is(T : int)) { return 2; } > > void main(){ > static assert(f6(200u)==1); //Calls first No, calls second. > static assert(f6(400u)==2); //Calls second (!?) > Yes. > //Run-time variable with TDPL-like range knowledge > uint a = 400; Knowledge lost here. > static assert(f6(a) == 2); //Calls second ? > a = 200; Ditto. > static assert(f6(a) == 1); //But now calls first !? > } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 01, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 --- Comment #16 from Kenji Hara <k.hara.pg@gmail.com> 2013-02-28 20:46:30 PST --- (In reply to comment #13) > // vs specialized parameter > int f4(int a) { return 1; } > int f4(T:int)(T b) { return 2; } > static assert(f4(1)==1); Just only this is wrong. f4(T:int) is specialized to int argument, so f4(1) could match both normal function version and template version *with the same extent*. Then it will be ambiguous. > static assert(f4(1L)==1); Ok. f4(T:int) cannot instantiate with T==long, so first version will be called. (In reply to comment #15) > (In reply to comment #14) > > ... > > > > static assert(f6(1L) == 1); > > static assert(f6(ulong.max) == 2); // (a) ??? > > > > No match. > > > ulong ul = runtime(); > > static assert(f6(ul) == 2); // (b) ??? > > > > No match. Both (a) and (b) should be "no match", but with my experimental change, (a) wrongly matches to int. I found an another bug in there, and filed it as bug 9617. Current test case results with my pull request: https://github.com/D-Programming-Language/dmd/pull/1409 is: -------- int f1(int a, double=10) { return 1; } int f1(int a, string="") { return 2; } int f2(T:int)(T b, double=10) { return 1; } int f2(T:int)(T b, string="") { return 2; } // vs deduced parameter int f3(int a) { return 1; } int f3(T)(T b) { return 2; } // vs specialized parameter int f4(int a) { return 1; } int f4(T:int)(T b) { return 2; } // vs deduced parameter + template constraint (1) int f5(int a) { return 1; } int f5(T)(T b) if (is(T == int)) { return 2; } // vs deduced parameter + template constraint (2) int f6(int a) { return 1; } int f6(T)(T b) if (is(T : int)) { return 2; } // vs nallowing conversion int f7(ubyte a) { return 1; } int f7(T)(T b) if (is(T : int)) { return 2; } void main() { static assert(!__traits(compiles, f1(1))); // ambiguous static assert(!__traits(compiles, f1(1L))); // ambiguous static assert(!__traits(compiles, f2(1))); // ambiguous static assert(!__traits(compiles, f2(1L))); // no match assert(f3(1) == 1); assert(f3(1L) == 2); static assert(!__traits(compiles, f4(1))); assert(f4(1L) == 1); assert(f5(1) == 1); assert(f5(1L) == 1); assert(f6(1) == 1); assert(f6(1L) == 1); static assert(!__traits(compiles, f6(ulong.max))); // no match // needs to fix bug 9617 ulong ulval = 1; static assert(!__traits(compiles, f6(ulval))); // no match assert(f7(200u) == 2); assert(f7(400u) == 2); uint uival = 400; // TDPL-like range knowledge lost here. assert(f7(uival) == 2); a = 200; // Ditto. assert(f7(uival) == 2); } -------- I welcome more complicated test case. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 01, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 Martin Nowak <code@dawg.eu> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |code@dawg.eu --- Comment #17 from Martin Nowak <code@dawg.eu> 2013-03-01 02:19:23 PST --- > template type parameter deduction without specialization always be MATCHconvert AFAIK this is a kludgy implementation detail to make specialization work. The last time we worked on that we concluded (with Daniel Murphy?) that there should be an additional level between convert and exact. I don't remember the details right now, but I'll try to find the relevant discussion. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 01, 2013 [Issue 1528] [tdpl] overloading template and non-template functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1528 --- Comment #18 from timon.gehr@gmx.ch 2013-03-01 03:15:40 PST --- (In reply to comment #17) > > template type parameter deduction without specialization always be MATCHconvert > > AFAIK this is a kludgy implementation detail It is a bug. > to make specialization work. Why wouldn't they work otherwise? > The > last time we worked on that we concluded (with Daniel Murphy?) that there > should be an additional level between convert and exact. I don't remember the > details right now, but I'll try to find the relevant discussion. There already is a level between them (conversion to const.) Anyway, I do not see why another level would be required, or even helpful in any way. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation