5 ms·
> It's still under debate and I'm personally in the camp that errors should not have a payload, so I would avoid assuming that it's definitely the preferable ch
by coder543 6y ago
> It's still under debate and I'm personally in the camp that errors should not have a payload, so I would avoid assuming that it's definitely the preferable choice.
How can you argue that not having access to string index where the JSON was unparseable is better than having access to it? I read through issues/2647, and I read through the "existing pattern", and it just seems obvious to me that containing the error information in the error is better than trying to hack it through side channels.
If A -> B, and B returns an error through a side channel, then A can use it and "what's so bad about that?"
But this doesn't seem to scale very well.
If A is refactored to use an intermediate function X, then it just doesn't work. A -> X -> C would mean that...
X cannot use Zig's normal error handling syntax to automatically propagate this error that A is better equipped to handle, unless we're going to further stipulate that A must pass this Diagnostics struct into X which then must pass it into B.
If we now assume that X calls into two fallible functions, B and C, and each of them provide their own diagnostics structs, then X will have to take in two "out" arguments that provide the diagnostics, and every single caller of X will have to provide those two values.
You see how this goes. It just doesn't seem scalable.
Why not take the current design to its logical conclusion of simply having every function return a Boolean indicating whether it succeeded or not, and then require the caller to look into some "out" argument to determine what the error was? Obviously, that would be extremely annoying.
A tagged error union containing the diagnostic error values is just a minor evolution of the current design that brings huge wins for language ergonomics.
For errors that don't need to carry a value, there is no additional cost: they compile and work exactly as they do today.
For errors that carry a value, the size of the error struct is only the size of the largest error value (plus the tag, of course), not the product of all possible error values, so the global error set will never grow to be enormous unless you have some very weird error type. In which case, you can solve this problem by fixing that error type.
So, I'm not deeply versed in Zig, but I have personally argued in favor of Zig's async design, which seems exceptionally interesting. I had not realized until now how limiting the error system implementation was, but I had superficially appreciated how much less verbose it was than Rust's where you tend to hand write these error enums, or use a bunch of code gen. However, errors benefit tremendously from having the ability to supply payloads.
No one is required to act on the payloads within the errors, but no one is able to if they don't exist.
- kristoff_it 6y agoThe problem is for all the situations where the error payload isn't needed. You now need to carry around the extra syntactic complexity and/or the extra wasted memory (unless you have a strategy to elide all of this stuff when error payloads are not needed). I think it's not trivial to find a good alternative to status quo.
- coder543 6y ago“wasted memory”... this stuff exists on the stack, right? And we’re talking on the order of like 64 bytes or less in common, practical scenarios? I believe the solution has been clearly presented to those who are listening, and the downsides are so much smaller than the status quo. If people on the language team are unwilling to provide developers with the tools to make more robust software because of something like 64 bytes of stack memory... I find that pretty shocking. And yes, I mean that it is extremely difficult to diagnose and fix issues in production software when you only get back a static error value that lacks the dynamic error context that a payload would provide. I’ve been there, done that. Do not want that again. Such a strong viewpoint (avoiding such error payloads) could at least focus more on the technical aspects of how best to implement the elision of unused error payloads instead of just broadly opposing the concept, since it should be obvious how beneficial those payloads are, and the only question is how to remove them for developers who literally cannot spare dozens of bytes of stack memory. (Which I find hard to believe outside of AVR or PIC microcontrollers, which is probably not the best use case to be optimizing for in a new language.) Elision is an optimization that can be added later. It’s not obvious that it can’t be done, and there’s no clear reason that it has to be solved first... I just don’t think anyone would actually care enough to implement it once they see how nonexistent the negative impacts are, but it would be a cool optimization. But, maybe everyone who upvoted the apparently most upvoted GitHub issue on the Zig repo (including myself) is just completely wrong and this obvious solution is actually secretly terrible. It’s entirely possible. Your comment has not really done anything to help me believe that I’m wrong, though, unfortunately. But, as I’m basically “no one” in this context, my opinion probably doesn’t really matter.
- dnautics 6y ago