top | item 17186562

(no title)

tiehuis | 7 years ago

To elaborate on a few of your remarks/questions.

> At first glance, Rust's `enum` looks safer and more powerful than Zig's `union` + `enum`, while Zig's `union` + `enum` appears more interoperable with C.

A `union(TagType)` in Zig is a tagged union and has safety checks on all accesses in debug mode. It is directly comparable to a Rust enum. Any differences are probably more down to the ways you are expected to access them and Rust's stronger pattern matching probably helps some here.

> I don't see traits in Zig.

Nothing of the sort just yet although it is an open question [1]. Currently std uses function pointers a lot for interface-like code, and relies on some minimal boilerplate to be done by the implementor.

See the interface for a memory allocator here [2]. An implementation of an allocator is given here [3] and needs to get the parent pointer (field) in order to provide the implementation.

It isn't too bad once you are familiar with the pattern, but it's also not ideal, and I would like to see this improved.

> I don't see smart pointers in Zig, and more generally, I have no idea how to deallocate memory in Zig.

You would use a memory allocator as mentioned above and use the `create` and `destroy` functions for a single item, or `alloc` and `free` for an array of items. Memory allocation/deallocation doesn't exist at the language level.

> I don't see anything on concurrency in Zig's documentation.

There are coroutines built in to the language [4]. This is fairly recent and there isn't much documentation just yet unfortunately. Preliminary thread support is in the stdlib. I know Andrew wants to write an async web-server example set up multiplexing coroutines onto a thread-pool, as an example.

> Zig supports varargs, Rust doesn't (yet).

It's likely that varargs are instead replaced with tuples as a comptime tuple (length-variable) conveys the same information. I believe this fixes a few other quirks around varargs (such as using not being able to use varargs functions at comptime).

[1] https://github.com/ziglang/zig/issues/130

[2] https://github.com/ziglang/zig/blob/15302e84a45a04cfe94a8842...

[3] https://github.com/ziglang/zig/blob/15302e84a45a04cfe94a8842...

[4] https://github.com/ziglang/zig/blob/15302e84a45a04cfe94a8842...

discuss

order

Yoric|7 years ago

> A `union(TagType)` in Zig is a tagged union and has safety checks on all accesses in debug mode. It is directly comparable to a Rust enum. Any differences are probably more down to the ways you are expected to access them and Rust's stronger pattern matching probably helps some here.

But if I understand correctly, out-of-the-box, Zig's `union` doesn't get a tag type, right? That's what I meant by Rust's `enum` being safer: you can use it safely in Zig, but you have to actually request safety, because that's not the default behavior.

I probably should have phrased it differently, though.

And the "more powerful" is about the fact that a Rust enum can actually carry data, while it doesn't seem to be the case with Zig.

>> I don't see smart pointers in Zig, and more generally, I have no idea how to deallocate memory in Zig. > >You would use a memory allocator as mentioned above and use the `create` and `destroy` functions for a single item, or `alloc` and `free` for an array of items. Memory allocation/deallocation doesn't exist at the language level.

So, it sounds like deallocations are not checked by default, right?

> I know Andrew wants to write an async web-server example set up multiplexing coroutines onto a thread-pool, as an example.

That would be a nice example, for sure!

tiehuis|7 years ago

> But if I understand correctly, out-of-the-box, Zig's `union` doesn't get a tag type, right? That's what I meant by Rust's `enum` being safer: you can use it safely in Zig, but you have to actually request safety, because that's not the default behavior.

Sure. I think that's more an effect of the choice of keyword defaults here. A straight union is very uncommon and is typically solely for C interoperability.

> And the "more powerful" is about the fact that a Rust enum can actually carry data, while it doesn't seem to be the case with Zig.

A tagged union can store data as in Rust. See the examples in the documentation [1]. Admittedly Rust's pattern matching is nicer to work with here.

To summarise the concepts:

- `enum` is a straight enumeration with no payload. The backing tag type can be specified (e.g. enum(u2)).

- `union` is an unchecked sum type, similar to a c union without a tag field.

- `union(TagType)` is a sum type with a tag field, analagous to a Rust enum . A `union(enum)` is simply shorthand to infer the underlying TagType.

> So, it sounds like deallocations are not checked by default, right?

If referring to if objects are guaranteed to be deallocated when out of scope then no, this isn't checked. There are a few active issues regarding some improvements to resource management but it probably won't result in any automatic RAII-like functionality. This is a manual step using defer right now.

[1] https://ziglang.org/documentation/master/#union