Live data from Hacker News

Thoughts on Go vs. Rust vs. Zig

sinclairtarget.com

331–340 of 599 posts

Re: Thoughts on Go vs. Rust vs. Zig

#331
post #214
post #29

> In Rust, creating a mutable global variable is so hard that there are long forum discussions on how to do it. In Zig, you can just create one, no problem. Well, no, creating a mutable global variable is trivial in Rust, it just requires either `unsafe` or using a smart pointer that provides synchronization. That's because Rust programs are re-entrant by default, because Rust provides compile-time thread-safety. If…

> [...] is trivial in Rust [...] it just requires [...] This is a tombstone-quality statement. It's the same framing people tossed around about C++ and Perl and Haskell (also Prolog back in the day). And it's true, insofar as it goes. But languages where "trivial" things "just require" rapidly become "not so trivial" in the aggregate. And Rust has jumped that particular shark. It will never be trivial, period.

> Rust has jumped that particular shark. It will never be trivial, period.

Maybe, but the language being hard in aggregate is very different from the quoted claim that this specific thing is hard.

Re: Thoughts on Go vs. Rust vs. Zig

#332

Earlier quoted context omitted.

I am quite certain that someone who has been on HN as long as you have is capable of understanding the difference between 0% compiler-enforced memory safety in a language with very weak type safety guarantees and 95%+ of code regions even in the worst case of low-level driver code that performs DMA with strong type safety guarantees.

Please explain the differences in typical aliasing rules between C and Rust. And please explain posts like https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/ https://news.ycombinator.com/item?id=41947921 https://lucumr.pocoo.org/2022/1/30/unsafe-rust/

Is three random people saying unsafe Rust is hard supposed to make us forget about C’s legendary problems with UB, nil pointers, memory management bugs, and staggering number of CVEs?

You have zero sense of perspective. Even if we accept the premise that unsafe Rust is harder than C (which frankly is ludicrous on the face of it) we’re talking about a tiny fraction of the overall code of Rust programs in the wild. You have to pay careful attention to C’s issues virtually every single line of code.

With all due respect this may be the singular dumbest argument I’ve ever had the displeasure of participating in on Hacker News.

Re: Thoughts on Go vs. Rust vs. Zig

#333
post #93

Earlier quoted context omitted.

> No more praying that your program isn't unceremoniously killed just for asking for more memory - all allocations are assumed fallible and failures must be handled explicitly. But for operating systems with overcommit, including Linux, you won't ever see the act of allocation fail, which is the whole point. All the language-level ceremony in the world won't save you.

> you won't ever see the act of allocation fail ever? If you have limited RAM and limited storage on a small linux SBC, where does it put your memory?

It handles OOM by killing processes.

Re: Thoughts on Go vs. Rust vs. Zig

#334
post #29

> In Rust, creating a mutable global variable is so hard that there are long forum discussions on how to do it. In Zig, you can just create one, no problem. Well, no, creating a mutable global variable is trivial in Rust, it just requires either `unsafe` or using a smart pointer that provides synchronization. That's because Rust programs are re-entrant by default, because Rust provides compile-time thread-safety. If…

If I created a new programming language I would just outright prohibit mutable global variables. They are pure pure pure evil. I can not count how many times I have been pulled in to debug some gnarly crash and the result was, inevitably, a mutable global variable.

Not really possible in a systems level programming language like rust/zig/C. There really is only one address space for the process... and if you have the ability to manipulate it you have global variables.

There's lots of interest things you could do with a rust like (in terms of correctness properties) high level language, and getting rid of global variables might be one of them (though I can see arguments in both directions). Hopefully someone makes a good one some day.

Re: Thoughts on Go vs. Rust vs. Zig

#335

Earlier quoted context omitted.

I am quite certain that someone who has been on HN as long as you have is capable of understanding the difference between 0% compiler-enforced memory safety in a language with very weak type safety guarantees and 95%+ of code regions even in the worst case of low-level driver code that performs DMA with strong type safety guarantees.

Please explain the differences in typical aliasing rules between C and Rust. And please explain posts like https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/ https://news.ycombinator.com/item?id=41947921 https://lucumr.pocoo.org/2022/1/30/unsafe-rust/

You phrase that as if 0-5% of a program being harder to write disqualifies all the benefits of isolating memory safety bugs to that 0-5%. It doesn't.

Re: Thoughts on Go vs. Rust vs. Zig

#336

Earlier quoted context omitted.

Pretty hard to do arena allocation in Java without JVM primitive support.

