# Reducing boilerplate for comptime anonymous array literal

I’m trying to simplify a set of chained if-elses

``````if( time < duration_1 ) {
return computation( time, factor_1, offset_1 );
}
else if( time < duration_1 + duration_2 ) {
return computation( time - duration_1, factor_2, offset_2 );
}
# ...
else {
return final;
}
``````

By using a macro-like function to turn a list of constraints into the above logic:

``````const Step = struct { duration: i32, factor: i32, offset: i32, ... };

fn Compute( time: i32, final: i32, steps: []const Step ) i32 {
var base_time = time;

for (steps) |step| {
if( base_time < step.duration ) {
return computation( base_time, step.duration, step.offset );
}
base_time -= step.duration;
}

return final;
}

fn run(...) {
# ...
result = Compute( time, final, ([_]Step {
Step.init( duration_1, factor_1, offset_1 ),
Step.init( duration_2, factor_2, offset_2 ),
})[0..] );
}
``````

Which works, but the complexity of the `([_]Step { ... })[0..]` makes me think I’m doing something wrong. I think it should be possible to do something like fmt since all I want is a comptime macro-like expansion. But I can’t figure out to tell the compiler that “steps” is a variable-length comptime-known list of Step structures.

I.e. simplify the appearance at time of use to something like

``````   result = Compute( time, final, .{
Step.init( duration_1, factor_1, offset_1 ),
Step.init( duration_2, factor_2, offset_2 ),
});
``````

`fn Compute( time: i32, final: i32, steps: anytype) i32`

Iterate through steps just like an array. Another option is to pass the length of steps as a comptime parameter:

`fn Compute( time: i32, final: i32, comptime count: comptime_int, steps: [count]Steps) i32`

Thanks, that did it.

``````fn Compute( time: i32, final: i32, steps: anytype ) i32 {
var base_time = time;

inline for ( steps ) |step| {
# ...
}

return final;
}
``````

I was also missing the “inline” on the “for”.

2 Likes