I’ve always been frustrated by the lack of interfaces in the Zig language, especially after having a taste of Rust’s traits. However, knowing Zig’s take on simplicity, and where it stands in its roadmap, I understand why it can’t be there yet (maybe ever).
But with the help of a few seemingly under-appreciated features like usingnamespace, the lazy semantic analysis, the absence of actual distinction between methods and functions, I’ve made Interfacil.
Really Nice Idea, I’m trying to build something from Rust too, I would really love to have a Result in Zig with the Some or None, and having nice payload attached to none, etc.
But you will loose try and catch. The challenge is to retain Zig’s excellent error propagating ergonomics while carrying error context (payload) upstack.
I know but to be honest I’d like to have also an error type which can carry payload too, wouldn’t be nice to return the exact values of the inputs that were passed to your functions and failed ? or have at least a more descriptive message. Even for checking inputs after a function returns, I’d really like to have a little switch or if payload capture on some and none, or ok and err or something similar.
This is what you do manually yourself. Zig does not support error payloads but you can mimic it if, by convention, you define your functions with an extra argument (a mutable pointer) to error context. In this case try works as expected and the caller can inspect err_ctx together with err. It is a workaround.
I think what @dee0xeed is saying is that you cannot use try foo() catch ... – this does not exist in Zig. You either do try foo() or foo() catch |err| ....
What I am saying is that the function that generates the error puts some payload in err_cxt via catch, then the error propagates up-stack over (multiple) try and finally being handled in main by another catch.
This technique is described in Allow returning a value with an error · Issue #2647 · ziglang/zig · GitHub as the “wordaround 2: Out parameter”. It is not perfect, quite ugly but better than nothing.
EDIT: Just found a well written article describing advanced version of the OUT-parameter technique on zig.news
You either catch or try but not both in the same statement.
foo(a,b, &err_ctx) catch |err| {
err_ctx.* = error_payload_you_want_to_store;
return err;
}
```
Then you can use `try` in the caller `bar(x,y,&err_ctx)` to bubble up-stack and finally catch it where you want to handle it. The "ugliness" of this method is that you either modify signature of all the error-prone functions to include an extra `err_ctx` argument or keep `err_ctx` object global.
My point is that it is possible to deal with error payloads in Zig even without proper language support. It is just a bit ugly and non-ergonomic.