I disagree. Zon isnât a configuration language, itâs a serialization format of a Zig literal.
That is, Zon is both machine readable and writable. A critical use case is a program reading a Zon file, making a change, and then saving back to that Zon file. Such a program making a change would either need to track additional state around where functions or references are used (defeating the simplicity of working with simple Zig values), or it would clobber such hand crafted statements while editing other information.
For example, you could imagine a video game level editor leveraging Zon. It would load a level.zon, the user could make edits, then save the file. On compilation of the game the level.zon is then @importâd , and baked directly into the code. Such a system has many advantages:
- The translation into code objects is trivial.
- Diffs in change lots have a hope of being human readable, and may be mergable. (unlike binary formats)
- Changes to the format can be handled through algorithmic editing, or hand editing like youâd do for any other literal.
If your data is going to be only edited by hand, and you want additional functionality, then you actually just want a Zig file. If you then want to pass this as a serialized format to a running program as a configuration format: Have your declaration exist inside of a Zig program which emits that declaration as a Zon file, and use that as a build step. You can use the build system to make this very ergonomic and scalable. Zon may not even be the ideal output fromat, depending on constraints such as size, de-serialization speed, and human readability.
You could write your own configuration language or use an existing one if the ergonomics of a configuration language are what you want. However, be warned: You start with literal values. Then users ask for functions. âOh how about importing.â âHey can I please have loops and conditionals?â âI really have a strong use case for templating.â All configuration languages converge to programming languages, but worse. Just use a programming language. Please, never waste my time with formatting functions to do indenting to get a yaml file to template properly.
Also keep in mind that you have the full power of Zig at hand. The values [de]serialized by Zon can be generics, where comptime turns easy to edit/serialize values into other values. Eg, (untested, rough code sketch)
fn MyConfigType(comptime baked: bool) type {
return struct {
start_date: if (baked) Date else []const u8,
end_date: if (baked) Date else []const u8,
};
}
fn bake(InType: type, OutType: type, v: InType ) OutType {
if (InType == OutType) return v;
// if struct, recursively call bake on each field.
if (InType == []const u8 and OutType == Date) {
return Date.parse(v) catch unreachable;
}
// Other translation cases
unreachable;
}
const my_baked_value = bake(MyConfigType(false), MyConfigType(true), @import("my_config.zon"));
Not that I would necessarily suggest the above for something as simple as dates, but I think that technique in the broad sense does have some uses where an editor and your application code want slightly different types.