Not sure what you mean by "primitive support". Java 22 added FFM (Foreign Function & Memory). It works w/ both on-heap & off-heap memory. It has an Arena interface. https://openjdk.org/jeps/454 https://docs.oracle.com/en/java/javase/25/docs/api/java.base...

So, one year ago? After more than 25 years without it?

And a lot of people writing Java can't update to that.

Re: Thoughts on Go vs. Rust vs. Zig

#337
post #218
post #183

Earlier quoted context omitted.

It's enough information if you are happy to have a fragile API, but why would you purposefully make life difficult not only for yourself, but the developers who have their code break every time you decide to change something that should only be an internal implementation detail? Look, if you're just writing a script that doesn't care about failure — where when something goes wrong you can exit and let the end user de…

That makes even less sense becasue go errors provide even less info other then a chain of messages. They might as well be lists of strings. You can maybe reassbmle a call stack your self if all of the error handlers are vigalente about wrapping

They should have made the point about knowing where errors will happen.

The cherry on top is that you always have a place to add context, but it's not the main point.

In the Python example, anything can fail anywhere. Exceptions can be thrown from deep inside libraries inside libraries and there's no good way to write code that exhaustively handles errors ahead of time. Instead you get whack-a-mole at runtime.

In Go, at least you know where things will fail. It's the poor man's impl of error enumeration, but you at least have it. The error that lib.foo() returned might be the dumbest error in the world (it's the string "oops") but you know lib.foo() would error, and that's more information you have ahead of time than in Python.

In Rust or, idk, Elm, you can do something even better and unify all downstream errors into an exhaustive AGDT like RequestError = NetworkError(A | B | C) | StreamError(D | E) | ParseError(F | G) | FooError, where ABCDEFG are themselves downstream error types from underlying libraries/fns that the request function calls.

Now the callsite of `let result = request("example.com")` can have perfect foresight into all failures.

Re: Thoughts on Go vs. Rust vs. Zig

#338
post #222
post #214

Earlier quoted context omitted.

> [...] is trivial in Rust [...] it just requires [...] This is a tombstone-quality statement. It's the same framing people tossed around about C++ and Perl and Haskell (also Prolog back in the day). And it's true, insofar as it goes. But languages where "trivial" things "just require" rapidly become "not so trivial" in the aggregate. And Rust has jumped that particular shark. It will never be trivial, period.

> languages where "trivial" things "just require" rapidly become "not so trivial" in the aggregate Sure. And in C and Zig, it's "trivial" to make a global mutable variable, it "just requires" you to flawlessly uphold memory access invariants manually across all possible concurrent states of your program. Stop beating around the bush. Rust is just easier than nearly any other language for writing concurrent programs,…

[dead]

Re: Thoughts on Go vs. Rust vs. Zig

#339

Earlier quoted context omitted.

If I created a new programming language I would just outright prohibit mutable global variables. They are pure pure pure evil. I can not count how many times I have been pulled in to debug some gnarly crash and the result was, inevitably, a mutable global variable.

You need to be pragmatic and practical. Extra large codebases have controllers/managers that must be accessible by many modules. A single global vs dozens of local references to said “global” makes code less practical.

There was an interesting proposal in the rust world to try and handle that with a form of implicit context arguments... I don't have time to track down all the various blogposts about it right now but I think this was the first one/this comment thread will probably have links to most of it: https://internals.rust-lang.org/t/blog-post-contexts-and-cap...

Anyways, I think there are probably better solutions to the problem than globals, we just haven't seen a language quite solve it yet.

Re: Thoughts on Go vs. Rust vs. Zig

#340
post #182

Earlier quoted context omitted.

If we can produce a substantial volume of software that can cope with allocation failures then the idea of using something than overcommit as the default becomes feasible. It's not a stretch to imagine that a different namespace might want different semantics e.g. to allow a container to opt out of overcommit. It is hard to justify the effort required to enable this unless it'll be useful for more than a tiny handful…

> If we can produce a substantial volume of software that can cope with allocation failures then the idea of using something than overcommit as the default becomes feasible. Except this won't happen, because "cope with allocation failure" is not something that 99.9% of programs could even hope to do. Let's say that you're writing a program that allocates. You allocate, and check the result. It's a failure. What do yo…

I used to run into allocation limits in opera all the time. Usually what happened was a failure to allocate a big chunk of memory for rendering or image decompression purposes, and if that happens you can give up on rendering the current tab for the moment. It was very resilient to those errors.
Post reply on HN