Const or var struct depending on program state

Somewhere I have a big constant struct filled with lots of const arrays, something like:

const Terms = struct {
    values: [10]i32,
    more_values: [10]i32,
}

const default_terms: Terms = .{
    .values = .{ 1,2,3,4,5,6,7,8,9,10},
    .more_values =  .{ 1,2,3,4,5,6,7,8,9,10},
}

now I want - depending on a global comptime boolean program state - these terms to be variable (mutable) or const.

pub const is_variable: bool = true; // or false
pub terms = if (is_variable) 
    variable_terms // mutable (and initialized with default_terms)
else 
    default_terms; // not mutable, totally const

The idea is to use and change these terrms when is_variable == true
and only use them if is_variable == false.
Is that possible?

Edit: the problem is the declaration:
pub const or pub var.

Going from the least work in the API, to the least work using the api:

Just have different definitions and let the users figure out which to use.

Make terms a pointer, the type can be inferred, it’d be a const or non const pointer depending on which It’s pointing to.

You could make terms a namespace that is different depending on is_variable.

I think the most robust way would be to make the const/var data private and have an api to access them.

There are probably more ways to do it too.

Not sure why you would want to do this but here’s how I think you could do it:

pub const wrapperStruct = if (mybool) struct {
    pub const variableName: myType = myValue;
} else struct {
    pub var variableName: myType = myValue;
};

Wrapping things in structs is something that can achive many things.
You Will access them via wrapperStruct.variableName

hm… I still don’t know how to declare it.

You used pub, which seems to imply that you intend to declare terms in the global scope. This makes me uneasy because if it is being set as a variable, it suggests that you intend to use a global variable, which is generally an unnecessary anti-pattern.

It could be an anti pattern. The idea is - when the program is in its ‘normal’ state - use the const arrays (in a lot of places). When I run (just recompile) the program locally I have to change / tune these arrays, write the source code to some file, and replace the default_terms with the newly generated ones.

For the pointer option

const default_terms = ...;
var variable_tersm = ...;

pub const terms = if (comptime is_variable) &variable_terms else &default_terms;

Since the type is inferred, and the condition is comptime, it will a const or non const pointer depending on the condition.

Please use ``` code blocks when posting code. I FTFY but it’s nicer for all involved.

1 Like

Oh thank you, I have been wondering how other people do it for a while

1 Like

That is easy :slight_smile:
But now I have one non-used variable.

They’re global so they are allowed to be unused, and won’t even be analysed.

Besides, I imagine you would initialise variable_terms = default_terms, so you’d only have an unused var in one case, not both.

Will the variable be non-existent in the exe when we are in !is_variable mode?

yes, zig will only include things that are actually needed, most languages remove them after the fact, but that tends to mis things

zig doesn’t look at them in the first place, but that’s also the downside, if it isn’t needed your code won’t trigger any errors beyond syntax errors. Its called lazy evaluation.

1 Like

Great. That is very usable.
One extra question. Is it possible to print the whole thing exactly as it is declared in code?
Or do I need to write a function for that?
(Edit: in reality the struct is much bigger of course. and not filled with ints but small structs)

you’ll need a custom format function to print the whole thing, the default struct printing has a limited depth it prints.

2 Likes

If you (@ericlang) don’t care about writing a formatter, I can suggest pretty, good results out of the box and reasonably configurable to purpose.

1 Like

okidoki! maybe I will do that.
I just wrote my ridiculous 1-d and 2-d array anytype printer. but i’ll contemplate using it!

1 Like