Thread overview
Key arguments
Jul 14, 2008
baleog
Jul 14, 2008
baleog
Jul 14, 2008
downs
Jul 14, 2008
downs
Re: [ot] Key arguments
Jul 14, 2008
BCS
Jul 14, 2008
downs
Jul 14, 2008
Bill Baxter
July 14, 2008
How can i implement key arguments in D? I want something like this:
--
void f(int x, double y = 2.0, int z = 3);
...
f(1, z:10, y:5.1); // x=1, y=5.1, z=10
f(1, z:10); // x=1, y=2.0, z=10
--
I tried to do this with Variant type and explicit type checking. But it takes a lot of routine actions. Maybe exists a better way?

Best regards
July 14, 2008
"baleog" <maccarka@yahoo.com> wrote in message news:g5er1d$1p15$1@digitalmars.com...
> How can i implement key arguments in D? I want something like this:
> --
> void f(int x, double y = 2.0, int z = 3);
> ...
> f(1, z:10, y:5.1); // x=1, y=5.1, z=10
> f(1, z:10); // x=1, y=2.0, z=10
> --
> I tried to do this with Variant type and explicit type checking. But it takes a lot of routine actions. Maybe exists a better way?
>
> Best regards

Downs will reply with a horrid hack involving overloading opAssign for some static instances of some structures and then getting their values in the function, but then you're severely limited since the "parameter" names are globals, and since that's so, you can't have two functions that use the same named parameters executing at the same time, either in a multithreaded fashion or with simple recursion.

There's no general purpose way to do it, no.


July 14, 2008
Please look at the code where i tried to implement something like Keys arguments:
---------
U K(T,U,V...)(T key, U default_value, V args) {
  foreach(i,h; args)
    {
      try {
      	static if(!is(typeof(args[i]) == void[0u]))
	  static if (is(T == typeof(h.keys[0])) && is(U == typeof(h.values[0])))
	    return h[key];
      } catch (Exception e) {
	;
      }
    }
  return default_value;
}

void f(T...)(int x, T args)
{

  int y = K("y",0, args);
  double z = K("z", 10.0, args);
  writefln(y);
  writefln(z);

}

unittest
{
  f(1,["y":2], ["z":3.1]); // 2 3.1
  f(1); // 0 10
}
-----
What do you think about this attempt?

July 14, 2008
Jarrett Billingsley wrote:
> > "baleog" <maccarka@yahoo.com> wrote in message news:g5er1d$1p15$1@digitalmars.com...
>> >> How can i implement key arguments in D? I want something like this:
>> >> --
>> >> void f(int x, double y = 2.0, int z = 3);
>> >> ...
>> >> f(1, z:10, y:5.1); // x=1, y=5.1, z=10
>> >> f(1, z:10); // x=1, y=2.0, z=10
>> >> --
>> >> I tried to do this with Variant type and explicit type checking. But it takes a lot of routine actions. Maybe exists a better way?
>> >>
>> >> Best regards
> >
> > Downs will reply with a horrid hack involving overloading opAssign for some static instances of some structures and then getting their values in the function, but then you're severely limited since the "parameter" names are globals, and since that's so, you can't have two functions that use the same named parameters executing at the same time, either in a multithreaded fashion or with simple recursion.
> >

Such abject nonsense. My hack is based on typesystem abuse, not global *variables*. It also doesn't use structs.

Basically, the idea is that you typedef double y_parameter; then y_parameter y_p(double d) { return cast(y_parameter) d; }

Then just make f a templated function, so that void f(T...)(int x, T t); and check for the presence of a y_parameter in T.

Called like so: f(2, y_p = 5f);
July 14, 2008
"downs" <default_357-line@yahoo.de> wrote in message news:g5fsef$p0d$4@digitalmars.com...

> Such abject nonsense. My hack is based on typesystem abuse, not global *variables*

Your face is abject nonsense!

> It also doesn't use structs.
>
> Basically, the idea is that you typedef double y_parameter; then y_parameter y_p(double d) { return cast(y_parameter) d; }
>
> Then just make f a templated function, so that void f(T...)(int x, T t); and check for the presence of a y_parameter in T.
>
> Called like so: f(2, y_p = 5f);


July 14, 2008
Jarrett Billingsley wrote:
> "downs" <default_357-line@yahoo.de> wrote in message news:g5fsef$p0d$4@digitalmars.com...
> 
>> Such abject nonsense. My hack is based on typesystem abuse, not global *variables*
> 
> Your face is abject nonsense!
> 

Verily, I believe it is indeed your maternal parent who possesses this attribute!

Ooooh, incinerate.

>> It also doesn't use structs.
>>
>> Basically, the idea is that you typedef double y_parameter; then y_parameter y_p(double d) { return cast(y_parameter) d; }
>>
>> Then just make f a templated function, so that void f(T...)(int x, T t); and check for the presence of a y_parameter in T.
>>
>> Called like so: f(2, y_p = 5f);
> 
> 

July 14, 2008
I really hope this is all Tung-in-cheek


July 14, 2008
BCS wrote:
> I really hope this is all Tung-in-cheek
> 
> 
Just a gentlemen's disagreement. The kind that sets off wars. :)

"Was this the hack that launched a thousand flames / and burnt the threads of this NG?"
July 14, 2008
"downs" <default_357-line@yahoo.de> wrote in message news:g5g29h$146h$1@digitalmars.com...
> Jarrett Billingsley wrote:
>> "downs" <default_357-line@yahoo.de> wrote in message news:g5fsef$p0d$4@digitalmars.com...
>>
>>> Such abject nonsense. My hack is based on typesystem abuse, not global *variables*
>>
>> Your face is abject nonsense!
>>
>
> Verily, I believe it is indeed your maternal parent who possesses this attribute!
>
> Ooooh, incinerate.

GOD YOU BURNED ME SO BAD


July 14, 2008
baleog wrote:
> How can i implement key arguments in D? I want something like this:
> --
> void f(int x, double y = 2.0, int z = 3);
> ...
> f(1, z:10, y:5.1); // x=1, y=5.1, z=10
> f(1, z:10); // x=1, y=2.0, z=10
> --
> I tried to do this with Variant type and explicit type checking. But it takes a lot of routine actions. Maybe exists a better way?
> 
> Best regards

If you have a lot of arguments with various optional arguments that each have their own defaults, I think a struct is the most straightforward solution right now.

struct FOptions {
   double y = 2.0;
   int z = 3;
}

void f(int x, FOptions opt) {...}

{FOptions opt;
 opt.z = 10;
 opt.y = 5.1;
 f(1, opt);
}

{FOptions opt;
 opt.z = 10;
 f(1, opt);
}

It would be a lot nicer if static struct initializers worked for non-static structs too.  Then you could do:

Foptions opt = {z:10};
f(1,opt);

Or even f(1,{z:10});

There have been proposals to make struct initializers more useful along these lines.  The next step logical step in that evolution would be to recognize a trailing struct argument as a keyword set, and let you call

 f(1,z:10)
as a shortcut for
 f(1,{z:10})
which would be a shortcut for something like
 f(1,cast(FOptions){z:10})
which would work if struct initializers didn't have to be static.

Walter doesn't seem particularly interested, though.

--bb