www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Manipulating alias sequences

reply Ben Ogles <benjaminogles gmail.com> writes:
I have written a simple function that can call another function 
over integral types with random arguments:

auto rnd = Random(42);

auto rand_integral(T)() {
   return uniform(T.min, T.max, rnd);
}

auto call_with_rand(alias fun)() {
   fun(staticMap!(get_rand_integral, Parameters!fun));
}

Now I want to extend it so that a caller can specify the values 
of only some of the parameters. I tried using a static foreach 
instead of the staticMap function. But I can't modify AliasSeq 
values.

alias args = AliasSeq!(0, 0);
static foreach (idx, val; args) {
   static if (user_defined_function_exists_for_arg!(idx)) {
     args[idx] = user_defined_function(); // cannot modify tuple
   } else {
     args[idx] = gen_rand_integral!(typeof(val)); // cannot modify 
tuple
   }
}

How do I build up an argument tuple at compile time where some 
values are randomly generated and others are given through some 
user defined function (most likely automatically discovered by a 
naming convention)?
Jul 15 2019
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Monday, 15 July 2019 at 13:40:29 UTC, Ben Ogles wrote:
 I have written a simple function that can call another function 
 over integral types with random arguments:

 [...]
You cannot. meta-programming and compile-time evaluation are supposed to be deterministic, and hence cannot take random values.
Jul 15 2019
parent Ben Ogles <benjaminogles gmail.com> writes:
On Monday, 15 July 2019 at 14:15:41 UTC, Stefan Koch wrote:
 On Monday, 15 July 2019 at 13:40:29 UTC, Ben Ogles wrote:
 I have written a simple function that can call another 
 function over integral types with random arguments:

 [...]
You cannot. meta-programming and compile-time evaluation are supposed to be deterministic, and hence cannot take random values.
Sorry, I wasn't clear. The code I wrote does not actually _produce_ the random values at compile time. It is just a template that evaluates to a function call where each argument is given as `gen_rand_integral()`. So if I call call_with_rand!(add)(); It will expand to add(gen_rand_integral!(int)(), gen_rand_integral!(int)()); But I want a way to expand this to add(gen_rand_integral!(int)(), user_defined_generator!(int)());
Jul 15 2019
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Monday, 15 July 2019 at 13:40:29 UTC, Ben Ogles wrote:
 Now I want to extend it so that a caller can specify the values 
 of only some of the parameters. I tried using a static foreach 
 instead of the staticMap function. But I can't modify AliasSeq 
 values.

 alias args = AliasSeq!(0, 0);
 static foreach (idx, val; args) {
   static if (user_defined_function_exists_for_arg!(idx)) {
     args[idx] = user_defined_function(); // cannot modify tuple
   } else {
     args[idx] = gen_rand_integral!(typeof(val)); // cannot 
 modify tuple
   }
 }

 How do I build up an argument tuple at compile time where some 
 values are randomly generated and others are given through some 
 user defined function (most likely automatically discovered by 
 a naming convention)?
Use a run-time Tuple instead of an AliasSeq: import std.typecons; auto args = tuple(0, 0); static foreach (idx, val; args) { static if (user_defined_function_exists_for_arg!idx) { args[idx] = user_defined_function(); } else { args[idx] = gen_random_integral!(typeof(val)); } } Then use `fun(args.expand)` to pass the members of the tuple as separate arguments to `fun`.
Jul 15 2019
parent Ben Ogles <benjaminogles gmail.com> writes:
On Monday, 15 July 2019 at 14:50:20 UTC, Paul Backus wrote:
 Use a run-time Tuple instead of an AliasSeq:

 import std.typecons;
 auto args = tuple(0, 0);
 static foreach (idx, val; args) {
     static if (user_defined_function_exists_for_arg!idx) {
         args[idx] = user_defined_function();
     } else {
         args[idx] = gen_random_integral!(typeof(val));
     }
 }

 Then use `fun(args.expand)` to pass the members of the tuple as 
 separate arguments to `fun`.
Amazing, this works great! Thanks.
Jul 15 2019