5 ms·
I've been building a toy project in zig in the last couple weeks. Zig is incredible. After only a short while working with it, it feels like deserves the title
by donpdonp 8y ago
I've been building a toy project in zig in the last couple weeks. Zig is incredible. After only a short while working with it, it feels like deserves the title of a "better C". With no runtime overhead you get:
* Type inference - var name = "Bob";
* Maybe types (from Elm/Haskell) that prevent NULL ptr bugs and syntactic sugar encourages its use for function return values.
if (doit()) |result| {
// result is always a populated Struct
} else |err| {
// error is always a populated Error
}
// a return type of !Something means Error type or Something type
fn doit() !Struct {
}
* Nullable types - var ?&object = null; if you need it, and var &object = aObject; if you want the safety.
* Great C interop, though there is more work to be done here. (gtk.h for instance is too much for zig today) Zig's approach is unique here too. You specify .h files in the zig source code and the zig compiler translates C in the .h into zig. Its not a function bridge or wrapper, its zig objects and zig functions available to your zig code.
const c = @cImport({
@cInclude("curl/curl.h");
});
var curl = c.curl_easy_init();
if(curl != null) {
_ = c.curl_easy_setopt(curl, c.CURLoption(c.CURLOPT_URL), url_cstr.ptr);
...
* Standard library operations that allocate memory take an 'allocator object' parameter that should give great programmer control over memory management (I didnt get into this myself), webasm is a compiler target, and lots more
- dbaupp 8y agoI think you mean Result or Either like Haskell etc., not Maybe. Additionally, Swift has essentially the same approach to C FFI.
- MaxBarraclough 8y agoDo nullable types and maybe types add much over checked dereferences (a la Java)? I imagine they might be good for performance (fewer checks), but does it really help with correctness/convenience/elegance/readability/etc?
- Yoric 8y agoIn my experience from Rust & co, yep, this improves correctness a lot. Elegance, not so much.
- whyever 8y agoI think some of the combinators can be elegant. E.g. `Option::map`.
- zoul 8y agoSwift’s syntax sugar for Optionals makes working with nullable types much more elegant, too.
- Yoric 8y agoMy personal experience of Swift vs. Rust is that Swift's syntax sugar is more readable for most examples, but Rust lack of syntax sugar scales better to more exotic examples. YMMV
- nonsince 8y agoYes, because you get told about problems at compile-time rather than at runtime.
- MaxBarraclough 8y agoI think I get it now: use different types for nullable and non-nullable pointers. Only non-nullable pointers can be dereferenced, and the conversion from nullable to non-nullable must be done explicitly, with different flow in the case that the pointer turns out to be null (which is to say, a non-nullable pointer will never enter scope). Dereferencing null is impossible, and the programmer is forced to explicitly handle null values. This contrasts with C, where the same type is used for a nullable and a non-nullable pointer, so the compiler can't help out, the programmer is at risk of forgetting/failing to keep track of the difference between the two, and null-dereferences may occur (and give you undefined behaviour). Java references take the same approach as C pointers, except all dereferences are checked at runtime, and dereferencing null throws an exception. I like it! It does better than the Never null, only cromulent values approach (like C++ references), as this can be inconvenient in practice. It makes null-dereferences impossible, and doesn't do anything funky that would introduce needless runtime overhead.