digitalmars.D - What to do about default function arguments
- Walter Bright (10/10) Apr 25 2012 A subtle but nasty problem - are default arguments part of the type, or ...
- Nathan M. Swan (4/16) Apr 25 2012 I don't think it's a bad thing: default arguments in the type
- Jonathan M Davis (13/28) Apr 25 2012 Can function pointers have default arguments in C? Honestly, it strikes ...
- Walter Bright (4/7) Apr 25 2012 One might suggest mangling the default argument into the type. But defau...
- Sean Kelly (6/12) Apr 26 2012 hen
- Walter Bright (3/4) Apr 26 2012 Pretty much. I posted it here to see if I missed something major. Not th...
- deadalnix (2/6) Apr 26 2012 Why does default argument should be mangled at all ?
- Martin Nowak (37/47) Apr 26 2012 import std.stdio;
- Martin Nowak (1/2) Apr 26 2012 That was wrong, this should be supported through implicit conversion.
- H. S. Teoh (26/39) Apr 25 2012 My intuition suggests they are part of the declaration, but not part of
- Walter Bright (3/10) Apr 25 2012 Give you two error messages, because default arguments wouldn't be allow...
- H. S. Teoh (6/19) Apr 25 2012 No I mean the current behaviour. And I just checked: dmd compiles it
- Walter Bright (2/18) Apr 25 2012 Hence the problem :-)
- Ary Manzana (5/16) Apr 25 2012 I don't understand the relationship between two delegate types being the...
- Walter Bright (3/7) Apr 25 2012 If you call a delegate directly, then the default arguments work. If you...
- H. S. Teoh (6/15) Apr 26 2012 This is even more an argument for *not* including default arguments in
- Maxim Fomin (14/26) Apr 25 2012 From what I would name "normative" view they should be the same
- Timon Gehr (13/25) Apr 26 2012 It contributes, but it is not the main cause.
- Walter Bright (6/25) Apr 26 2012 This is simply not tenable. What defines when they are "equal" types and...
- Timon Gehr (11/47) Apr 26 2012 This is a matter of terminology. For example, for 'equal' just exclude
- Don Clugston (5/44) Apr 26 2012 The language doesn't have the concepts of "same" and "equal" with
- Timon Gehr (5/53) Apr 26 2012 I think I have answered that. Anyway, probably it is indeed a good idea
- Walter Bright (3/8) Apr 26 2012 That's the problem - the selection of arbitrary rules.
- Timon Gehr (2/12) Apr 26 2012 It is not entirely arbitrary. Anyway, point taken.
- Don Clugston (20/31) Apr 26 2012 I think it is a mistake to allow default arguments in function pointers
- Timon Gehr (4/39) Apr 26 2012 We probably don't.
- Don Clugston (3/25) Apr 26 2012 No it doesn't. A default argument is a delegate literal is part of the
- Timon Gehr (5/31) Apr 26 2012 If types cannot specify default arguments, then those will be thrown
- Don Clugston (7/42) Apr 26 2012 Fair point. It could be used in the case where it is called at the point...
- Jacob Carlborg (4/7) Apr 26 2012 Why not?
- Walter Bright (3/8) Apr 26 2012 Because a function pointer, and delegate, can exist without a correspond...
- Trass3r (3/3) Apr 26 2012 I've always thought of default arguments to be plain syntactic sugar, so...
- Michel Fortin (24/38) Apr 26 2012 Assuming we want to allow it, all you need is to treat the type having
- bearophile (8/10) Apr 26 2012 Good reminder. I think such parts of D shouldn't be designed one
- deadalnix (5/16) Apr 26 2012 Maybe the problem is that type are considered to be the same when the
- bearophile (32/34) Apr 26 2012 I'm waiting for years to see you finally facing this problem too
- Jonathan M Davis (26/30) Apr 26 2012 No it doesn't. You could definitely have a pointer to function with defa...
- Steven Schveighoffer (33/44) Apr 26 2012 Some testing (2.059):
- Steven Schveighoffer (20/33) Apr 26 2012 Nevermind, I just realized it was ignoring my pure nothrow @safe for the...
- Joseph Rushton Wakeling (21/24) Apr 26 2012 I can't see disallowing default arguments as being a good thing. For ex...
- Daniel Murphy (5/16) Apr 26 2012 From what I remember, function pointer parameter names have similar
- Jonathan M Davis (17/48) Apr 26 2012 There is an _enormous_ difference between disallowing default arguments ...
- Joseph Rushton Wakeling (12/14) Apr 26 2012 I think maybe I've misunderstood the problem. Are we talking about defa...
- Jonathan M Davis (27/45) Apr 26 2012 The second. If you have
- Manu (9/46) Apr 26 2012 I've actually been making fairly extensive use of function/delegate defa...
A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)
Apr 25 2012
On Thursday, 26 April 2012 at 03:44:27 UTC, Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I don't think it's a bad thing: default arguments in the type system mean values in the type system. NMS
Apr 25 2012
On Wednesday, April 25, 2012 20:44:07 Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)Can function pointers have default arguments in C? Honestly, it strikes me as rather bizarre for them to have default arguments. I really don't think that they buy you much. If you use the function or delegate immediately after declaring it (as is typically the case when they're nested), then you could have just just put the default argument in the function itself and not have it as a parameter. And if you're holding on to a function or delegate long term, you're almost certainly going to be using it generically, in which case I wouldn't expect a default argument to make sense there often either. I'd vote to just disallow default arguments for function pointers and delegates. - Jonathan M Davis
Apr 25 2012
On 4/25/2012 8:44 PM, Walter Bright wrote:The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior.One might suggest mangling the default argument into the type. But default arguments need not be compile time constants - they are evaluated at runtime! Hence the unattractive specter of trying to mangle a runtime expression.
Apr 25 2012
On Apr 25, 2012, at 9:10 PM, Walter Bright <newshound2 digitalmars.com> wrot= e:On 4/25/2012 8:44 PM, Walter Bright wrote:henThe problem centers around name mangling. If two types mangle the same, t=they are the same type. But default arguments are not part of the mangled=arguments need not be compile time constants - they are evaluated at runtim= e! Hence the unattractive specter of trying to mangle a runtime expression. Sounds to me like you just answered your own question :-)=string. Hence the schizophrenic behavior.=20 One might suggest mangling the default argument into the type. But default=
Apr 26 2012
On 4/26/2012 8:06 AM, Sean Kelly wrote:Sounds to me like you just answered your own question :-)Pretty much. I posted it here to see if I missed something major. Not that that ever happens :-)
Apr 26 2012
Le 26/04/2012 20:49, Walter Bright a écrit :On 4/26/2012 8:06 AM, Sean Kelly wrote:Why does default argument should be mangled at all ?Sounds to me like you just answered your own question :-)Pretty much. I posted it here to see if I missed something major. Not that that ever happens :-)
Apr 26 2012
On Thu, 26 Apr 2012 06:10:14 +0200, Walter Bright <newshound2 digitalmars.com> wrote:On 4/25/2012 8:44 PM, Walter Bright wrote:import std.stdio; int readVal() { int val; stdin.readf("%s", &val); return val; } void main() { auto dg = (int a=readVal()) => a; writeln(dg()); } ---- Stuffing the value into the type is not going to work out when taking the address. I think it would be interesting to transform them to values of a type that preserves the behavior. This would work for polymorphic lambdas as values too. ---- auto dg = (int a=readVal()) => a; static struct Lamba { int opCall() { return fbody(readVal()); } int opCall(int a) { return fbody(a); } int function(int) opAddrOf() { return &fbody; } static int fbody(int a) { return a; } } ---- auto dg = a => 2 * a; struct Lambda { auto opCall(Ta)(auto ref Ta a) { return fbody(a); } disable opAddrOf(); /*static*/ auto fbody(Ta)(Ta a) { return 2 * a; } }The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior.One might suggest mangling the default argument into the type. But default arguments need not be compile time constants - they are evaluated at runtime! Hence the unattractive specter of trying to mangle a runtime expression.
Apr 26 2012
int function(int) opAddrOf() { return &fbody; }That was wrong, this should be supported through implicit conversion.
Apr 26 2012
On Wed, Apr 25, 2012 at 08:44:07PM -0700, Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration?My intuition suggests they are part of the declaration, but not part of the type. For example, you could have two functions: void f(int a, int b); void g(int a, int b=1); Are they the same type? I say yes, because both functions accept two int arguments. Nothing about g suggests that it's any different from f, except for the syntactic sugar that you can write g(1) instead of g(1,1). So the default argument really is just part of the declaration, not the type.See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior.This is bad. What if you have two delegates with different default arguments? What would this code do: auto foo = (int a=1) { return a; }; auto bar = (int a=2) { return a; }; writeln(foo()); writeln(bar()); ?But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I see default arguments as syntactic sugar; they are to avoid typing commonly used trailing arguments repeatedly. They don't make sense in the context of func ptrs and delegates because presumably you're using a func ptr or a delegate for generic handling, as Jonathan said, so you wouldn't be relying on default arguments anyway. So default arguments aren't really useful in this case. No big loss if we lose them. T -- Computers aren't intelligent; they only think they are.
Apr 25 2012
On 4/25/2012 9:42 PM, H. S. Teoh wrote:This is bad. What if you have two delegates with different default arguments? What would this code do: auto foo = (int a=1) { return a; }; auto bar = (int a=2) { return a; }; writeln(foo()); writeln(bar()); ?Give you two error messages, because default arguments wouldn't be allowed for delegates.
Apr 25 2012
On Wed, Apr 25, 2012 at 10:08:26PM -0700, Walter Bright wrote:On 4/25/2012 9:42 PM, H. S. Teoh wrote:No I mean the current behaviour. And I just checked: dmd compiles it fine, and prints 1 for both cases (which is wrong). T -- EMACS = Extremely Massive And Cumbersome SystemThis is bad. What if you have two delegates with different default arguments? What would this code do: auto foo = (int a=1) { return a; }; auto bar = (int a=2) { return a; }; writeln(foo()); writeln(bar()); ?Give you two error messages, because default arguments wouldn't be allowed for delegates.
Apr 25 2012
On 4/25/2012 10:20 PM, H. S. Teoh wrote:On Wed, Apr 25, 2012 at 10:08:26PM -0700, Walter Bright wrote:Hence the problem :-)On 4/25/2012 9:42 PM, H. S. Teoh wrote:No I mean the current behaviour. And I just checked: dmd compiles it fine, and prints 1 for both cases (which is wrong).This is bad. What if you have two delegates with different default arguments? What would this code do: auto foo = (int a=1) { return a; }; auto bar = (int a=2) { return a; }; writeln(foo()); writeln(bar()); ?Give you two error messages, because default arguments wouldn't be allowed for delegates.
Apr 25 2012
On 4/26/12 11:44 AM, Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I don't understand the relationship between two delegate types being the same and thus sharing the same implementation for default arguments for *different instances* of a delegate with the same type. Maybe a bug in how it's currently implemented?
Apr 25 2012
On 4/25/2012 10:29 PM, Ary Manzana wrote:I don't understand the relationship between two delegate types being the same and thus sharing the same implementation for default arguments for *different instances* of a delegate with the same type. Maybe a bug in how it's currently implemented?If you call a delegate directly, then the default arguments work. If you call it indirectly, the default arguments won't work.
Apr 25 2012
On Wed, Apr 25, 2012 at 10:39:01PM -0700, Walter Bright wrote:On 4/25/2012 10:29 PM, Ary Manzana wrote:This is even more an argument for *not* including default arguments in the type. T -- IBM = I Blame MicrosoftI don't understand the relationship between two delegate types being the same and thus sharing the same implementation for default arguments for *different instances* of a delegate with the same type. Maybe a bug in how it's currently implemented?If you call a delegate directly, then the default arguments work. If you call it indirectly, the default arguments won't work.
Apr 26 2012
On Thursday, 26 April 2012 at 03:44:27 UTC, Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report.From what I would name "normative" view they should be the same type: function type is charcterized by return type and by number and order of parameters' types. Because both functions accept and return the same types they should be the same function type. On the other hand, D is an ongoing project and you are free to implement special behavior.The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior.I think it should be done in reverse order: firstly decide whether they are the same or not, than apply mangling to the decision. Tail doesn't wag a dog.But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)The bad thing is that we would need extra typing, the good thing is that if the declaration changes the bug wouldn't be hidden. That I find similar to the D policy of preventing function hijacking, etc.
Apr 25 2012
On 04/26/2012 05:44 AM, Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both,That is how it should be.which leads to the nasty behavior in the bug report.It contributes, but it is not the main cause.The problem centers around name mangling. If two types mangle the same, then they are the same type.Then they are equal types.But default arguments are not part of the mangled string. Hence the schizophrenic behavior.The schizophrenic behavior occurs because the types cross-talk. Are mangled names kept unique in the compiler or what is the implementation issue exactly?But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I think default arguments for delegates and function pointers are quite a feat. The proposal is to change the language in a backwards-incompatible way based on implementation issues that shouldn't be that hard to resolve. (Related: Template instantiation should strip off the default arguments from delegate and function pointer types.)
Apr 26 2012
On 4/26/2012 12:47 AM, Timon Gehr wrote:On 04/26/2012 05:44 AM, Walter Bright wrote:This is simply not tenable. What defines when they are "equal" types and when they are "not equal"? Consider a pointer to a function. Are the default arguments part of its type? If it compares "equal" to another type without default arguments, which is the real type (such as the result of ?:) ?A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both,That is how it should be.which leads to the nasty behavior in the bug report.It contributes, but it is not the main cause.The problem centers around name mangling. If two types mangle the same, then they are the same type.Then they are equal types.It's a conceptual issue. When is one type the same as another, and when is it not?But default arguments are not part of the mangled string. Hence the schizophrenic behavior.The schizophrenic behavior occurs because the types cross-talk. Are mangled names kept unique in the compiler or what is the implementation issue exactly?
Apr 26 2012
On 04/26/2012 09:54 AM, Walter Bright wrote:On 4/26/2012 12:47 AM, Timon Gehr wrote:This is a matter of terminology. For example, for 'equal' just exclude the default parameters from the comparison. For 'the same' include default parameters in the comparison. (therefore, 'the same' implies 'equal')On 04/26/2012 05:44 AM, Walter Bright wrote:This is simply not tenable. What defines when they are "equal" types and when they are "not equal"?A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both,That is how it should be.which leads to the nasty behavior in the bug report.It contributes, but it is not the main cause.The problem centers around name mangling. If two types mangle the same, then they are the same type.Then they are equal types.Consider a pointer to a function. Are the default arguments part of its type?Yes.If it compares "equal" to another type without default arguments, which is the real type (such as the result of ?:) ?The result of ?: is the type of the two arguments if they are the same, and it is the equal type without default arguments if they are not the same.void function(int) is the same as void function(int) and both are equal void function(int=2) is not the same as void function(int=3), but both are equal.It's a conceptual issue. When is one type the same as another, and when is it not?But default arguments are not part of the mangled string. Hence the schizophrenic behavior.The schizophrenic behavior occurs because the types cross-talk. Are mangled names kept unique in the compiler or what is the implementation issue exactly?
Apr 26 2012
On 26/04/12 11:21, Timon Gehr wrote:On 04/26/2012 09:54 AM, Walter Bright wrote:The language doesn't have the concepts of "same" and "equal" with respect to types. There is "equal" and "implicitly converts to", but that's not quite the same.On 4/26/2012 12:47 AM, Timon Gehr wrote:This is a matter of terminology. For example, for 'equal' just exclude the default parameters from the comparison. For 'the same' include default parameters in the comparison. (therefore, 'the same' implies 'equal')On 04/26/2012 05:44 AM, Walter Bright wrote:This is simply not tenable. What defines when they are "equal" types and when they are "not equal"?A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both,That is how it should be.which leads to the nasty behavior in the bug report.It contributes, but it is not the main cause.The problem centers around name mangling. If two types mangle the same, then they are the same type.Then they are equal types.The question was *when* are they same, not how you name them.void function(int) is the same as void function(int) and both are equal void function(int=2) is not the same as void function(int=3), but both are equal.The schizophrenic behavior occurs because the types cross-talk. Are mangled names kept unique in the compiler or what is the implementation issue exactly?It's a conceptual issue. When is one type the same as another, and when is it not?
Apr 26 2012
On 04/26/2012 11:54 AM, Don Clugston wrote:On 26/04/12 11:21, Timon Gehr wrote:I think I have answered that. Anyway, probably it is indeed a good idea to get rid of default parameters for delegates and function pointers. The issues are certainly resolvable but the complexity of the resulting feature could not be justified.On 04/26/2012 09:54 AM, Walter Bright wrote:The language doesn't have the concepts of "same" and "equal" with respect to types. There is "equal" and "implicitly converts to", but that's not quite the same.On 4/26/2012 12:47 AM, Timon Gehr wrote:This is a matter of terminology. For example, for 'equal' just exclude the default parameters from the comparison. For 'the same' include default parameters in the comparison. (therefore, 'the same' implies 'equal')On 04/26/2012 05:44 AM, Walter Bright wrote:This is simply not tenable. What defines when they are "equal" types and when they are "not equal"?A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both,That is how it should be.which leads to the nasty behavior in the bug report.It contributes, but it is not the main cause.The problem centers around name mangling. If two types mangle the same, then they are the same type.Then they are equal types.The question was *when* are they same, not how you name them.void function(int) is the same as void function(int) and both are equal void function(int=2) is not the same as void function(int=3), but both are equal.The schizophrenic behavior occurs because the types cross-talk. Are mangled names kept unique in the compiler or what is the implementation issue exactly?It's a conceptual issue. When is one type the same as another, and when is it not?
Apr 26 2012
On 4/26/2012 2:21 AM, Timon Gehr wrote:This is a matter of terminology. For example, for 'equal' just exclude the default parameters from the comparison. For 'the same' include default parameters in the comparison. (therefore, 'the same' implies 'equal')I think this is torturing the semantics.The result of ?: is the type of the two arguments if they are the same, and it is the equal type without default arguments if they are not the same.That's the problem - the selection of arbitrary rules.
Apr 26 2012
On 04/26/2012 08:56 PM, Walter Bright wrote:On 4/26/2012 2:21 AM, Timon Gehr wrote:It is not entirely arbitrary. Anyway, point taken.This is a matter of terminology. For example, for 'equal' just exclude the default parameters from the comparison. For 'the same' include default parameters in the comparison. (therefore, 'the same' implies 'equal')I think this is torturing the semantics.The result of ?: is the type of the two arguments if they are the same, and it is the equal type without default arguments if they are not the same.That's the problem - the selection of arbitrary rules.
Apr 26 2012
On 26/04/12 05:44, Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I think it is a mistake to allow default arguments in function pointers and delegates (it's OK for delegate literals, there you have the declaration). I don't see how it can possibly work. If it's really a type, then given: void foo(int x = 2) {} void bar(int y = 3) {} then typeof(&foo) should be: void function (int __param0 = 2) I don't see how we could justify having those types and not using them. But then, if you have: auto p = &foo; // p has default parameter of 2 p = &bar; // Should this work? I really don't think we want this. As I vaguely remember someone saying about the bug report, it looks like an attempt to have a pathetic special case of currying syntax sugar built into the language. But it isn't even as efficient as a library solution (if the construction of the default parameter is expensive, it will generate gobs of code every time the function parameter is called).
Apr 26 2012
On 04/26/2012 10:51 AM, Don Clugston wrote:On 26/04/12 05:44, Walter Bright wrote:The parenthesised part is in conflict with your other statement.A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I think it is a mistake to allow default arguments in function pointers and delegates (it's OK for delegate literals, there you have the declaration).I don't see how it can possibly work. If it's really a type, then given: void foo(int x = 2) {} void bar(int y = 3) {} then typeof(&foo) should be: void function (int __param0 = 2) I don't see how we could justify having those types and not using them. But then, if you have: auto p = &foo; // p has default parameter of 2 p = &bar; // Should this work? I really don't think we want this.We probably don't.As I vaguely remember someone saying about the bug report, it looks like an attempt to have a pathetic special case of currying syntax sugar built into the language.I don't see how it relates to currying.But it isn't even as efficient as a library solution (if the construction of the default parameter is expensive, it will generate gobs of code every time the function parameter is called).
Apr 26 2012
On 26/04/12 11:28, Timon Gehr wrote:On 04/26/2012 10:51 AM, Don Clugston wrote:No it doesn't. A default argument is a delegate literal is part of the declaration, not part of the type.On 26/04/12 05:44, Walter Bright wrote:The parenthesised part is in conflict with your other statement.A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I think it is a mistake to allow default arguments in function pointers and delegates (it's OK for delegate literals, there you have the declaration).
Apr 26 2012
On 04/26/2012 11:46 AM, Don Clugston wrote:On 26/04/12 11:28, Timon Gehr wrote:If types cannot specify default arguments, then those will be thrown away right away, because what is later called is based on the type of the delegate and not on the implicit function declaration that has its address taken. What is the point of allowing it if it cannot be used?On 04/26/2012 10:51 AM, Don Clugston wrote:No it doesn't. A default argument is a delegate literal is part of the declaration, not part of the type.On 26/04/12 05:44, Walter Bright wrote:The parenthesised part is in conflict with your other statement.A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I think it is a mistake to allow default arguments in function pointers and delegates (it's OK for delegate literals, there you have the declaration).
Apr 26 2012
On 26/04/12 12:11, Timon Gehr wrote:On 04/26/2012 11:46 AM, Don Clugston wrote:Fair point. It could be used in the case where it is called at the point of declaration (I do that a fair bit), but it's pretty much useless because it is clearer code to put the default parameter in the call. int m = (int a, int b = 3){ return a+b;}(7); Point conceded. So default arguments should be disallowed in delegate literals as well.On 26/04/12 11:28, Timon Gehr wrote:If types cannot specify default arguments, then those will be thrown away right away, because what is later called is based on the type of the delegate and not on the implicit function declaration that has its address taken. What is the point of allowing it if it cannot be used?On 04/26/2012 10:51 AM, Don Clugston wrote:No it doesn't. A default argument is a delegate literal is part of the declaration, not part of the type.On 26/04/12 05:44, Walter Bright wrote:The parenthesised part is in conflict with your other statement.A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I think it is a mistake to allow default arguments in function pointers and delegates (it's OK for delegate literals, there you have the declaration).
Apr 26 2012
On 2012-04-26 05:44, Walter Bright wrote:But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)Why not? -- /Jacob Carlborg
Apr 26 2012
On 4/26/2012 1:54 AM, Jacob Carlborg wrote:On 2012-04-26 05:44, Walter Bright wrote:Because a function pointer, and delegate, can exist without a corresponding declaration.But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)Why not?
Apr 26 2012
I've always thought of default arguments to be plain syntactic sugar, so for void f(int i, int j=5) f(1) is simply transformed to f(1,5) and the rest is the same.
Apr 26 2012
On 2012-04-26 03:44:07 +0000, Walter Bright <newshound2 digitalmars.com> said:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)Assuming we want to allow it, all you need is to treat the type having the default parameters as a specialization of the type that has none. In other words, the type with the default arugments is implicitly castable to the type without. Should it affect name mangling? Yes and not. It should affect name mangling in the compiler since you're using the mangled name to check for equality between types. But I think it should not affect name mangling for the generated code: the base type without the default arguments should give its name to the emitted symbols so that changing the default argument does not change the ABI. But is it desirable? I'm not convinced. I don't really see the point. It looks like a poor substitute for overloading to me. That said, there was some talk about adding support for named parameters a year ago. For named parameters, I think it'd make sense to have parameter names be part of the type, and little harm would result in adding default parameters too into the mix. As suggested above, it should be implicitly castable to a base type without parameter names or default values. But for default parameters alone, I don't feel the complication is justified. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 26 2012
Michel Fortin:That said, there was some talk about adding support for named parameters a year ago.Good reminder. I think such parts of D shouldn't be designed one of a time. If you want to face the problem of default arguments, it's better to think about named arguments too (even if you don't want to implement them now, to not preclude their good future implementation). Bye, bearophile
Apr 26 2012
Le 26/04/2012 05:44, Walter Bright a écrit :A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)Maybe the problem is that type are considered to be the same when the mangling is the same. The default parameter is part of the type, isn't mangled (or hell will come on earth) and is covariant with the type with no default.
Apr 26 2012
Walter:A subtle but nasty problem - are default arguments part of the type, or part of the declaration?I'm waiting for years to see you finally facing this problem too :-) The current situation is not acceptable, so some change of the current situation is required, probably a small breaking change. The simplest solution is to the breaking change of disallowing default arguments for function pointers and delegates. This also means disallowing talking the pointer/delegate of function with default arguments. The advantage of this solution is its simplicity, for both the compiler the D programmer and the D newbie that has to learn D. A second alternative solution is to put the default arguments inside the function mangled and, and to avoid troubles, allow this only for POD data known at compile-time (and throw a compile-time error in all other cases). This has the advantage that common default arguments like "true", 15, 2.5, are accepted, so this gives some flexibility. One disadvantage is that you need to add a special case to D, but it's not a nasty special case, it's a clean thing. A third possible way is to put the default arguments inside the delegate/function itself, as in Python. So default arguments for delegates/function have a different semantics. Then add a hidden extra field to such delegates/functions, a ubyte that tells the function how many arguments are actually given to the function (so the function is later able to use this argument to know how many arguments replace with the default ones). This has some disadvantages, because you can retrofit already compiled modules, so you can't get the function pointer of a function that doesn't have this hidden argument. The advantage is that the semantics is clean, and it's quite flexible. Bye, bearophile
Apr 26 2012
On Thursday, April 26, 2012 13:54:47 bearophile wrote:The simplest solution is to the breaking change of disallowing default arguments for function pointers and delegates. This also means disallowing talking the pointer/delegate of function with default arguments.No it doesn't. You could definitely have a pointer to function with default arguments. It's just that the pointer doesn't use the default arguments at all. The default arguments get inserted at the call site if you explicitly call a function and don't pass arguments for those parameters. The function's signature is unaffected by the presence of default arguments, so the pointer should be unaffected. What should be disallowed is giving default arguments to function pointers and delegate literals. So, stuff like void main() { int foo(int a = 1) { return a; } } should work just fine. The default argument will only get used if foo is called directly. However, stuff like void main() { auto foo = (int a = 1) { return a;}; } wouldn't work, because you can't call the function except through its pointer. As you can never call the function directly, its default argument would never be used, and there would be no point to having it. - Jonathan M Davis
Apr 26 2012
On Wed, 25 Apr 2012 23:44:07 -0400, Walter Bright <newshound2 digitalmars.com> wrote:A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)Some testing (2.059): void main() { auto a = (int x = 1) { return x;}; auto b = (int x) { return x;}; pragma(msg, typeof(a).stringof); pragma(msg, typeof(b).stringof); } output: int function(int x = 1) pure nothrow safe int function(int x = 1) pure nothrow safe second pass: void main() { auto a = (int x = 1) { return x;}; pure nothrow safe int function(int) b = (int x) { return x;}; pragma(msg, typeof(a).stringof); pragma(msg, typeof(b).stringof); b = a; // ok //a = b; // error //b(); // error } output: int function(int x = 1) pure nothrow safe int function(int) if you ask me, everything looks exactly as I'd expect, except the auto type inference of b. Can this not be fixed? I don't understand the difficulty. BTW, I didn't know you could have default arguments for functions/delegates, it's pretty neat :) -Steve
Apr 26 2012
On Thu, 26 Apr 2012 09:08:07 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:void main() { auto a = (int x = 1) { return x;}; pure nothrow safe int function(int) b = (int x) { return x;}; pragma(msg, typeof(a).stringof); pragma(msg, typeof(b).stringof); b = a; // ok //a = b; // error //b(); // error } output: int function(int x = 1) pure nothrow safe int function(int)Nevermind, I just realized it was ignoring my pure nothrow safe for the declaration. Moving it after the declaration results in: void main() { auto a = (int x = 1) { return x;}; int function(int) pure nothrow safe b = (int x) { return x;}; pragma(msg, typeof(a).stringof); pragma(msg, typeof(b).stringof); } output: int function(int x = 1) pure nothrow safe int function(int x = 1) pure nothrow safe which clearly mimics the auto behavior. This is *really* no good, since it seems to be ignoring the explicit type that I specified. IMO, the correct solution is to make the default argument part of the type (and don't let it affect things globally!), and make it derived from the version without a default arg. I think Michel Fortin said the same thing. -Steve
Apr 26 2012
On 26/04/12 05:44, Walter Bright wrote:But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I can't see disallowing default arguments as being a good thing. For example, instead of, void foo(int a, int b = 2) { ... } surely I can just put instead void foo(int a, int b) { ... } void foo(int a) { foo(a, 2); } ... and surely I can do something similar for function pointers and delegates. So, I can still have default arguments in effect, I just have to work more as a programmer, using a less friendly and easy-to-understand syntax. That doesn't really seem like a good way to operate unless there's an extreme level of complication in getting the compiler to handle the situation.
Apr 26 2012
"Walter Bright" <newshound2 digitalmars.com> wrote in message news:jnagar$2d8k$1 digitalmars.com...A subtle but nasty problem - are default arguments part of the type, or part of the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same, then they are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)From what I remember, function pointer parameter names have similar problems. It never made any sense to me to have default parameters or parameter names as part of the type.
Apr 26 2012
On Thursday, April 26, 2012 15:09:15 Joseph Rushton Wakeling wrote:On 26/04/12 05:44, Walter Bright wrote:There is an _enormous_ difference between disallowing default arguments in general and disallowing them in function pointers and delegates. Think about how function pointers and delegates get used. They're almost always called generically. Something gets passed a function pointer or delegate and argument and calls it. The caller isn't going to care about default arguments. It expects a specific signature and passes those specific arguments to the function/delegate when it calls it. It's not going to be calling it with 2 arguments in one case and 3 in another. No default arguments are involved with function pointers in C/C++, and I've never heard of anyone complain about it there. Default arguments are great when you're going to be calling a function in a variety of places, and you want defaults for some parameters in cases where they're almost always a particular value so that you don't have to always type them. But function pointers and delegates are generally called in _one_ way, if not in one place, so their usage is _very_ different. - Jonathan M DavisBut if we make default arguments solely a part of the function declaration, then function pointers (and delegates) cannot have default arguments. (And maybe this isn't a bad thing?)I can't see disallowing default arguments as being a good thing. For example, instead of, void foo(int a, int b = 2) { ... } surely I can just put instead void foo(int a, int b) { ... } void foo(int a) { foo(a, 2); } ... and surely I can do something similar for function pointers and delegates. So, I can still have default arguments in effect, I just have to work more as a programmer, using a less friendly and easy-to-understand syntax. That doesn't really seem like a good way to operate unless there's an extreme level of complication in getting the compiler to handle the situation.
Apr 26 2012
On 26/04/12 19:25, Jonathan M Davis wrote:There is an _enormous_ difference between disallowing default arguments in general and disallowing them in function pointers and delegates.I think maybe I've misunderstood the problem. Are we talking about default values _of the function pointer_ or that get passed to the function pointer? i.e. are we talking about, int foo(int delegate() dg = &bar) { ... } or about int foo(int delegate() dg = &bar) { bar(); // assumes default arguments for bar } ...?
Apr 26 2012
On Thursday, April 26, 2012 19:45:55 Joseph Rushton Wakeling wrote:On 26/04/12 19:25, Jonathan M Davis wrote:The second. If you have int foo(int a = 1) { return a + 3; } and you call foo directly without any arguments, then the default argument would be inserted. The problem is when you have a pointer to foo. Should calls to the pointer use a default argument or not? To do that, they need to be part of the type of the function pointer (or delegate). Personally, I think that it's a very clear and resounding _no_. Default arguments are merely syntactic sugar (albeit very useful syntactic sugar) and should _not_ affect the type of a function pointer or delegate. A function pointer shouldn't care about whatever default arguments its function might have, and a pointer to the foo above should have the same type as a pointer to int bar(int a) { return a - 2; } As such, code like auto foo = (int a = 1) { return a;}; should probably be illegal, since the default argument could never be used. Right now, we get very weird behavior due to an attempt to make such things work. And I think that it's pretty clear that that was a mistake (though obviously this discussion is to gauge what the group as a whole think and debate it if necessary). - Jonathan M DavisThere is an _enormous_ difference between disallowing default arguments in general and disallowing them in function pointers and delegates.I think maybe I've misunderstood the problem. Are we talking about default values _of the function pointer_ or that get passed to the function pointer? i.e. are we talking about, int foo(int delegate() dg = &bar) { ... } or about int foo(int delegate() dg = &bar) { bar(); // assumes default arguments for bar }
Apr 26 2012
I've actually been making fairly extensive use of function/delegate default args. I was pleasantly surprised when I realised it was possible. Funnily enough, It's one of those things that I just expected should work (as I find most things I just expect should work do in fact tend to work in D), so it seems it was intuitive too at some level. It would be a shame to see it go, but I wouldn't say it's critical, just very handy. In my case, used in shared interface bindings. Occurs more often than not in some interfaces. On 26 April 2012 07:00, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Wednesday, April 25, 2012 20:44:07 Walter Bright wrote:A subtle but nasty problem - are default arguments part of the type, orpartof the declaration? See http://d.puremagic.com/issues/show_bug.cgi?id=3866 Currently, they are both, which leads to the nasty behavior in the bug report. The problem centers around name mangling. If two types mangle the same,thenthey are the same type. But default arguments are not part of the mangled string. Hence the schizophrenic behavior. But if we make default arguments solely a part of the functiondeclaration,then function pointers (and delegates) cannot have default arguments.(Andmaybe this isn't a bad thing?)Can function pointers have default arguments in C? Honestly, it strikes me as rather bizarre for them to have default arguments. I really don't think that they buy you much. If you use the function or delegate immediately after declaring it (as is typically the case when they're nested), then you could have just just put the default argument in the function itself and not have it as a parameter. And if you're holding on to a function or delegate long term, you're almost certainly going to be using it generically, in which case I wouldn't expect a default argument to make sense there often either. I'd vote to just disallow default arguments for function pointers and delegates. - Jonathan M Davis
Apr 26 2012