Agreed, this is probably my biggest ongoing issue with Zig. I really enjoy it overall but this is a really big sticking point.
I find it really amusing that we have a language that has built its brand around "only one obvious way to do things", "reducing the amount one must remember", and passing allocators around so that callers can control the most suitable memory allocation strategy.
And yet in this language we supposedly can't have error payloads because not every error reporting strategy is suitable for every environment due to memory constraints, so we must rely on every library implementing its own, yet slightly unique version of the diagnostic pattern that should really be codified as some sort of a language construct where the caller decides which allocator to use for error payloads (if any).
Instead we must hope that library authors are experienced and curious enough to have gone out of their way to learn this pattern because it isn't mentioned in any official documentation and doesn't have any supporting language constructs and isn't standardized in any way.
There must be an argument against this (rather obvious) observation but I'm not aware of it?
Genuine question, how would error set unioning work with payloads? error.WriterFailed (might be getting the exact name wrong) is returned from many different writers, whether writing to a statically allocated array, writing to a socket, or writing to a file. Each error would have a very different payload, so how would you disambiguate between the different payloads with a global error type? The way I see it is either you have error sets, or payloads, but not both.
I'm also wondering what payload people want. There's already an error handling trace (similar but different to a normal stack trace) that captures the how the error propagates up to the point it's being handled so shows you exactly where the initial point was.
A payload can contain any details that the producer of that error believes are important. I don't know what you mean by the error handling trace, how does that help with the toy JSON parsing example? I want the payload to indicate the position in the input string where the parser encountered an error.
I want a function like `diffFiles(path_a, path_b)` to have an error set of `error { ReadError }` with more detailed information in the payload (e.g. file path, translated error code). The alternative is: `error { FileAReadErrorNotFound, FileBReadErrorNotFound, FileAReadErrorPermissionDenied, FileBReadErrorPermissionDenied, ...}`
I would expect a generic interface to define a base error payload which would contain some common information and a pointer to the implementation-specific details (or embed them in the original payload as a tagged union).
I find it really amusing that we have a language that has built its brand around "only one obvious way to do things", "reducing the amount one must remember", and passing allocators around so that callers can control the most suitable memory allocation strategy.
And yet in this language we supposedly can't have error payloads because not every error reporting strategy is suitable for every environment due to memory constraints, so we must rely on every library implementing its own, yet slightly unique version of the diagnostic pattern that should really be codified as some sort of a language construct where the caller decides which allocator to use for error payloads (if any).
Instead we must hope that library authors are experienced and curious enough to have gone out of their way to learn this pattern because it isn't mentioned in any official documentation and doesn't have any supporting language constructs and isn't standardized in any way.
There must be an argument against this (rather obvious) observation but I'm not aware of it?