digitalmars.D.learn - Function with default parameters
- =?UTF-8?B?TWFyaXVzeiBHbGl3acWEc2tp?= (12/12) Sep 17 2010 I just could promise I've seen in D2 something like in scripting languag...
- Steven Schveighoffer (6/17) Sep 17 2010 D parameters don't work this way. You cannot specify a parameter by nam...
- =?UTF-8?B?TWFyaXVzeiBHbGl3acWEc2tp?= (19/27) Sep 17 2010 No? That was different language then :(
- Simen kjaeraas (86/101) Sep 17 2010 e =
- Philippe Sigaud (33/33) Sep 18 2010 It seems doable to have some kind of function transformer (adaptor?) for
- Simen kjaeraas (6/42) Sep 18 2010 My main problem with these solutions is that they're largely runtime
- Philippe Sigaud (4/7) Sep 18 2010 I imagined the foo("b", 100, "d", true) version to be largely CT: variad...
- Jacob Carlborg (6/18) Sep 18 2010 I have a simple implementation of named arguments here:
I just could promise I've seen in D2 something like in scripting languages: module test; void main (string[] args) { test(b = "test"); } void test(string a = "a", string b = "b", string c = "c") { } Basically picking just right parameter while other have default. But now I can't find syntax anywhere. This code didn't worked, could you refresh my memory? Thanks, Mariusz Gliwiński
Sep 17 2010
On Fri, 17 Sep 2010 18:37:09 -0400, Mariusz Gliwiński <alienballance gmail.com> wrote:I just could promise I've seen in D2 something like in scripting languages: module test; void main (string[] args) { test(b = "test"); } void test(string a = "a", string b = "b", string c = "c") { } Basically picking just right parameter while other have default. But now I can't find syntax anywhere. This code didn't worked, could you refresh my memory?D parameters don't work this way. You cannot specify a parameter by name. There are tricks you can use, such as structs with initializers, but the result is probably not what you want. -Steve
Sep 17 2010
On 2010-09-18 00:40, Steven Schveighoffer wrote:On Fri, 17 Sep 2010 18:37:09 -0400, Mariusz Gliwiński <alienballance gmail.com> wrote:No? That was different language then :( Why it isn't allowed? Implementing that would be just about checking if all required parameters are filled and make something with parameter name / local function variable conflict. It would be nice a little nice thing... Or maybe lack of this feature pulling programmer out from throwing into function 10 rarely used parameters? Would be a bad thing? What are limitations for parameter number? There are any? Lastly, what's the most preferred way of adding many rarely used parameters into function? Been thinking about adding struct for them but it's probably not efficient. Been thinking about variadic solution, but that's just ugly since I hide possible solutions from programmer. I can make solution stateful in the meaning of adding parameters one by one because it's a method... I don't like this solution too. Named parameters would be great but... absent. As You probably understand adding foo(,,,,,,,,,bar,,,) isn't proper solution too :) Any hints? Thanks, Mariusz GliwińskiBasically picking just right parameter while other have default. But now I can't find syntax anywhere. This code didn't worked, could you refresh my memory?D parameters don't work this way. You cannot specify a parameter by name. There are tricks you can use, such as structs with initializers, but the result is probably not what you want.
Sep 17 2010
Mariusz Gliwi=C5=84ski <alienballance gmail.com> wrote:Why it isn't allowed? Implementing that would be just about checking i=f =all required parameters are filled and make something with parameter =name / local function variable conflict. It would be nice a little nic=e =thing...Many of us have lobbied for that feature. I understand that it's hard finding the time to implement all the features we want, and finding the right syntax (yours, for instance, conflicts with assignment).Or maybe lack of this feature pulling programmer out from throwing int=o =function 10 rarely used parameters? Would be a bad thing? What are =limitations for parameter number? There are any?I know of no such limitation. There likely is one in the compiler, if no= t in the language.Lastly, what's the most preferred way of adding many rarely used =parameters into function? Been thinking about adding struct for them b=ut =it's probably not efficient. Been thinking about variadic solution, bu=t =that's just ugly since I hide possible solutions from programmer. I ca=n =make solution stateful in the meaning of adding parameters one by one ==because it's a method... I don't like this solution too. Named =parameters would be great but... absent. As You probably understand =adding foo(,,,,,,,,,bar,,,) isn't proper solution too Any hints?If you need to pass many parameters to a function, you should probably think twice about what you're doing. It is often an indication that your= function is trying to do too much, and perhaps it should be an object of= some kind. Creating a struct with all those parameters as fields may feel wrong, but it can be the correct solution. Also, method chaining can be used to good effect in such situations: struct Foo { int _param1 =3D 4; string _param2 =3D "Hello!"; ref Foo parameter1( int value ) { _param1 =3D value; return this; } ref Foo parameter2( string value ) { _param2 =3D value; return this; } void opCall( float mandatoryParameter ) { // Do stuff } } property Foo foo( ) { return Foo.init; } void main( ) { foo.parameter1( 3 ).parameter2( "ouch" )( 0.23 ); //If you want to use assignment, this also works: ((foo.parameter1 =3D 3).parameter2 =3D "ouch")( 0.23 ); } One could also use templates to inspect std.typecons.Tuples and ascertai= n the names of their fields, then use those as parameters: import std.typecons; void bar( T =3D Tuple!() )( int req1, string req2, T arg =3D T() ) { float optional =3D 2.54; static if ( __traits( compiles, { optional =3D arg.optional; } ) ) = { optional =3D arg.optional; } // Do stuff } void main( ) { bar( 1, "bonk!" ); bar( 1, "bonk!", Tuple!( float, "optional" )( 19.7 ) ); } The main problem of this solution is its ugliness. One could, of course, also use template parameters to specify which parameters are = passed: template baz( T... ) { void baz( U... )( int mandatory, U optional ) if ( U.length =3D=3D = = T.length ) { string optionalValue =3D "a"; foreach ( i, name; T ) { if ( name =3D=3D "optionalValue" ) { optionalValue =3D optional[i]; } } } } void main( ) { baz!("optionalValue")( 1, "b" ); } A problem of this solution is that it's verbose, has little visual coupl= ing between parameter names and values, and does not check for unused = parameters. The verbosity and unused parameter problems could be lessened by making = a templated solution, but I'm not about to do that right now. -- Simen
Sep 17 2010
It seems doable to have some kind of function transformer (adaptor?) for this. from: int foo(int a = 0, int b = 1, double c = 0.0, bool d = false) { return 1;} alias namedParams!foo nfoo; nfoo("d", true); // a = 0, b = 1, c = 0.0, d = true nfoo("d", true, "b", 100); // a=0, b=100, c=0.0, d=true nfoo(1, 2, "d", true); // a=1, b=2, c=0.0, d=true That is, it expects some values, then string/values couples. Downside: in the above example, if foo accepts a string argument in first or second position the "d" will be passed down as an argument... or, using AA syntax: nfoo(1, ["d":true],["b":100]); Would that be palatable? Because I think it's doable. To obtain the arguments names: int foo(int a, int b, double c = 0.0, bool d = true) { return 1;} template Name(alias foo) if (isCallable!foo) { enum string Name = S!(foo.stringof); } template S(string s) // this template is just a trick because foo.stringof directly displeases DMD { enum string S = s; } writeln(Name!foo); // "int(int a, int b, double c = 0, bool d = true)" So this gives me: - the arguments names - which ones have default values - what is that default value The difficulty here is correctly parsing the ( ,,,) part, without getting desoriented by argument types that themselves use (,), like templated types. Philippe
Sep 18 2010
Philippe Sigaud <philippe.sigaud gmail.com> wrote:It seems doable to have some kind of function transformer (adaptor?) for this. from: int foo(int a = 0, int b = 1, double c = 0.0, bool d = false) { return 1;} alias namedParams!foo nfoo; nfoo("d", true); // a = 0, b = 1, c = 0.0, d = true nfoo("d", true, "b", 100); // a=0, b=100, c=0.0, d=true nfoo(1, 2, "d", true); // a=1, b=2, c=0.0, d=true That is, it expects some values, then string/values couples. Downside: in the above example, if foo accepts a string argument in first or second position the "d" will be passed down as an argument... or, using AA syntax: nfoo(1, ["d":true],["b":100]); Would that be palatable? Because I think it's doable. To obtain the arguments names: int foo(int a, int b, double c = 0.0, bool d = true) { return 1;} template Name(alias foo) if (isCallable!foo) { enum string Name = S!(foo.stringof); } template S(string s) // this template is just a trick because foo.stringof directly displeases DMD { enum string S = s; } writeln(Name!foo); // "int(int a, int b, double c = 0, bool d = true)" So this gives me: - the arguments names - which ones have default values - what is that default value The difficulty here is correctly parsing the ( ,,,) part, without getting desoriented by argument types that themselves use (,), like templated types.My main problem with these solutions is that they're largely runtime solutions. Not that calling a function with named parameters is very likely to happen in an inner loop, now I think of it... -- Simen
Sep 18 2010
My main problem with these solutions is that they're largely runtime solutions. Not that calling a function with named parameters is very likely to happen in an inner loop, now I think of it...I imagined the foo("b", 100, "d", true) version to be largely CT: variadic list, testing and extracting done at CT. As for the one accepting AAs, I don't know. Philippe
Sep 18 2010
On 2010-09-18 00:37, Mariusz Gliwiński wrote:I just could promise I've seen in D2 something like in scripting languages: module test; void main (string[] args) { test(b = "test"); } void test(string a = "a", string b = "b", string c = "c") { } Basically picking just right parameter while other have default. But now I can't find syntax anywhere. This code didn't worked, could you refresh my memory? Thanks, Mariusz GliwińskiI have a simple implementation of named arguments here: http://dsource.org/projects/orange/browser/orange/util/Reflection.d search for "callWithNamedArguments". -- /Jacob Carlborg
Sep 18 2010