6 ms·
> I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust: But you only need about 5% o
by deathanatos 11mo ago
> I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust:
But you only need about 5% of the concepts in that comment to be productive in Rust. I don't think I've ever needed to know about #[fundamental] in about 12 years or so of Rust…
> In both Go and Rust, allocating an object on the heap is as easy as returning a pointer to a struct from a function. The allocation is implicit. In Zig, you allocate every byte yourself, explicitly. […] you have to call alloc() on a specific kind of allocator,
> In Go and Rust and so many other languages, you tend to allocate little bits of memory at a time for each object in your object graph. Your program has thousands of little hidden malloc()s and free()s, and therefore thousands of different lifetimes.
Rust can also do arena allocations, and there is an allocator concept in Rust, too. There's just a default allocator, too.
And usually a heap allocation is explicit, such as with Box::new, but that of course might be wrapped behind some other type or function. (E.g., String, Vec both alloc, too.)
> In Rust, creating a mutable global variable is so hard that there are long forum discussions on how to do it.
The linked thread is specifically about creating a specific kind of mutable global, and has extra, special requirements unique to the thread. The stock "I need a global" for what I'd call a "default situation" can be as "simple" as,
static FOO: Mutex<T> = Mutex::new(…);
Since mutable globals are inherently memory unsafe, you need the mutex.
(Obviously, there's usually an XY problem in such questions, too, when someone wants a global…)
To the safety stuff, I'd add that Rust not only champions memory safety, but the type system is such that I can use it to add safety guarantees to the code I write. E.g., String can guarantee that it always represents a Unicode string, and it doesn't really need special support from the language to do that.
- Capricorn2481 11mo ago>> In Go and Rust and so many other languages, you tend to allocate little bits of memory at a time for each object in your object graph. Your program has thousands of little hidden malloc()s and free()s, and therefore thousands of different lifetimes. > Rust can also do arena allocations, and there is an allocator concept in Rust, too. There's just a default allocator, too. Thank you. I've seen this repeated so many times. Casey Muratori did a video on batch allocations that was extremely informative, but also stupidly gatekeepy [1]. I think a lot of people who want to see themselves as super devs have latched onto this point without even understanding it. They talk like RAII makes it impossible to batch anything. Last year the Zig Software Foundation wrote about Asahi Lina's comments around Rust and basically implied she was unknowingly introducing these hidden allocations, citing this exact Casey Muratori video. And it was weird. A bunch of people pointed out the inaccuracies in the post, including Lina [2]. That combined with Andrew saying Go is for people without taste (not that I like Go myself), I'm not digging Zig's vibe of dunking on other companies and languages to sell their own. [1] https://www.youtube.com/watch?v=xt1KNDmOYqA https://www.youtube.com/watch?v=xt1KNDmOYqA [2] https://lobste.rs/s/hxerht/raii_rust_linux_drama https://lobste.rs/s/hxerht/raii_rust_linux_drama
- zozbot234 11mo ago"Batch allocation" in Rust is just a matter of Box-ing a custom-defined tuple of objects as opposed to putting each object in its own little Box. You can even include MaybeUninit's in the tuple that are then initialized later in unsafe code, and transmuted to the initialized type after-the-fact. You don't need an allocator library at all for this easy case, that's more valuable when the shape of allocations is in fact dynamic.
- kibwen 11mo ago> You don't need an allocator library at all for this easy case, that's more valuable when the shape of allocations is in fact dynamic. Though I'd still reach for something like Bumpalo ( https://crates.io/crates/bumpalo https://crates.io/crates/bumpalo ) unless I had good reason to avoid it.
- deleted 11mo ago[deleted]
- dnautics 11mo ago> there is an allocator concept in Rust, too. aren't allocators types in rust? suppose you had an m:n system (like say an evented http request server split over several threads so that a thread might handle several inbound requests), would you be able to give each request its own arena?
- codys 11mo agoAllocators in rust are objects that implement the allocator trait. One (generally) passes the allocator object to functions that use the allocator. For example, `Vec` has `Vec::new_in(alloc: A) where A: Allocator`. And so if in your example every request can have the same Allocator type, and then have distinct instances of that type . For example, you could say "I want an Arena" and pick the Arena type that impls Allocator, and then create a new instance of Arena for each `Vec::new_in(alloc)` call. Alternately, if you want every request to have a distinct Allocator type as well as instance, one can use `Box<dyn Allocator>` as the allocators type (or use any other dispatch pattern), and provide whatever instance of the allocator is appropriate.
- weavie 11mo agoTo be clear though, the allocator API is still experimental and from what I remember has been for quite a while now..
- Mawr 11mo ago> Rust can also do arena allocations, Is there a language that can't? The author isn't saying it's literally impossible to batch allocate, just that the default happy path of programming in Rust & Go tends to produce a lot of allocations. It's a take more nuanced than the binary possible vs impossible.
- seanmcdirmid 11mo agoPretty hard to do arena allocation in Java without JVM primitive support.
- jeberle 11mo agoNot 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://openjdk.org/jeps/454 https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/foreign/Arena.html https://docs.oracle.com/en/java/javase/25/docs/api/java.base...
- Dylan16807 11mo agoSo, one year ago? After more than 25 years without it? And a lot of people writing Java can't update to that.
- jeberle 11mo agoYeah, FFM adds many quality-of-life features - scoped lifetimes being a standout. If you just want an arena interface, ByteBuffer has been there since Java 1.4 (2002). It also does off-heap w/ ByteBuffer.allocateDirect(). https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/nio/ByteBuffer.html https://docs.oracle.com/en/java/javase/25/docs/api/java.base...
- seanmcdirmid 11mo agoThat brings back some memories...when Frank Yellin and Sheng Liang (from Javasoft) visited our team at UW I think in 1996 or 1997, we mentioned that our bytecode verifier/failure injector was really fast because we were using arena allocation, which was only possible (at the time) because we did the project in C. If you are using non-pointer offsets, you totally can do arena allocation with a byte buffer. I still don't get how you can do it safely with high level objects even with the mechanism described above, but there are definitely lots of unsafe ways to do it.
- attractivechaos 11mo ago> But you only need about 5% of the concepts in that comment to be productive in Rust. The similar argument against C++ is applicable here: another programmer may be using 10% (or a different 5%) of the concepts. You will have to learn that fraction when working with him/her. This may also happen when you read the source code of some random projects. C programmers seldom have this problem. Complexity matters.
- scuff3d 11mo agoThere's also the problem of the people who are either too clever for their own good, or not nearly as clever as they think they are. Either group can produce horribly convoluted code to perform relatively simple tasks, and it's irritating as hell everytime I run into it. That's not unique to Rust of course, but the more tools you give to them the bigger mess they make.
- hu3 11mo agoAnd this is amplified by LLMs. Before LLMs, only the author had a firm grasp of how their convoluted solution works. Now sometimes not even the author knows wtf is going on among thousands of added lines of code.
- kibwen 11mo agoNo, this is overly simplistic. The features in the quoted comment are largely things that nobody other than stdlib developers need to understand. There is no bespoke subset-dialect of Rust where people are tossing around the `fundamental` attribute--it is strictly an obscure detail that not even an expert Rust programmer would be expected to have even heard of.
- zozbot234 11mo agoThe main issue with "fundamental" is that it's currently unstable, but a stable version of it could definitely be useful for lessening the "orphan rule" constraints on implementing traits. Probably would want a different name such as #[deorphan] though.
- tapirl 11mo ago> Rust can also do arena allocations, and there is an allocator concept in Rust, too. Just a pure question: Is Rust allocator global? (Will all heap allocations use the same allocator?)
- yccs27 11mo agoNo. There is a global allocator which is used by default, but all the stdlib functions that allocate memory have a version which allows you to pass in a custom allocator. These functions are still "unstable" though, so they can currently only be used with development builds of the compiler.
- steveklabnik 11mo agoRust, as a language, has no allocator. The standard library provides a global allocator. The collections in the standard library currently use that allocator. It also provides an unstable interface for allocators in general. That's of course useful someday, but also doesn't prevent people from using whatever allocators they want in the meantime. It just means that libraries that want to be generic over one cannot currently agree. The standard library collections also will use that once it becomes stable.