Live data from Hacker News

Zig; what I think after months of using it

strongly-typed-thoughts.net

91–100 of 181 posts

Re: Zig; what I think after months of using it

#91

Earlier quoted context omitted.

I'm normally not sympathetic to the "you don't need that" argument, but there is a much stronger argument for not having arbitrarily-sized integers in Rust: the fact that values of such types can't have an address. The reason why our types all have bit sizes measured in octets is that a byte is the minimum granularity for a pointer.

A byte isn't the minimum granularity for a pointer. The minimum is based on whatever target you're compiling for. If it's a 32-bit target platform, then the minimum granularity is 4 bytes. Why should pointer size determine value size though? It's super fast to shift bits around, too, when needed.

> If it's a 32-bit target platform, then the minimum granularity is 4 bytes.

Huh? How do you think `const char *s = "Hello"; const char *t = &s[1];` works?

> Why should pointer size determine value size though?

Because you should be able to take the address of any value, and addresses have byte granularity.

Re: Zig; what I think after months of using it

#92
post #86

Earlier quoted context omitted.

> Replacing the value of one variable constantly throughout the code could lead to unpredictable bugs. Having variables with scopes that last longer than they're actually used and with names that are overly long and verbose leads to unpredictable bugs, too, when people misuse the variables in the wrong context later. When I have `initial_foo`, `foo_feature_a`, and `foo_feature_b`, I have to read the entire code caref…

It’s a trade-off. If you allow shadowing, then you rule out the possibility of the value being used later. This prevents accidental use (later on, in a location you didn't intend to use it) and helps readability by reducing the number of variables you must keep track of at once. If you ban shadowing, then you rule out the possibility of the same name referring to different things in the same scope. This prevents acci…

And on the whole, I prefer shadowing. I’ve never had a bug in either direction, but keeping everything immutable without shadowing means you spend all your brain power Naming Things.

Re: Zig; what I think after months of using it

#93

Earlier quoted context omitted.

Unsafe Rust is problematic: https://zackoverflow.dev/writing/unsafe-rust-vs-zig See also: https://github.com/roc-lang/roc/blob/main/www/content/faq.md... Zig is not entirely unsafe. It provides quite a few compile time checks and primitives to catch memory leaks or prevent them altogether.

> It provides quite a few compile time checks and primitives to catch memory leaks or prevent them altogether. From what I've seen, clang has all of these and more for C++. If your metric is "tooling to help you catch UB", C++ is significantly superior to Zig.

Zig has a C and C++ compiler built into it and works seamlessly with it. Several C/C++ projects use Zig as a build tool. Zig makes different trade-offs with C++ from a language design standpoint. C++ has a lot more footguns to create UB in the first place.

Re: Zig; what I think after months of using it

#94
post #53

Earlier quoted context omitted.

What they're trying to convey is that errors are structurally typed. If you declare: const MyError = error{Foo} in one library and: const TheirError = error{Foo} in another library, these types are considered equal. Unlike structs/unions/enums which are nominal in zig, like most languages. The reason for this, and the reason that errors are not regular records, is to allow type inference to union and subtract error t…

if you need values associated with your error you can stash them in an in-out parameter

If I have multiple errors then that in-out parameter has to be a union(enum). And then I'm back to creating dozens of slightly different unions for functions which return slightly different sets of errors. Which is the same problem I have in rust. All of the nice inference that zig does doesn't apply to my in-out parameter either. And the compiler won't check that every path that returns error.Foo always initializes error_info.Foo.

Re: Zig; what I think after months of using it

#95

Earlier quoted context omitted.

> It provides quite a few compile time checks and primitives to catch memory leaks or prevent them altogether. From what I've seen, clang has all of these and more for C++. If your metric is "tooling to help you catch UB", C++ is significantly superior to Zig.

Zig has a C and C++ compiler built into it and works seamlessly with it. Several C/C++ projects use Zig as a build tool. Zig makes different trade-offs with C++ from a language design standpoint. C++ has a lot more footguns to create UB in the first place.

> C++ has a lot more footguns to create UB in the first place.

I'd actually give the edge to C++ over Zig, because of smart pointers (not that I'm implying smart pointers are anywhere near sufficient).

Re: Zig; what I think after months of using it

#96
post #10

