Live data from Hacker News

Zig and Rust

matklad.github.io

41–50 of 247 posts

Re: Zig and Rust

#41

I tried zig after reading so many HN articles and I am not impressed. You have to remember to free after each allocation. The language is supposed to be simple, yet there exist try, catch, defer, errdefer. Rust enums make defining errors so simple with arbitrary payload. Using data structures in rust is much nicer. I think unless you have some precise needs about memory allocation, and want to control exactly where w…

> I think unless you have some precise needs about memory allocation, and want to control exactly where when and how memory is allocated, it is hard to argue in favour of Zig. I do have a hard time to think of use cases other than embedded microcontroller work where that matters nowadays. That said, I suspect that while they could have written TigerBeetle in Rust (no_std does not assume the existence of an allocator)…

> I do have a hard time to think of use cases other than embedded microcontroller work where that matters nowadays.

Another example: realtime audio applications. There are rather strict rules about what you can and cannot do in the audio callback. In particular, you must not use the system memory allocator (because it may block). Instead you have to pre-allocate memory or use real-time safe memory pools. For this reason, the vast majority of (realtime) audio code is still written in C and C++.

Re: Zig and Rust

#42

The only advantage Zig has is its ability to consume C/C++ as it ships with clang That's about it, the language is too verbose and sometimes not enough verbose with all these .{} you need to always look at the documentation to remember what this does, this is time consuming and does useless context switches Last time i tried to build their language server to use in my editor, and i was surprised it took an eternity t…

I tend to agree with most of your remarks.

Zig would clearly be a better choice than Rust to replace C.

Zig is also better than C in some ways, but worse in others, this is frustrating.

The trick is that most of the good parts are either transient QoL improvements (such as the build system) or guard rails to avoid costly mistakes (no macros, explicit memory management) but the drawbacks (annoying syntax, peculiarities, probably trying to do too much) seems to be long-lasting daily annoyances.

I am waiting for 1.0 and also for Jai.

Re: Zig and Rust

#43
post #34
post #13

This title is almost perfectly designed to do well on HN, but it's definitely worth reading in it's entirety. Some highlights for me: - The author sees Rust and Zig in different niches. When Rust was created it didn't need to specialise because there were no languages like Rust. It was free to be a general purpose language targeting multiple domains. But that's not the case for Zig. He sees Zig shining at writing sys…

> I remember reading his original proposal for why Rust should ditch their existing LSP effort (called Rust Language Server) and start afresh with a completely new. And he was 100% right. Where can I read more about this? What ended up happening?

https://blog.rust-lang.org/2022/07/01/RLS-deprecation.html was the announcement of the replacement, and talks about it a little bit:

> RLS was introduced by RFC 1317 and development was very active from 2016 through 2019. However, the architecture of RLS has several limitations that can make it difficult to provide low-latency and high-quality responses needed for an interactive environment.

> rust-analyzer uses a fundamentally different approach that does not rely on using rustc. In RFC 2912 rust-analyzer was adopted as the official replacement for RLS.

These RFCs provide some more color.

The long and short of it is, the RLS relied on a process where rustc would sort of pre-process your codebase, and spit out a "save analysis" file. RLS would read this file, and do its thing. rust-analyzer, on the other hand, doesn't use rustc at all(*), and instead analyzes your code on-demand, in an incremental style. The latter has many advantages in an IDE context.

The * is there because part of the original idea is that rustc would end up producing some libraries that rust-analyzer would also use, allowing them to share code. Given that rustc has also been moving towards an incremental, on-demand architecture, this would be easier. I am out of the loop these days, but from the relative outside, this effort seemed to stall out. I don't really know why. Maybe it has been happening and just isn't really visible.

Regardless of those details, rust-analyzer is very good. It's a shame the transition took so long, in retrospect!

Re: Zig and Rust

#44
> First, I think Zig’s strength lies strictly in the realm of writing “perfect” systems software. It is a relatively thin slice of the market, but it is important.

This resonates with me. This is exactly why I use C today, and why Zig appeals to me.

Re: Zig and Rust

#45
post #7

Earlier quoted context omitted.

can you elaborate why

Not the parent, but Zig being much easier to use unsafely is not a good thing IMO. Rust tries to pave a path for all types of developers to eventually learn how to write performant code safely in a way that integrates cleanly. This is a much more practical need for the programming community at this time. I have to agree with the parent - I was interested in looking at Zig eventually, but after reading this I am not.…

the assumption with Rust is that memory safety (or, generally, resource provenance) is something that needs to exist in the type system. Zig is still young, so i would say it's not 100% certain that this shouldn't exist, for example, in a separate step, for example using static analysis.

Rust is already bumping into important cases where the typesystem is incapable of resolving things that "you might want its typesystem to track", and support for these would require breaking all of rust.

Before you say, "static analysis is impossible" -- that's very likely generically true for C (something like Sel4 is in C but gives even stronger guarantees than rust, but IIRC it analyzes machine code). It might not necessarily be. In extremis you could in principle attach a separate file that provides rust function headers for every single function in zig, and checks resource lifetimes inside of each function. So it is not theoretically impossible, just a question of whether or not it's ergonomic and easily accessible.

