digitalmars.D - overloading functions against function templates
- Walter Bright (7/7) Jul 30 2009 Currently, that can't be done. But it would be good to get it in for D2....
- grauzone (2/3) Jul 30 2009 What for?
- bearophile (4/5) Jul 30 2009 Even if for every person that may ask for such feature, there are probab...
- Trass3r (2/3) Jul 30 2009 That's true :)
- bearophile (18/25) Jul 30 2009 I'm ignorant, so here is an example to see if I have understood what you...
- ponce (6/6) Jul 30 2009 How would compete template specialization and matching functions ?
- Michal Minich (16/30) Jul 31 2009 I'm not sure by choosing function first, code size will be lower.
- BCS (8/22) Jul 30 2009 That sounds good.
- Lutger (3/3) Jul 30 2009 My intuition would be that functions are more concrete than templates, a...
- Lars T. Kyllingstad (27/39) Jul 31 2009 I think:
- BCS (4/32) Jul 31 2009 Something about that rules set doesn't seem rigorous enough. I'm not sur...
- Sergey Gromov (22/34) Jul 31 2009 I think regular functions should go first.
- Jason House (3/5) Jul 31 2009 My vote would be to use partial ordering [1] for consistency. I'm just n...
Currently, that can't be done. But it would be good to get it in for D2. The question is, what rule to use? I suggest that: 1. if any functions match, then overload functions the usual way 2. if no functions match, then overload the function templates the usual way Or reverse the priority of the two. What do you think?
Jul 30 2009
Walter Bright wrote:Currently, that can't be done. But it would be good to get it in for D2.What for?
Jul 30 2009
grauzone:What for?<Even if for every person that may ask for such feature, there are probably 30 persons that may ask for the "stacktrace hack" built-in in DMD, I presume such overload of functions against function templates is more fun to implement :-) DMD is probably fun-driven too, not just community-needs-driven :-) Bye, bearophile
Jul 30 2009
bearophile schrieb:Even if for every person that may ask for such feature, there are probably 30 persons that may ask for the "stacktrace hack" built-in in DMDThat's true :)
Jul 30 2009
Walter Bright:Currently, that can't be done. But it would be good to get it in for D2.<I think someone has already asked for this feature, time ago :-)The question is, what rule to use? I suggest that: 1. if any functions match, then overload functions the usual way 2. if no functions match, then overload the function templates the usual way Or reverse the priority of the two. What do you think?I'm ignorant, so here is an example to see if I have understood what you mean: import std.stdio: writeln; double foo(int x) { return x * 2; } double foo(float x) { return x * 3; } double foo(T)(T x) { return x * 4; } double foo(T : double)(T x) { return x * 5; } void main() { writeln(foo(10)); // prints: writeln(foo(10.5)); // prints: writeln(foo(10.5f)); // prints: writeln(foo(10U)); // prints: } What's the output? I think functions have to be used first, when possible, to reduce "template bloat". Bye, bearophile
Jul 30 2009
How would compete template specialization and matching functions ? like : double foo(double x) { return x * 2; } double foo(T)(T x) { return x * 3; } double foo(T : double)(T x) { return x * 4; } writeln(foo(4.0));
Jul 30 2009
bearophile wrote:import std.stdio: writeln; double foo(int x) { return x * 2; } double foo(float x) { return x * 3; } double foo(T)(T x) { return x * 4; } double foo(T : double)(T x) { return x * 5; } void main() { writeln(foo(10)); // prints: writeln(foo(10.5)); // prints: writeln(foo(10.5f)); // prints: writeln(foo(10U)); // prints: } What's the output? I think functions have to be used first, when possible, to reduce "template bloat".I'm not sure by choosing function first, code size will be lower. I'm not sure how dmd works, but I think by choosing template foo, code will be generated only once for both Point and size classes. (correct me if I'm wrong) Thus I agree the functions should be chosen first, because functions are more specific. class Point { int x, y; } class Size { int width, height; } void foo (Point P) { ... } void foo (Size s) { ... } void foo (T) (T t) { ... } void main () { foo (new Point()); foo (new Point()); }
Jul 31 2009
Reply to Walter,Currently, that can't be done. But it would be good to get it in for D2. The question is, what rule to use? I suggest that: 1. if any functions match, then overload functions the usual way 2. if no functions match, then overload the function templates the usual way Or reverse the priority of the two. What do you think?That sounds good. One other option would be to go with: 1. if any function matches exactly, then use it 2. if no function match exactly, then overload the function templates the usual way. overload list and process it the usual way.
Jul 30 2009
My intuition would be that functions are more concrete than templates, and thus will be checked first. Will implicit conversions match the same way as exact type matches?
Jul 30 2009
Walter Bright wrote:Currently, that can't be done. But it would be good to get it in for D2. The question is, what rule to use?Yay! I've been waiting for this! :)I suggest that: 1. if any functions match, then overload functions the usual way 2. if no functions match, then overload the function templates the usual way Or reverse the priority of the two. What do you think?I think: 1: Look for exact function matches 2: Look for exact function template matches 3: Look for compatible function matches 4: Look for compatible function template matches If you are going to allow ordinary and templated functions to overload against each other, there is a problem with IFTI that I think will become more visible. It's something I run into all the time: T sum(T)(T a, T b) { return a + b; } real x = 2.0; real y = sum(1.0, x); The above doesn't compile, because 1.0 is a double literal, while x is a real. However, if this was an ordinary function with T->real, it would be valid code. I think it should also work with templates. Granted, I don't know how the matching procedure works now, but for this case I picture it could be something like this: Given: T sum(T)(T a, T b, T c) { return a + b + c; } sum(x, y, z); then do the following: 1: Try T = typeof(x). If it works, use it. 2: Try T = typeof(y). If it works, use it. 3: Try T = typeof(z). If it works, use it. 4: Give template matching error. -Lars
Jul 31 2009
Hello Lars,If you are going to allow ordinary and templated functions to overload against each other, there is a problem with IFTI that I think will become more visible. It's something I run into all the time: T sum(T)(T a, T b) { return a + b; } real x = 2.0; real y = sum(1.0, x); The above doesn't compile, because 1.0 is a double literal, while x is a real. However, if this was an ordinary function with T->real, it would be valid code. I think it should also work with templates.Ditto on thisGranted, I don't know how the matching procedure works now, but for this case I picture it could be something like this: Given: T sum(T)(T a, T b, T c) { return a + b + c; } sum(x, y, z); then do the following: 1: Try T = typeof(x). If it works, use it. 2: Try T = typeof(y). If it works, use it. 3: Try T = typeof(z). If it works, use it. 4: Give template matching error.Something about that rules set doesn't seem rigorous enough. I'm not sure what.
Jul 31 2009
Thu, 30 Jul 2009 14:09:21 -0700, Walter Bright wrote:Currently, that can't be done. But it would be good to get it in for D2. The question is, what rule to use? I suggest that: 1. if any functions match, then overload functions the usual way 2. if no functions match, then overload the function templates the usual way Or reverse the priority of the two. What do you think?I think regular functions should go first. Let's take 4 functions for example: void foo(int); void foo(long); void foo(T)(T); void foo(T : int)(T); and call foo(5); If regular functions go first, we can order ours by match quality: void foo(int); <= best void foo(long); void foo(T : int)(T); void foo(T)(T); <= worst That's OK, the worst match is the least specialized template. But if we consider templates first: void foo(T : int)(T); <= best void foo(T)(T); void foo(int); void foo(long); <= worst What I strongly dislike about this is that a generic, non-specialized foo(T)(T) effectively hides any non-templated and obviously more specialized regular functions. I think this simply won't work.
Jul 31 2009
Walter Bright Wrote:Currently, that can't be done. But it would be good to get it in for D2. The question is, what rule to use?My vote would be to use partial ordering [1] for consistency. I'm just not sure what that would mean in this situation :( [1] http://dobbscodetalk.com/index.php?option=com_myblog&show=Function-Overloading-With-Partial-Ordering.html&Itemid=29
Jul 31 2009