Live data from Hacker News

Failing to Learn Zig via Advent of Code

forrestthewoods.com

241–250 of 338 posts

Re: Failing to Learn Zig via Advent of Code

#241
post #79
post #24

I like zig, but agree with many of the points here. A couple of thoughts below, > Zig reference documentation badly needs examples. Can't figure out how to use std.fmt.parseInt. While yes, Zig documentation badly needs examples, I'm not sure this particular criticism is justified. I would have thought that the usage of parseInt, was fairly obvious from the type-signature: parseInt(comptime T: type, buf: []const u8, r…

> ArrayList explicitly manages a contiguous region of memory, so I don't see the problem with exposing it as a slice as part of the interface. It used to be that you'd get an allocator by taking a pointer to the allocator field (&gpa.allocator), in 0.9.0 that was changed to a function call (gpa.allocator()) and thus broke _a lot_ of things. Exposing all these fields seems like it'll cause challenges when trying balan…

> Exposing all these fields seems like it'll cause challenges when trying balance backwards compatibility vs breaking changes.

That's less important than it sounds because the project is pretty explicit about not caring about backward compatibility till 1.0.

Re: Failing to Learn Zig via Advent of Code

#242
post #136

The author is not excited about "No hidden control flow", but as a code reader it's really nice. It means that the only context you need in order to understand the control flow of a given line of code is that line itself. You don't need to check for overloaded operators, exceptions, virtual functions, etc. It's this property of Zig that I think makes "read the stdlib source" actually a viable strategy for learning ho…

What did you think of the example in the article about vector math? Seems like that's an area where operator overloading actually makes the code more readable. Maybe it depends on the problem domain you're working in.

Zig is fairly low-level. GPU compute kernels are already defined as stringly typed things that get thrown into an additional non-Zig compilation step; I don't know that I'd feel too badly about somebody having to write a tensor DSL that Zig could interpret at compile time.

Do you have any examples of situations where people would be writing a lot of code with custom operators where each individual block is pretty small and having to deal with a DSL of some flavor would be especially burdensome?

Re: Failing to Learn Zig via Advent of Code

#243
post #224
post #171

Earlier quoted context omitted.

It's an open question [1] along with other safety checks both comptime and runtime [2]. The issue here is a balance of keeping language complexity low while providing safety at the same time and not depriving users of control when they know better than the type checker/lifetime analysis. [1]: https://github.com/ziglang/zig/issues/782 [2]: https://github.com/ziglang/zig/issues/2301

> not depriving users of control when they know better than the type checker/lifetime analysis. You're never deprived of control though, that's what unsafe is for, and it provides roughly the same level of safety as C or Zig would.

unsafe Rust has its own UB pitfalls that don't exist in C nor Zig, particularly in regards to the lifetimes of references [0] and preserving provenance through experimental apis [1].

[0]: the compiler is allowed to emit extra reads/writes to references so a mut and shared one to the same memory location cant be alive at the same time, across threads, and across sometimes non-obvious scoping rules.

[1]: [pointer::set_ptr_value](https://doc.rust-lang.org/std/primitive.pointer.html#method....) is used by containers like Arc for `from_raw` in order to carry over aliasing, mutability, and other location meta data.

unsafe Rust is also less ergonomic when dealing with concepts that go against the borrow checker like Pinning for intrusive memory, ptr::read/write and ManuallyDrop for controlling unorthodox object ownership/lifetime, and MaybeUninit/NonNull for facilitating certain data layout/access optimizations. Such designs often can't be wrapped in safe-Rust without introducing runtime overhead the patterns were used to originally avoid. Languages like Zig and C however make these patterns natural or event pleasant enough to consider it over unsafe Rust.

Re: Failing to Learn Zig via Advent of Code

#244

Zig is a very low level language. I think the fancy type system can trip up people into thinking they are working with a high-level language. Zig is basically C with a fancy type system, so you should not expect things like special String types, overloading of index based access etc. I think the author was thinking that Zig was very close to Rust or C++, when in reality it is much closer to C. I had to keep reminding…

I still can't figure out how Zig proposes to prevent undefined behavior without a borrow checker (aka MLKit regions) or GC.

AFAICT the answer is "inject as many runtime checks as needed" although the docs seem to go way out of their way to avoid making this explicit.... or deal with the fact that these checks are now runtime failures rather than compile-time failures, and therefore need code to handle them.

It seems like it would be the same as writing Rust code using std::cell instead of references, except that Rust would force you to insert handlers for all the new failure modes this would create (of course you could just panic!(), but at least the compiler would force you to insert those panics...).

Re: Failing to Learn Zig via Advent of Code

#245
post #152

To me the biggest difference between Rust and Zig in practical terms is that Zig does not offer statically safe resource management like Rust does, and as far as I know they have no intentions of doing so in the future because they think it’s less important than all this stuff about control flow. There are a lot of interesting ideas in the language but my disagreement with them on this issue is so fundamental that I…

I feel like Nim is a much closer comparison than Rust. All three could be described as "grassroots projects on a holy mission to replace C and/or C++," but Nim and Zig are more similar in terms of operating budget/team size/adoption rate. I may be a bit biased, but many of the problems mentioned in the post are the sorts of things I haven't dealt with in Nim for probably 2 years. Nim's error messages are still hit-or…

Rust isn't on a holy mission; it's simply the only memory-safe language without a garbage collector.

It's really that simple. There is no international conspiracy behind Rust's popularity. It's the only thing that can do what it does in that respect.

Re: Failing to Learn Zig via Advent of Code

#246
post #171
post #152

To me the biggest difference between Rust and Zig in practical terms is that Zig does not offer statically safe resource management like Rust does, and as far as I know they have no intentions of doing so in the future because they think it’s less important than all this stuff about control flow. There are a lot of interesting ideas in the language but my disagreement with them on this issue is so fundamental that I…

It's an open question [1] along with other safety checks both comptime and runtime [2]. The issue here is a balance of keeping language complexity low while providing safety at the same time and not depriving users of control when they know better than the type checker/lifetime analysis. [1]: https://github.com/ziglang/zig/issues/782 [2]: https://github.com/ziglang/zig/issues/2301

This is such a squishy value proposition, which is why people aren't taking Zig seriously.

Rust's value proposition is simple: no GC and no undefined behavior. Period. Nothing else has that.

Re: Failing to Learn Zig via Advent of Code

#247
post #152

To me the biggest difference between Rust and Zig in practical terms is that Zig does not offer statically safe resource management like Rust does, and as far as I know they have no intentions of doing so in the future because they think it’s less important than all this stuff about control flow. There are a lot of interesting ideas in the language but my disagreement with them on this issue is so fundamental that I…

There is nothing fundamental about ownership-based resource management, memory-safety can be achieved in other ways. Zig is C, it's not meant to abstract away memory management. You can do whatever in Zig, write a specialized allocator that's verified to be correct, even for a microcontroller with 2 KiB memory. Zig is a machine-oriented language, which means no hidden control flow, no hidden allocation. You can write…

> nothing fundamental about ownership-based resource management, memory-safety can be achieved in other ways.

Not other ways. One other way. Just one. Garbage collection.

Re: Failing to Learn Zig via Advent of Code

#248
When I saw

> I try to keep my C++ simple and somewhat C-like.

... I knew this would not be very informative.

On one hand, the author's failure to take advantage of the power C++ offers means he will likely also fail to see how to use well what Zig does offer. (One doubts he makes any more effective use of Rust, another powerful language, than of C++.) At the same time, it should make him a better prospect to become a Zig user, not missing powerful features that could make him a more productive programmer.

But he is right that "no hidden control flow" is an anti-feature. What they call "hidden control flow" seems to be what we know of as destructors (or, in Rust, the Drop trait) that is about the only piece of programming automation invented in 40 years.

One might as well dispense with running water and cooked food.

Re: Failing to Learn Zig via Advent of Code

#249
post #248

When I saw > I try to keep my C++ simple and somewhat C-like. ... I knew this would not be very informative. On one hand, the author's failure to take advantage of the power C++ offers means he will likely also fail to see how to use well what Zig does offer. (One doubts he makes any more effective use of Rust, another powerful language, than of C++.) At the same time, it should make him a better prospect to become a…

> But he is right that "no hidden control flow" is an anti-feature.

Hmmm, "no hidden control flow" is at least what I want writing distributed systems, storage engines or device drivers.

Calling it an "anti-feature" is dismissing important domains for system languages where control flow in the control plane needs to be explicitly visible, and where the necessity for things like static allocation and NASA's "The Power of 10: Rules for Developing Safety-Critical Code" mean that destructors during the lifetime of a system are an anti-pattern anyway.

Re: Failing to Learn Zig via Advent of Code

#250

Earlier quoted context omitted.

> Zig is basically C with a fancy type system, so you should not expect things like special String types, If I can't have nice strings, what should I be expecting from a fancy type system?

Zig's "fancy" (I don't think they're that fancy) type features that IMO make it a great C alternative are: - non-null pointers, and distinct types for single-item pointers and multi-item pointers (multi-item pointers are rarely used except indirectly via slices, so unchecked pointer arithmetic errors are largely banished) - builtin tagged unions (AKA algebraic data types) with very pleasant to use switch logic -- it…

Also Zig's memory alignment in the type system is great for doing low-level I/O.

Coming from C, I find that Zig's memory alignment options are easier and more powerful.

Post reply on HN