digitalmars.D.learn - Manipulating alias sequences
- Ben Ogles (26/26) Jul 15 2019 I have written a simple function that can call another function
 - Stefan Koch (4/7) Jul 15 2019 You cannot. meta-programming and compile-time evaluation are
 - Ben Ogles (10/18) Jul 15 2019 Sorry, I wasn't clear. The code I wrote does not actually
 - Paul Backus (13/30) Jul 15 2019 Use a run-time Tuple instead of an AliasSeq:
 - Ben Ogles (2/14) Jul 15 2019 Amazing, this works great! Thanks.
 
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
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
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: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)());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
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
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








 
 
 
 Ben Ogles <benjaminogles gmail.com> 