March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to J | The bigger point here is more profound: it is trivial to implement named parameters using structs + trivial lowerings, and this is no way conflicts with function overloading. D deserves to have named parameters to functions -- it makes for much more legible code, and obviates the need for slow builder patterns. Readable and speedable. It's win-win. |
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to J | With credit for inspiration to David Medlock in this post-- http://forum.dlang.org/thread/d9lnrr$26q3$1@digitaldaemon.com ... // Tongue firmly in cheek, I'd like to introduce // the NAPAPISS principle: (with apologies to SFINAE and RAII) // NAPAPISS = NAmed Parameters Are simply Passed in a Struct, Silly. // Yes, indeed, maybe this is what happens after drinking too much of // the fine wine products from the Napa valley... you start having // wild flights of fancy of how D might surprisingly soon have // named parameters.... import std.stdio; import std.c.stdlib; void main(string[] arg) { // this works today: but with the drawback that the // named params must be known at compile time... // Here is a named param call, // as compact as I could get it (see struct below for actual definition). auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls opCall writeln("a=", a); // prints "a=yo", as returned from opCall // And here's the runtime version, unfortunately you have to // pre-declare g because otherwise it won't survive the scope, and // the return value from myfunc.opCall would become inaccessible. string g; with(myfunc!()(0)) { x=rand() % 40; y=x/2; z=y/2; g = call(); // as a side effect, prints 'X 7, Y 3, Z 1' } writeln("g=", g); // prints "g=yo", as returned from opCall /* // The bright future: this demonstrates that // it would be fairly trivial to make some kind of annotation // like @kwarg or whaterver, to indicate that a function // was using this calling convention: @kwarg string f(int a, string b) { body; } // so that @kwarg function definitions are lowered to: struct f_kw { int a; string b; string f() { body; } } // and calls to @kwarg functions are transformed // from this: auto r = f(a=5, b="good"); // into this: f_kw tmp34; tmp34.a = 5; tmp34.b = "good"; auto r = tmp34.f(); // the benefit: named parameters can be used in a natural way, // and they need be known only at runtime. */ } // how the 'works today' above examples were implemented: struct myfunc(string init_string="") { // named keyword or named parameters // --the call arguments and their defaults int x=0; int y=0; int z=0; this(int) {} string opCall() { mixin(init_string ~ ";"); writefln("X %s, Y %s, Z %s", x, y, z ); return "yo"; } alias opCall call; } On Friday, 22 March 2013 at 09:18:33 UTC, J wrote: > > The bigger point here is more profound: it is trivial to implement named parameters using structs + trivial lowerings, and this is no way conflicts with function overloading. > > D deserves to have named parameters to functions -- it makes for much more legible code, and obviates the need for slow builder patterns. Readable and speedable. It's win-win. |
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to J | On 2013-03-22 11:17, J wrote: > With credit for inspiration to David Medlock in this post-- > http://forum.dlang.org/thread/d9lnrr$26q3$1@digitaldaemon.com ... > > // Tongue firmly in cheek, I'd like to introduce > // the NAPAPISS principle: (with apologies to SFINAE and RAII) > > // NAPAPISS = NAmed Parameters Are simply Passed in a Struct, Silly. > > // Yes, indeed, maybe this is what happens after drinking too much of > // the fine wine products from the Napa valley... you start having > // wild flights of fancy of how D might surprisingly soon have > // named parameters.... > > > import std.stdio; > import std.c.stdlib; > > void main(string[] arg) { > > // this works today: but with the drawback that the > // named params must be known at compile time... > > // Here is a named param call, > // as compact as I could get it (see struct below for actual > definition). > > auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls opCall > writeln("a=", a); // prints "a=yo", as returned from opCall > > > > // And here's the runtime version, unfortunately you have to > // pre-declare g because otherwise it won't survive the scope, and > // the return value from myfunc.opCall would become inaccessible. > string g; > with(myfunc!()(0)) { > x=rand() % 40; > y=x/2; > z=y/2; > g = call(); // as a side effect, prints 'X 7, Y 3, Z 1' > } > writeln("g=", g); // prints "g=yo", as returned from opCall > > > /* > // The bright future: this demonstrates that > // it would be fairly trivial to make some kind of annotation > // like @kwarg or whaterver, to indicate that a function > // was using this calling convention: > @kwarg string f(int a, string b) { body; } > > // so that @kwarg function definitions are lowered to: > struct f_kw { > int a; > string b; > string f() { body; } > } > > // and calls to @kwarg functions are transformed > // from this: > auto r = f(a=5, b="good"); > > // into this: > f_kw tmp34; > tmp34.a = 5; > tmp34.b = "good"; > auto r = tmp34.f(); > > // the benefit: named parameters can be used in a natural way, > // and they need be known only at runtime. > */ > } > > // how the 'works today' above examples were implemented: > struct myfunc(string init_string="") > { > // named keyword or named parameters > // --the call arguments and their defaults > int x=0; > int y=0; > int z=0; > > this(int) {} > string opCall() { > mixin(init_string ~ ";"); > writefln("X %s, Y %s, Z %s", x, y, z ); > return "yo"; > } > alias opCall call; > } Here's my proposal for anonymous structs that can be used as name parameters: http://forum.dlang.org/thread/kfbnuc$1cro$1@digitalmars.com?page=1 -- /Jacob Carlborg |
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to J | On Friday, 22 March 2013 at 09:18:33 UTC, J wrote:
>
> The bigger point here is more profound: it is trivial to implement named parameters using structs + trivial lowerings, and this is no way conflicts with function overloading.
>
> D deserves to have named parameters to functions -- it makes for much more legible code, and obviates the need for slow builder patterns. Readable and speedable. It's win-win.
Question for specialists of the topic : are parameter name available using compile time reflection ?
Because if they are, the problem boils down to perfect forwarding issue. And it seems solvable :
NamedCall!(
function,
"foo", fooVal,
"bar", barVal); // Booya !
|
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | http://dlang.org/phobos/std_traits.html#.ParameterIdentifierTuple |
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Friday, 22 March 2013 at 15:50:38 UTC, Dicebot wrote:
> http://dlang.org/phobos/std_traits.html#.ParameterIdentifierTuple
Seems to me like a solved problem.
|
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | so i hacked up a working solution yesterday. advantages over https://github.com/jacob-carlborg/mambo/blob/master/mambo/util/Reflection.d#L135: no need to no arguments at CT (just names); allows optional and non optional ones; allows return value; also, mambo depends on tango and is hard to revive. More later. see: https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d nothing to install, just call: rdmd --main -unittest dtools/util/functional.d auto s=callNamed!(fun,`x,y`)(10,20); given a function: auto fun(int x,int y=2,double z=z_val, string z2="asdf"); Compile time errors will occur on duplicate param names, or ones that don't exist, or ones that are not optional and not provided (eg x, above) Feel free to contribute / comment |
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to timotheecour | On Friday, 22 March 2013 at 18:48:56 UTC, timotheecour wrote:
> so i hacked up a working solution yesterday.
> advantages over https://github.com/jacob-carlborg/mambo/blob/master/mambo/util/Reflection.d#L135:
> no need to no arguments at CT (just names); allows optional and non optional ones; allows return value; also, mambo depends on tango and is hard to revive.
>
> More later.
>
>
> see:
> https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d
>
> nothing to install, just call:
> rdmd --main -unittest dtools/util/functional.d
>
>
> auto s=callNamed!(fun,`x,y`)(10,20);
> given a function:
> auto fun(int x,int y=2,double z=z_val, string z2="asdf");
>
> Compile time errors will occur on duplicate param names, or ones that don't exist, or ones that are not optional and not provided (eg x, above)
>
> Feel free to contribute / comment
Don't have time to look at the code now, but it seems awesome ! Great leverage of language capabilities. Slightly different from my proposal, but I'm really not sure which interface fit best. I'm starting to think this should be :
callNamed!(fun,`x`, `y`)(10,20);
But I'm not sure of all the pro and cons.
|
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | 22-Mar-2013 23:03, deadalnix пишет: > On Friday, 22 March 2013 at 18:48:56 UTC, timotheecour wrote: >> so i hacked up a working solution yesterday. >> advantages over >> https://github.com/jacob-carlborg/mambo/blob/master/mambo/util/Reflection.d#L135: >> >> no need to no arguments at CT (just names); allows optional and non >> optional ones; allows return value; also, mambo depends on tango and >> is hard to revive. >> >> More later. >> >> >> see: >> https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d >> >> >> nothing to install, just call: >> rdmd --main -unittest dtools/util/functional.d >> >> >> auto s=callNamed!(fun,`x,y`)(10,20); >> given a function: >> auto fun(int x,int y=2,double z=z_val, string z2="asdf"); >> >> Compile time errors will occur on duplicate param names, or ones that >> don't exist, or ones that are not optional and not provided (eg x, above) >> >> Feel free to contribute / comment > > Don't have time to look at the code now, but it seems awesome ! Great > leverage of language capabilities. Slightly different from my proposal, > but I'm really not sure which interface fit best. I'm starting to think > this should be : > > callNamed!(fun,`x`, `y`)(10,20); Can opDispatch & chaining be leveraged to get the effect of: named!(fun).x(10).y(20).call(); Or maybe even simpler? > > But I'm not sure of all the pro and cons. -- Dmitry Olshansky |
March 22, 2013 Re: this is almost a workaround for the lack of named parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to J | On Friday, 22 March 2013 at 10:17:02 UTC, J wrote:
> With credit for inspiration to David Medlock in this post-- http://forum.dlang.org/thread/d9lnrr$26q3$1@digitaldaemon.com ...
>
> // Tongue firmly in cheek, I'd like to introduce
> // the NAPAPISS principle: (with apologies to SFINAE and RAII)
>
> // NAPAPISS = NAmed Parameters Are simply Passed in a Struct, Silly.
>
> // Yes, indeed, maybe this is what happens after drinking too much of
> // the fine wine products from the Napa valley... you start having
> // wild flights of fancy of how D might surprisingly soon have
> // named parameters....
>
>
> import std.stdio;
> import std.c.stdlib;
>
> void main(string[] arg) {
>
> // this works today: but with the drawback that the
> // named params must be known at compile time...
>
> // Here is a named param call,
> // as compact as I could get it (see struct below for actual definition).
>
> auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls opCall
> writeln("a=", a); // prints "a=yo", as returned from opCall
>
>
>
> // And here's the runtime version, unfortunately you have to
> // pre-declare g because otherwise it won't survive the scope, and
> // the return value from myfunc.opCall would become inaccessible.
> string g;
> with(myfunc!()(0)) {
> x=rand() % 40;
> y=x/2;
> z=y/2;
> g = call(); // as a side effect, prints 'X 7, Y 3, Z 1'
> }
> writeln("g=", g); // prints "g=yo", as returned from opCall
>
>
> /*
> // The bright future: this demonstrates that
> // it would be fairly trivial to make some kind of annotation
> // like @kwarg or whaterver, to indicate that a function
> // was using this calling convention:
> @kwarg string f(int a, string b) { body; }
>
> // so that @kwarg function definitions are lowered to:
> struct f_kw {
> int a;
> string b;
> string f() { body; }
> }
>
> // and calls to @kwarg functions are transformed
> // from this:
> auto r = f(a=5, b="good");
>
> // into this:
> f_kw tmp34;
> tmp34.a = 5;
> tmp34.b = "good";
> auto r = tmp34.f();
>
> // the benefit: named parameters can be used in a natural way,
> // and they need be known only at runtime.
> */
> }
>
> // how the 'works today' above examples were implemented:
> struct myfunc(string init_string="")
> {
> // named keyword or named parameters
> // --the call arguments and their defaults
> int x=0;
> int y=0;
> int z=0;
>
> this(int) {}
> string opCall() {
> mixin(init_string ~ ";");
> writefln("X %s, Y %s, Z %s", x, y, z );
> return "yo";
> }
> alias opCall call;
> }
>
>
> On Friday, 22 March 2013 at 09:18:33 UTC, J wrote:
>>
>> The bigger point here is more profound: it is trivial to implement named parameters using structs + trivial lowerings, and this is no way conflicts with function overloading.
>>
>> D deserves to have named parameters to functions -- it makes for much more legible code, and obviates the need for slow builder patterns. Readable and speedable. It's win-win.
WTF? What do kwargs have to do with programming? Sounds more like a half-Klingon & half-Ferengi species to me.
|
Copyright © 1999-2021 by the D Language Foundation