Great write-up, thank you! I used Zig for (most of) Advent Of Code last year, and while I did get up-to-speed on it faster than I did with Rust the previous year, I think that was just Second (low-level) Language syndrome. Having experienced it, I'm glad that I did (learning how cumbersome memory management is makes me glad that every other language I've used abstracts it away!), but if I had to pick a single low-lev…

As a systems programmer, Rust has won. It will take decades before there is substantial Rust replacing the absurd amounts of C that runs on any modern Unix system, but I do believe that our of all the replacements for C/C++, Rust has finally gained the traction most of them have lacked at the large companies that put resources behind these types of rewrites and exploratory projects. I do not think Zig will see wide a…

Zig might not become very popular, but IMO, it will become more popular than Rust. Zig is good at all the areas Rust is good at. Zig is also good at game development which Rust is not good at.

And Zig is better when integrating with C/C++ libraries.

Re: Zig; what I think after months of using it

#97

Earlier quoted context omitted.

Over the years, I’ve wasted 1-2 days of my life debugging bugs caused by unintentional variable shadowing in Go (yes, I’ve kept track). Often, the bug is caused by an accidental use of := instead of =. I don’t understand why code that relies on shadowing isn’t harder to follow. Wish I could disable it entirely.

You can (assuming you're talking about Rust)! Just use Clippy and add #[deny(clippy::shadow_reuse)]: https://rust-lang.github.io/rust-clippy/master/#shadow_reuse My position on shadowing is that it's a thing where different projects can have different opinions, and that's fine. There are good arguments for allowing shadowing, and there are good arguments for disallowing it.

This is another big difference between Rust and Zig. Rust lets you have it both ways with configuration. Zig places much more value on being able to read and understand any Zig code in the wild, based only on “it compiles”. Rust’s “it compiles” gives you lots of information about safety (modulo unsafe blocks), but very little about certain other things until you’ve examined the 4-5 places which might be tweaking configuration (#[attributes], various toml files, environment variables, command line flags).

Re: Zig; what I think after months of using it

#98

Earlier quoted context omitted.

There it says "errors are values" so now that contradicts what OP said.

I said I wasn't speaking for Zig specifically, just on general principle that errors are not really values. Many languages reify errors as values to avoid having different semantics for errors, but errors probably should have their own semantics. Zig seems to take a middle ground here, where errors are a special type of value but that still sort of has its own semantics.

> I said I wasn't speaking for Zig specifically

Lol, you are right. My brain just skipped that part somehow.

Re: Zig; what I think after months of using it

#99
post #89

Earlier quoted context omitted.

Rust has very real limitations and trade-offs. It compiles slow and the binaries are large. The compiler also makes performance sacrifices that makes it generally slower than C. I'm sure the language will continue to be successful, but it hasn't "won".

Why do you say slower than C? I’ve never seen a reason to believe they’re anything but roughly equivalent.

The last I heard, Rust had issues with freeing memory when it wouldn't need to, particularly with short-lived processes (like terminal programs) where the the Rust program would be freeing everything while the C version would just exit out and let the operating system do cleanup.

Re: Zig; what I think after months of using it

#100

Earlier quoted context omitted.

yes but by the time you're using miri, why not just run zig with a separate static checker that does all the memory safety parts? https://github.com/ityonemo/clr

For one, it doesn't do all the "memory safety parts", according to the readme. I'm very skeptical that Zig can be made memory safe with a checker while still remaining compatible with existing code. Certainly neither C nor C++ can, and Zig isn't meaningfully different in expressivity (if anything, it's more expressive, which is the opposite of what you want).

FTrepo:

Q: You didn't do X, so Zig will never be able to track X

A: Maybe. Only way to know for sure is to fork this (or, hopefully, a 'real' successor) and fail. However, consider that "trivially" it should be possible to externally annotate every zig file with lifetime/type annotations identical to that of Rust and run "exactly the same" analysis as Rust and get the same memory safety as Rust.

it appears the clr author anticipated you: you didnt fork it, try, and fail, so you have ceded the authority to credibly make your speculative complaint

> Zig isn't meaningfully different in expressivity

it is meaningfully different in expressivity at the AIR level. AIR looks nothing like c, c++, zig, or rust.

Post reply on HN