4 ms·
In Zig: const ComplexType = union(enum) { Ok: u8, NotOk, }; It's recommended to use destructuring syntax to unpack it, but you have th
by AndyKelley 8y ago
In Zig:
const ComplexType = union(enum) {
Ok: u8,
NotOk,
};
It's recommended to use destructuring syntax to unpack it, but you have the option to use fields directly which invokes runtime safety checks.
This matches the syntax for normal unions, which do not have tags, but still have runtime safety checks. Rust does not have this feature - unions must always have tags - where as in Zig the state that determines which tag is active in a union could be somewhere else.
> What would happen if I wanted to be able to print a custom type for instance?
const std = @import("std");
pub fn main() void {
const ComplexType = union(enum) {
Ok: u8,
NotOk,
};
var ct = ComplexType { .Ok = 123 };
std.debug.warn("{}\n", ct);
ct = ComplexType.NotOk;
std.debug.warn("{}\n", ct);
}
Outputs:
ComplexType{ .Ok = 123 }
ComplexType{ .NotOk = void }
This is all implemented in userland in the standard library. Last time I checked, in Rust the equivalent code is implemented with a macro hard coded in the compiler.
> why are things like "@clz" or "@intToFloat" compiler builtins, surely they could be implemented as part of the stdlib using a generic method?
They could be implemented in userland, but then they would possibly not lower to the LLVM primitives that they represent. In the case of the casting functions, it's more to do with semantics of the language, making it hard to accidentally shoot yourself in the foot. Shooting yourself in the foot on purpose, however, is always allowed.
- simias 8y ago>This is all implemented in userland in the standard library. Last time I checked, in Rust the equivalent code is implemented with a macro hard coded in the compiler. You're right and it's still the case as far as I know but I was thinking more about having a customized output, in Rust you can implement the Display interface and completely customize the way the object is serialized for output. Your sibling comment by AnIdiotOnTheNet shows how to do just that but is it done purely in stdlib or is it actually implementable in the language itself? If it is actually doable in pure Zig I'd recommend showcasing that as part of the "generics" docs because as it is it's a bit odd to have example code that ends up exhaustively matching possible types, it kinds of defeat the purpose of generics and is the cause of my confusion. Thank you for your answers by the way, they're appreciated. I'm very happy to see all this experimentation around low level "light runtime" languages lately, it's definitely sorely needed. I hope that 20 years from now C won't still be the alpha and omega of low level code.
- AnIdiotOnTheNet 8y agoThe standard lib has no special privileges, it's written entirely using the same language features available to everyone. There are probably 2 reasons the documentation uses a simplified example: 1) the ability to introspect a type for the presence of a field or definition before attempting to use it is relatively new 2) the actual implementation of fmt.format is rather long and involved
- CUViper 8y ago> The standard lib has no special privileges, it's written entirely using the same language features available to everyone. Sort of -- it uses a lot of unstable features that are only available to outsiders with the nightly compiler.
- steveklabnik 8y agoYour parent is talking about Zig, not Rust, I believe.
- CUViper 8y agoAh, ok. I suppose that's still a useful thing to say about Rust std though. :)
- bendmorris 8y ago>Rust does not have this feature - unions must always have tags Rust has had untagged unions since last year (https://blog.rust-lang.org/2017/07/20/Rust-1.19.html https://blog.rust-lang.org/2017/07/20/Rust-1.19.html)