March 22, 2013
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
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
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
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
http://dlang.org/phobos/std_traits.html#.ParameterIdentifierTuple
March 22, 2013
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
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
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
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
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.