The fact people want it shows that there are plenty of cases where the asserted condition has side effects, this is usually the result of getting the data you want to assert on in the first place.
for example, you have a database you are putting things in occasionally, but often what/if you put in the db depends on stuff thats already there. You dont want to read from it every time you want to write to it, so you keep whatever you need for that in memory. Now you have an assumption that your in memory data, and db data are in sync, to assert that assumption you need to read data from the db and compare it to what you have in memory. That operation has side effects, and exists only to validate your assumption. Failure of this condition is purely the fault of the programmer.
I think you are missing the point of assert, it is not to check things the language already checks, it’s to check things the language doesn’t. Zig doesn’t know what your minimum buffer size is so it can’t check that, zig doesn’t know foo should only be called under certain conditions.
assert is for your assumptions/conditions that can’t be encoded into the language.
whether a condition has side effects is irrelevant to whether it should be asserted or return an error.
If the failure of the condition is something the caller can/should be able to handle, then it should be an error.
If failure of the condition can be only the fault of the programmer, then it should be an assertion.
For example std.Io.Reader.rebase, only calls vtable.rebase under certain conditions, the default vtable.rebase asserts those conditions. Failure of that assert means the upper non vtable function didn’t implement the right logic, it is not the fault of the user of the interface, nor is it the concrete implementations (eg File.Reader) fault. It is the fault of andrew/core team member who made the interface.
I don’t think you are guaranteed to already have ‘different build states’ if you need an assert with side effects. However, I think you should have ‘different build states’ so you can configure what asserts you want without affecting separate categories of asserts. This is very useful for debugging.