digitalmars.D - Passing function parameters by name
- Artyom Shalkhakov (12/12) Dec 04 2007 Hello everyone.
- bearophile (13/14) Dec 04 2007 Python uses =
- David Wilson (21/35) Dec 04 2007 This one is pretty close to my heart too, but I can't quite decide
- Artyom Shalkhakov (3/58) Dec 04 2007 I'm not into getting D so close to Python... I think that the default-pa...
- Bill Baxter (24/82) Dec 04 2007 I think for any keyword argument proposal to fly, it's going to need to
- Robert Fraser (4/5) Dec 04 2007 The call is bound at compile-time, so there's no runtime cost
- bearophile (4/5) Dec 04 2007 I can't understand how you can fully solve that problem I have shown at ...
- Kirk McDonald (14/23) Dec 04 2007 Function pointers don't know anything about default parameters. That is,...
- bearophile (4/6) Dec 04 2007 I was talking about adding things to D. So it can solve the kind of prob...
- downs (4/15) Dec 04 2007 Multiple parameters can be handled with some templates and static ifs as...
- Robert Fraser (3/25) Dec 04 2007 Doing that for every function would be ugly & error-prone, though (even
- Don Clugston (13/31) Dec 05 2007 (Genuine question, not a flame):
- bearophile (4/5) Dec 05 2007 They are quite handy and useful when used wisely, but they require care,...
- renoX (7/39) Dec 05 2007 I could ask the opposite question: why should we restrict the API to the...
- Don Clugston (17/56) Dec 05 2007 Because it's simpler, and there's an enormous body of code (C, C++ for e...
- bearophile (4/6) Dec 05 2007 I think D (and some dynamic languages too) have demonstrated that there ...
- guslay (3/5) Dec 05 2007 GC seems to have been pushed after c++0x.
- guslay (3/5) Dec 05 2007 GC seems to have been pushed after c++0x.
- bearophile (4/6) Dec 05 2007 I see, thank you for the link. They are adding features to allow a simpl...
- renoX (5/18) Dec 05 2007 "better" only if D's GC is considered reliable enough for "serious"
- renoX (13/45) Dec 05 2007 Uh? Why would renaming the parameters of a function happen more
- Janice Caron (19/31) Dec 05 2007 I often write constructor functions which look something like this
- Bill Baxter (5/33) Dec 05 2007 That's why any named parameter proposal is going to have to flag the
- Leandro Lucarella (11/36) Dec 06 2007 I don't see what's the big problem with named parameters being part of t...
- Bill Baxter (12/41) Dec 06 2007 In Python you cannot overload functions based on argument types.
- bearophile (5/8) Dec 06 2007 I presume a simpler semantics is enough for D; the * and ** semantic of ...
- renoX (16/65) Dec 06 2007 Would have?
- Janice Caron (2/3) Dec 05 2007 And not just constructors, by the way - any "setter" property function
- Janice Caron (27/28) Dec 06 2007 Another thought. If the name were part of the API then could one
- Bill Baxter (6/46) Dec 06 2007 Gee that's so clean! Not.
- Bruce Adams (41/78) Dec 06 2007 =
Hello everyone. I suggest adding a new syntax for function parameter passing. To illustrate: void foo( int a, float b ) { // some code } void main() { foo( 1, 2.5f ); // classic foo( b : 2.5f, a : -3 ); // sort of struct initializer } Since named arguments can be passed in any order, they can be especially useful when a function has more than one parameter with a default value. This concept could be applied to template instantiation as well. -Artyom Shalkhakov
Dec 04 2007
Artyom Shalkhakov:foo( b : 2.5f, a : -3 ); // sort of struct initializerPython uses = foo(b=2.5f, a=-3); This is a very useful feature, I use it often in Python. But if you try to translate this Python code: from sys import argv def a(c="A"): print c def b(c="B"): print c l = [a, b] if argv[1] == "1": l.reverse() l[1]() to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me). Bye, bearophile
Dec 04 2007
On 12/4/07, bearophile <bearophileHUGS lycos.com> wrote:Artyom Shalkhakov:This one is pretty close to my heart too, but I can't quite decide what the resulting feature would look like in D. I made an effort to port Python's awesome ElementTree XML library to D, but found most of its convenient syntax was lost because D doesn't support named arguments. A further twist to this is Python's ability to take arbitrary named arguments and build an associative array from them ("dict"). Implementing this feature would probably mean tight integration with AA literal syntax for uniformity's sake, but I couldn't come up with a syntax worth proposing. Desirable: - Ability to specify non-default parameters after default parameters. - Ability to lazy-build an associative array argument to a function, without using AA literal syntax. Rough idea: void foo(int a, bool b = true, bool c = false, char[][char[]] args); foo(0xcafebabe, c: true, strangeArg: "hello", otherArg: "world"); Except I'm sure there's a plethora of things I've forgotten about (interactions with templates for example?) David.foo( b : 2.5f, a : -3 ); // sort of struct initializerPython uses = foo(b=2.5f, a=-3); This is a very useful feature, I use it often in Python. But if you try to translate this Python code: from sys import argv def a(c="A"): print c def b(c="B"): print c l = [a, b] if argv[1] == "1": l.reverse() l[1]() to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).Bye, bearophile
Dec 04 2007
David Wilson Wrote:On 12/4/07, bearophile <bearophileHUGS lycos.com> wrote:I'm not into getting D so close to Python... I think that the default-parameter-values should remain as-is, with the added ability to address parameters by their name. I suggest looking at D's struct initializers. (Make the process of initializing an array and calling a function more 'uniform'.)Artyom Shalkhakov:This one is pretty close to my heart too, but I can't quite decide what the resulting feature would look like in D. I made an effort to port Python's awesome ElementTree XML library to D, but found most of its convenient syntax was lost because D doesn't support named arguments. A further twist to this is Python's ability to take arbitrary named arguments and build an associative array from them ("dict"). Implementing this feature would probably mean tight integration with AA literal syntax for uniformity's sake, but I couldn't come up with a syntax worth proposing. Desirable: - Ability to specify non-default parameters after default parameters. - Ability to lazy-build an associative array argument to a function, without using AA literal syntax. Rough idea: void foo(int a, bool b = true, bool c = false, char[][char[]] args); foo(0xcafebabe, c: true, strangeArg: "hello", otherArg: "world"); Except I'm sure there's a plethora of things I've forgotten about (interactions with templates for example?) David.foo( b : 2.5f, a : -3 ); // sort of struct initializerPython uses = foo(b=2.5f, a=-3); This is a very useful feature, I use it often in Python. But if you try to translate this Python code: from sys import argv def a(c="A"): print c def b(c="B"): print c l = [a, b] if argv[1] == "1": l.reverse() l[1]() to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).Bye, bearophile
Dec 04 2007
Artyom Shalkhakov wrote:David Wilson Wrote:I think for any keyword argument proposal to fly, it's going to need to specially mark the keyword args. D's parameter declaration syntax is tied very closely to that of C/C++ and changing that wholesale will break tons of D code and probably make interfacing with C code a confusing mess. In C/C++/D You can declare prototypes using different parameter names from the actual implementation, or with no names at all. This is behavior that is relied upon in many places. However, if the keyword arguments were differentiated from the regular arguments, it might be workable. Lisp uses some kind of token like "&keyword" to separate keyword arguments from others. When calling, the keyword for a keyword arg must always be specified. That sort of things seems like it might be doable in a backwards-compatible way. So something like: void myFunc(int x, &&, float key1=10, float key2=20); ... myFunc(3, key2:10); I think the problem with any keyword arg proposal at this point is that the cost/benefit ratio is low. Thoroughly specing it out and implementing it will be difficult, but the benefit will not be that great. It just adds a little extra convenience. Fixing template overload issues, for instance, would be a much bigger win. Or implementing real reference types. Or Tuples as return values. --bbOn 12/4/07, bearophile <bearophileHUGS lycos.com> wrote:I'm not into getting D so close to Python... I think that the default-parameter-values should remain as-is, with the added ability to address parameters by their name. I suggest looking at D's struct initializers. (Make the process of initializing an array and calling a function more 'uniform'.)Artyom Shalkhakov:This one is pretty close to my heart too, but I can't quite decide what the resulting feature would look like in D. I made an effort to port Python's awesome ElementTree XML library to D, but found most of its convenient syntax was lost because D doesn't support named arguments. A further twist to this is Python's ability to take arbitrary named arguments and build an associative array from them ("dict"). Implementing this feature would probably mean tight integration with AA literal syntax for uniformity's sake, but I couldn't come up with a syntax worth proposing. Desirable: - Ability to specify non-default parameters after default parameters. - Ability to lazy-build an associative array argument to a function, without using AA literal syntax. Rough idea: void foo(int a, bool b = true, bool c = false, char[][char[]] args); foo(0xcafebabe, c: true, strangeArg: "hello", otherArg: "world"); Except I'm sure there's a plethora of things I've forgotten about (interactions with templates for example?) David.foo( b : 2.5f, a : -3 ); // sort of struct initializerPython uses = foo(b=2.5f, a=-3); This is a very useful feature, I use it often in Python. But if you try to translate this Python code: from sys import argv def a(c="A"): print c def b(c="B"): print c l = [a, b] if argv[1] == "1": l.reverse() l[1]() to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).Bye, bearophile
Dec 04 2007
bearophile wrote:to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).The call is bound at compile-time, so there's no runtime cost associated. The default parameters are passed in explicitly for the parameters that the user doesn't supply.
Dec 04 2007
Robert Fraser:The call is bound at compile-time,I can't understand how you can fully solve that problem I have shown at compile time. A function pointer can be managed at runtime, so at runtime you can choose to give or to not give the default parameter... Bye, bearophile
Dec 04 2007
bearophile wrote:Robert Fraser:Function pointers don't know anything about default parameters. That is, the following does not work: void foo(int i=20) {} void main() { void function() fn = &foo; // Error: typeof(&foo) is // void function(int) fn(); } -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.orgThe call is bound at compile-time,I can't understand how you can fully solve that problem I have shown at compile time. A function pointer can be managed at runtime, so at runtime you can choose to give or to not give the default parameter... Bye, bearophile
Dec 04 2007
Kirk McDonald Wrote:Function pointers don't know anything about default parameters. That is, the following does not work:I was talking about adding things to D. So it can solve the kind of problem I have shown in my first post. I am talking about possible enhancements... Bye, bearophile
Dec 04 2007
You can "sort-of" do function parameters by name by turning the function into a template, and using some typedefs. Completely untested example:typedef int _Foo; _Foo Foo(int e) { return cast(_Foo) e; } typedef int _Bar; _Bar Bar(int e) { return cast(_Bar) e; } void test(T)(T t) { static if (is(T==_Bar)) writefln("Got bar: ", t); static if (is(T==_Foo)) writefln("Got foo: ", t); } void main() { test(Foo=4); test(Bar=17); }Multiple parameters can be handled with some templates and static ifs as well. :) --downs
Dec 04 2007
downs wrote:You can "sort-of" do function parameters by name by turning the function into a template, and using some typedefs. Completely untested example:Doing that for every function would be ugly & error-prone, though (even with the magic of nested templates/tuples/mixins).typedef int _Foo; _Foo Foo(int e) { return cast(_Foo) e; } typedef int _Bar; _Bar Bar(int e) { return cast(_Bar) e; } void test(T)(T t) { static if (is(T==_Bar)) writefln("Got bar: ", t); static if (is(T==_Foo)) writefln("Got foo: ", t); } void main() { test(Foo=4); test(Bar=17); }Multiple parameters can be handled with some templates and static ifs as well. :) --downs
Dec 04 2007
Artyom Shalkhakov wrote:Hello everyone. I suggest adding a new syntax for function parameter passing. To illustrate: void foo( int a, float b ) { // some code } void main() { foo( 1, 2.5f ); // classic foo( b : 2.5f, a : -3 ); // sort of struct initializer } Since named arguments can be passed in any order, they can be especially useful when a function has more than one parameter with a default value. This concept could be applied to template instantiation as well. -Artyom Shalkhakov(Genuine question, not a flame): To play devil's advocate for a moment: doesn't a long parameter list or lots of default arguments indicate a poor design? Essentially, the name of the argument becomes part of the API. Why isn't function and object name good enough? Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived. (OTOH: A string mixin can, given the name of a function, tell you what the names of all of it's default arguments are (as well as what their default values are). I can in fact write a string mixin implementation of this feature; it's perfectly feasible. But is the concept actually a good idea?)
Dec 05 2007
Don Clugston:Named arguments are potentially a disastrous feature, if completely unrestricted.They are quite handy and useful when used wisely, but they require care, you don't have to use them too much otherwise you risk doing a mess (this is true for many things in Python. Python is supposed to be a language for almost-newbies, but it contains many things that must be used with discipline, to avoid creating a tangled mess instead of a program. In that regard I think Ruby is even worse than Python. I think Java helps you keep the program tidy and clean even if you have less self-discipline, because it has more built-in 'bondage', almost as Ada. At the moment D seems between Python and Java in that regard. Often the bigger the log10(line_count) is, the higher the discipline you need to write the program with, imposed by the language or self-imposed. D's macros will make D a more flexible too, but sharper and more dangerous too, so will need more self-discipline to use it. Something similar is true in Lisp too. Scheme has more hygenic macros to give some restraints to the semantic and decrease bugs). Bye, bearophile
Dec 05 2007
Don Clugston Wrote:Artyom Shalkhakov wrote:A long list of parameter is not needed in order to have parameter passing par name useful: some compilers have added specific checks for memset (only 3 arguments) because quite a few people made an error in the order of parameters..Hello everyone. I suggest adding a new syntax for function parameter passing. To illustrate: void foo( int a, float b ) { // some code } void main() { foo( 1, 2.5f ); // classic foo( b : 2.5f, a : -3 ); // sort of struct initializer } Since named arguments can be passed in any order, they can be especially useful when a function has more than one parameter with a default value. This concept could be applied to template instantiation as well. -Artyom Shalkhakov(Genuine question, not a flame): To play devil's advocate for a moment: doesn't a long parameter list or lots of default arguments indicate a poor design?Essentially, the name of the argument becomes part of the API. Why isn't function and object name good enough?I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have? To answer your question: passing parameter by name increase the readability of the source, reduce the number of mistake when writing the code (and with a good IDE the number of character to type would be the same).Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived.Could you explain this point? (I know nothing about COM).(OTOH: A string mixin can, given the name of a function, tell you what the names of all of it's default arguments are (as well as what their default values are). I can in fact write a string mixin implementation of this feature; it's perfectly feasible. But is the concept actually a good idea?)Note that passing parameter by name is only useful if programmers doesn't have to jump through hoops to do it, otherwise nobody will use it. renoX
Dec 05 2007
renoX wrote:Don Clugston Wrote:Artyom Shalkhakov wrote:A long list of parameter is not needed in order to have parameter passing par name useful: some compilers have added specific checks for memset (only 3 arguments) because quite a few people made an error in the order of parameters..Hello everyone. I suggest adding a new syntax for function parameter passing. To illustrate: void foo( int a, float b ) { // some code } void main() { foo( 1, 2.5f ); // classic foo( b : 2.5f, a : -3 ); // sort of struct initializer } Since named arguments can be passed in any order, they can be especially useful when a function has more than one parameter with a default value. This concept could be applied to template instantiation as well. -Artyom Shalkhakov(Genuine question, not a flame): To play devil's advocate for a moment: doesn't a long parameter list or lots of default arguments indicate a poor design?Because it's simpler, and there's an enormous body of code (C, C++ for example) which demonstrates a language can get by perfectly well without it; Is the extra cost worth the benefit?Essentially, the name of the argument becomes part of the API. Why isn't function and object name good enough?I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?To answer your question: passing parameter by name increase the readability of the source, reduce the number of mistake when writing the code (and with a good IDE the number of character to type would be the same).But it also means that if you change the name of a parameter in a library, user code will break. Certainly, you'd need some special syntax to specify which parameters are part of the API, otherwise you get horribly brittle code. Overload lookup rules could become complicated.<flame> VB allows you to call a C++ COM object by giving a list of argument names (as a text array, with whatever stupid VB formats are possible) together with the argument values as VB Variants. Languages like C++ were supposed to support any combination the VB programmer chose to use. A massive complication of COM code, just to support sloppy practice by VB programmers, and even then it was only necessary because the VB interpreter was too lazy to put the parameters in the right order. </flame>Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived.Could you explain this point? (I know nothing about COM).
Dec 05 2007
Don Clugston:Because it's simpler, and there's an enormous body of code (C, C++ for example) which demonstrates a language can get by perfectly well without it;I think D (and some dynamic languages too) have demonstrated that there are many things C/C++ lack! (but associative arrays and GC will go into C++0x anyway...) Bye, bearophile
Dec 05 2007
bearophile Wrote:I think D (and some dynamic languages too) have demonstrated that there are many things C/C++ lack! (but associative arrays and GC will go into C++0x anyway...)GC seems to have been pushed after c++0x. http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!330.entry
Dec 05 2007
bearophile Wrote:I think D (and some dynamic languages too) have demonstrated that there are many things C/C++ lack! (but associative arrays and GC will go into C++0x anyway...)GC seems to have been pushed after c++0x. http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!330.entry
Dec 05 2007
guslay:GC seems to have been pushed after c++0x. http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!330.entryI see, thank you for the link. They are adding features to allow a simpler support of an external GC instead. I think this will keep D "better" for some more time then :-) (I have used quotes because often you can't tell langage X is better than Y because they are better regarding specific purposes). Bye, bearophile
Dec 05 2007
bearophile a écrit :guslay:"better" only if D's GC is considered reliable enough for "serious" projects which is debatable currently: having memory leaks in some case due to the GC isn't acceptable IMHO. renoXGC seems to have been pushed after c++0x. http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!330.entryI see, thank you for the link. They are adding features to allow a simpler support of an external GC instead. I think this will keep D "better" for some more time then :-)(I have used quotes because often you can't tell langage X is better than Y because they are better regarding specific purposes). Bye, bearophile
Dec 05 2007
With hacks in the compiler such as the special case for memset I talked about, I don't think that it works 'perfectly well'.I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?Because it's simpler, and there's an enormous body of code (C, C++ for example) which demonstrates a language can get by perfectly well without it;Is the extra cost worth the benefit?Uh? Why would renaming the parameters of a function happen more frequently than say renaming a function?To answer your question: passing parameter by name increase the readability of the source, reduce the number of mistake when writing the code (and with a good IDE the number of character to type would be the same).But it also means that if you change the name of a parameter in a library, user code will break. Certainly, you'd need some special syntax to specify which parameters are part of the API, otherwise you get horribly brittle code.Overload lookup rules could become complicated.If two function overloaded function have a different set of parameters name, then if you call a function passing a parameter by name then, then either it's a 'common' name and the normal overload rules apply either it's a name which appears in only one function so it's not an overload anymore (if you have two parameters specific to two different function, it's an error) ..Interesting. Regards, renoX<flame> VB allows you to call a C++ COM object by giving a list of argument names (as a text array, with whatever stupid VB formats are possible) together with the argument values as VB Variants. Languages like C++ were supposed to support any combination the VB programmer chose to use. A massive complication of COM code, just to support sloppy practice by VB programmers, and even then it was only necessary because the VB interpreter was too lazy to put the parameters in the right order. </flame>Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived.Could you explain this point? (I know nothing about COM).
Dec 05 2007
On Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?I often write constructor functions which look something like this this(int x_, int y_, int z_) { x = x_; y = y_; z = z_; } If parameter names were part of the API, then anyone calling my code would have to refer to those constructor parameters as x_, y_ and z_, complete with trailing underscores Of course, I could go back and change all my code to this(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } but that would be a lot of code to change, and it might break calling code!To answer your question: passing parameter by name increase the readability of the source, reduce the number of mistake when writing the code (and with a good IDE the number of character to type would be the same).Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived.Could you explain this point? (I know nothing about COM).(OTOH: A string mixin can, given the name of a function, tell you what the names of all of it's default arguments are (as well as what their default values are). I can in fact write a string mixin implementation of this feature; it's perfectly feasible. But is the concept actually a good idea?)Note that passing parameter by name is only useful if programmers doesn't have to jump through hoops to do it, otherwise nobody will use it. renoX
Dec 05 2007
Janice Caron wrote:On Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:That's why any named parameter proposal is going to have to flag the named parameters somehow. Non-flagged parameters will continue to behave as always. --bbI could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?I often write constructor functions which look something like this this(int x_, int y_, int z_) { x = x_; y = y_; z = z_; } If parameter names were part of the API, then anyone calling my code would have to refer to those constructor parameters as x_, y_ and z_, complete with trailing underscores Of course, I could go back and change all my code to this(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } but that would be a lot of code to change, and it might break calling code!
Dec 05 2007
Bill Baxter, el 6 de diciembre a las 16:58 me escribiste:Janice Caron wrote:I don't see what's the big problem with named parameters being part of the API (when, by convention, you are told so). This is widely used on Python and works just great and it's damn useful. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- A can of diet coke will float in water While a can of regular coke will sinkOn Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:That's why any named parameter proposal is going to have to flag the named parameters somehow. Non-flagged parameters will continue to behave as always.I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?I often write constructor functions which look something like this this(int x_, int y_, int z_) { x = x_; y = y_; z = z_; } If parameter names were part of the API, then anyone calling my code would have to refer to those constructor parameters as x_, y_ and z_, complete with trailing underscores Of course, I could go back and change all my code to this(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } but that would be a lot of code to change, and it might break calling code!
Dec 06 2007
Leandro Lucarella wrote:Bill Baxter, el 6 de diciembre a las 16:58 me escribiste:In Python you cannot overload functions based on argument types. Keyword arguments help to fill the void that leaves. So C++ and D don't need keyword args quite as badly as Python. Also a D implementation probably would lack many of the features of Python's keyword args. I doubt you would be able to do things like passing an AA as a set of keyword arguments. I think in the end this is a feature that would be nice but A) probably needs to be designed as part of the language from the beginning. B) needs to be a pet peeve of the person writing the compiler. --bbJanice Caron wrote:I don't see what's the big problem with named parameters being part of the API (when, by convention, you are told so). This is widely used on Python and works just great and it's damn useful.On Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:That's why any named parameter proposal is going to have to flag the named parameters somehow. Non-flagged parameters will continue to behave as always.I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?I often write constructor functions which look something like this this(int x_, int y_, int z_) { x = x_; y = y_; z = z_; } If parameter names were part of the API, then anyone calling my code would have to refer to those constructor parameters as x_, y_ and z_, complete with trailing underscores Of course, I could go back and change all my code to this(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } but that would be a lot of code to change, and it might break calling code!
Dec 06 2007
Bill Baxter:Also a D implementation probably would lack many of the features of Python's keyword args. I doubt you would be able to do things like passing an AA as a set of keyword arguments.I presume a simpler semantics is enough for D; the * and ** semantic of parameter passing in Python 3.0 is probably a bit too much for D. (And in the future that Python syntax with ** may be implmented too in SkedSkin, that translates a subset of Python to C++. I think the main problem isn't implementing its workings, but managing types: probably those function arguments (those dict values) are all of different type. Python dicts have no problem because it's a dynamically typed language, but D's AA are statically typed. So you may need an AA of Box[string]. Note that IronPython runs on dotnet, that has statically typed AAs, so thy have solved similar problems). Bye, bearophile
Dec 06 2007
Janice Caron a écrit :On Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:Would have? No only could: nobody said that passing parameter by name should be mandatory. As for the rest, yes having the possibility to pass parameter by name would mean that programmers will try to find better name for the parameters, but that's a plus if you believe in literate programming..I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?I often write constructor functions which look something like this this(int x_, int y_, int z_) { x = x_; y = y_; z = z_; } If parameter names were part of the API, then anyone calling my code would have to refer to those constructor parameters as x_, y_ and z_, complete with trailing underscoresOf course, I could go back and change all my code to this(int x, int y, int z) { this.x = x; this.y = y; this.z = z; }I'm not sure that the trailing underscores would be that hurtful to the users.. Maybe such feature could be advertised 6 month before: "In 6 month, the name of your parameter will become visible to the users, please ensure that your parameters names are well-chosen."but that would be a lot of code to change, and it might break calling code!Somehow Python, Ada manage to have this feature without issue, I've seen plenty of rants against both language but *never* read complaints against Python or Ada "passing parameter by name" feature.. renoXTo answer your question: passing parameter by name increase the readability of the source, reduce the number of mistake when writing the code (and with a good IDE the number of character to type would be the same).Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived.Could you explain this point? (I know nothing about COM).(OTOH: A string mixin can, given the name of a function, tell you what the names of all of it's default arguments are (as well as what their default values are). I can in fact write a string mixin implementation of this feature; it's perfectly feasible. But is the concept actually a good idea?)Note that passing parameter by name is only useful if programmers doesn't have to jump through hoops to do it, otherwise nobody will use it. renoX
Dec 06 2007
I often write constructor functions which look something like thisAnd not just constructors, by the way - any "setter" property function is likely to apply the same convention.
Dec 05 2007
On Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?Another thought. If the name were part of the API then could one overload functions by parameter name? e.g. void f(int a) { /* do something */ } void f(int b) { /* do something different */ } After all, if the name were part of the API, then they have different APIs. I'm not convinced that this is a good idea. It's also not the only alternative. I have in the past written programs which take parameters of the same underlying type in any order, using only D-as-it-is-now (or C++), and it's not so hard. For example, suppose you want a function that looks like MyDate makeDate(int month, int day, int year) but you think callers might get confused about what order to pass the parameters in (European date order, American date order, YMD date order, whatever...) typedef int Year; typedef int Month; typedef int Day; MyDate makeDate(Year y; Month m, Day d) {/*...*/ } MyDate makeDate(Year y, Day d, Month m) { return MyDate(y,m,d); } MyDate makeDate(Day d, Month m, Year y) { return MyDate(y,m,d); } MyDate makeDate(Month m, Day d, Year y) { return MyDate(y,m,d); } That forces callers to name their arguments, as in: MyDate date = makeDate(cast(Day)11, cast(Month)11, cast(Year)1999); If you wanted, you could also add a "default" function that took ints but required parameters in the right order. And that, basically, is problem solved, as far as I can see.
Dec 06 2007
Janice Caron wrote:On Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:Gee that's so clean! Not. You've taken one simple function and turned it into 4 functions plus 3 extra types. It's a workaround at best. --bbI could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?Another thought. If the name were part of the API then could one overload functions by parameter name? e.g. void f(int a) { /* do something */ } void f(int b) { /* do something different */ } After all, if the name were part of the API, then they have different APIs. I'm not convinced that this is a good idea. It's also not the only alternative. I have in the past written programs which take parameters of the same underlying type in any order, using only D-as-it-is-now (or C++), and it's not so hard. For example, suppose you want a function that looks like MyDate makeDate(int month, int day, int year) but you think callers might get confused about what order to pass the parameters in (European date order, American date order, YMD date order, whatever...) typedef int Year; typedef int Month; typedef int Day; MyDate makeDate(Year y; Month m, Day d) {/*...*/ } MyDate makeDate(Year y, Day d, Month m) { return MyDate(y,m,d); } MyDate makeDate(Day d, Month m, Year y) { return MyDate(y,m,d); } MyDate makeDate(Month m, Day d, Year y) { return MyDate(y,m,d); } That forces callers to name their arguments, as in: MyDate date = makeDate(cast(Day)11, cast(Month)11, cast(Year)1999); If you wanted, you could also add a "default" function that took ints but required parameters in the right order. And that, basically, is problem solved, as far as I can see.
Dec 06 2007
On Thu, 06 Dec 2007 08:58:40 -0000, Bill Baxter = <dnewsgroup billbaxter.com> wrote:Janice Caron wrote:=On Dec 5, 2007 1:48 PM, renoX <renosky free.fr> wrote:I could ask the opposite question: why should we restrict the API to==the function and object name instead of using the full data that we =t =have?Another thought. If the name were part of the API then could one overload functions by parameter name? e.g. void f(int a) { /* do something */ } void f(int b) { /* do something different */ } After all, if the name were part of the API, then they have differen=sAPIs. I'm not convinced that this is a good idea. It's also not the only alternative. I have in the past written programs which take parameter=eof the same underlying type in any order, using only D-as-it-is-now (or C++), and it's not so hard. For example, suppose you want a function that looks like MyDate makeDate(int month, int day, int year) but you think callers might get confused about what order to pass th=parameters in (European date order, American date order, YMD date order, whatever...) typedef int Year; typedef int Month; typedef int Day; MyDate makeDate(Year y; Month m, Day d) {/*...*/ } MyDate makeDate(Year y, Day d, Month m) { return MyDate(y,m,d); }=MyDate makeDate(Day d, Month m, Year y) { return MyDate(y,m,d); }=MyDate makeDate(Month m, Day d, Year y) { return MyDate(y,m,d); }=999);That forces callers to name their arguments, as in: MyDate date =3D makeDate(cast(Day)11, cast(Month)11, cast(Year)1=sIf you wanted, you could also add a "default" function that took int==but required parameters in the right order. And that, basically, is problem solved, as far as I can see.Gee that's so clean! Not. You've taken one simple function and turned it into 4 functions plus 3=extra types. It's a workaround at best. --bbThat is a bad example of when (not) to use named parameters. A better on= e = is: typedef double Radions; typedef double Degrees; double sin(Degrees angleInDegrees); double sin(Radions angleInRadians); I think this is the classic example used to justify named parameters in = = Fortran-90. The typedef trick doesn't always work. You can use const for memset memset(void* dest, const void* source, int value); but not for file copy: void copyFile(string source, string dest); Here source and dest are easily confusee leading to errors hard to pick = up = at runtime. It would be nice if you could switch on an extra compiler warning that = forces you to use the parameter names to disambiguiate. Some would argue that an alternative more OO solution would be: File sourceFile(source); sourceFile.copyTo(dest); This kind of thing will be even easier when you can extend classes using= = any function whose first argument is the right type for 'this'. Though there is a = danger of serious encapsulation breakage there. Regards, Bruce.
Dec 06 2007