Re: Zig and Rust

#46

May someone chime in between that and make a quick 3-way comparison with Golang? I already know Rust and shipped nontrivial stuff, but I need something simpler that average developers can pickup quickly to produce performant+parallel code and be able to crosscompile+ship a single binary. (The last point already ruled out Crystal which has a poor crosscompilation story as well as insanely long compile times for nontri…

The main topic of the article is about resource management (ie. allocation), which is automatic in Golang, so a comparison wouldn't make much sense in this context.

Additionally, a requirement of the project is:

> On the engineering side of things, we are building a reliable, predictable system. And predictable means really predictable. Rather than reigning in sources of non-determinism, we build the whole system from the ground up from a set of fully deterministic, hand crafted components.

which rules out garbage collected languages (also see the design document here: https://github.com/tigerbeetledb/tigerbeetle/blob/fe09404d46...).

Re: Zig and Rust

#47

Earlier quoted context omitted.

Nothing is breaking! The change isn't a move to a zig-like style, but instead, that in today's Rust, you have struct Foo { // ... } and not struct Foo { // ... } This isn't breaking because there is a default type provided for A. The handwave is over "Today's Rust", as this machinery has already landed, in a sense, it's just not really possible to use with the standard library because the allocator API isn't fully st…

I see. I'm interested in the motivation and design goals behind it, is there something that spells those out? The only thing I could find quickly is this [0]. [0] https://internals.rust-lang.org/t/why-bring-your-own-allocat...

https://rust-lang.github.io/rfcs/1974-global-allocators.html was the original RFC.

My vague understanding is that there's a working group https://github.com/rust-lang/wg-allocators

The further I get from working on Rust day to day, the less I know about these things, so that's all I've got for you.

Re: Zig and Rust

#48
post #34
post #13

This title is almost perfectly designed to do well on HN, but it's definitely worth reading in it's entirety. Some highlights for me: - The author sees Rust and Zig in different niches. When Rust was created it didn't need to specialise because there were no languages like Rust. It was free to be a general purpose language targeting multiple domains. But that's not the case for Zig. He sees Zig shining at writing sys…

> I remember reading his original proposal for why Rust should ditch their existing LSP effort (called Rust Language Server) and start afresh with a completely new. And he was 100% right. Where can I read more about this? What ended up happening?

I can't find the original link to his proposal, but I did send him a message on reddit asking if still had a link to it.

The gist of it was, he felt the first attempt to make a Rust LSP (RLS) had the wrong architecture. It was basically running the Rust compiler in check mode and relaying the errors back. In his opinion an IDE needed a different, incremental architecture that stored state. It also needed to be much more tolerant of errors.

He had already made a Rust IDE plugin in Java for JetBrain's IntelliJ-Rust plugin, and wanted to make a similar one in Rust.

So he started the rust-analyzer project and it succeeded. Last year it became the official LSP of the Rust project. (https://blog.rust-lang.org/2022/02/21/rust-analyzer-joins-ru...)

Re: Zig and Rust

#49
post #33

Earlier quoted context omitted.

Psuedo-Rust code here, showing off both styles. Parameterized by an allocator: struct Foo { // ... } impl Foo { fn new() -> Foo { // do something to make a new foo, calling functions via A } } contrast with "an allocator is passed in explicitly to every method which actually needs to allocate." struct Foo { // ... } impl Foo { fn new (a: A) -> Foo { // do something to make a new foo, calling functions via A } } (EDIT…

I suppose the distinction you're suggesting here is that in the Zig-like example, two `Foo ` can have the same type and different allocators. Author mostly notes that this is more flexible. I can see it being possible in each case to have the system be parametric in the allocator, though it'll be a lot more annoying in Rust give the need to pipe the types around. Something between that noisiness and the global defaul…

Ah you are right, choosing "new" was a poor choice for my example. I didn't even realize that implied something slightly different until you made this comment, I'm going to update mine slightly to point this out, thank you.

Re: Zig and Rust

#50

Still not convinced that memory semantics are critical in the vast majority of domains. Incredibly fast speeds can be achieved with simple GC and RC for short-running programs, and programs with sustained runtimes can rely on generational GC. These methods have the advantage of nearly eliminating the need for memory semantics, leaving only business logic behind. The best example might be Nim, which drastically reduce…

You can get the idea that a GC has minimal impact on performance when you just look at things like how fast the GC runs, or what % of time is spent in GC, but that only represents a portion of performance implications, there are lots of indirect effects:

1. More memory is used, which means more CPU cache evictions happen 2. There will be things the language won't let you do, because it is garbage collected 3. There will be extra FFI costs, like when making OS calls or calling into other languages 4. There will be cultural tendencies, if a language uses GC, the people who designed it and used it are less likely to be interested in compromising other things for extreme performance. Example: If a linq query has overhead in C#, and they have to make a breaking change to eliminate it, they will not. In Rust if an iterator is slower than what hand coded C would be, its a bug, and every effort will be made to fix it if possible.

That said, it is still the case that most programs aren't penalized by GC much. But people do still work on operating systems, games, databases, video editing tools and such where getting great performance is really important.

Post reply on HN