3 ms·
In Zig, as far as I understand, you really just pass an allocator around. I don't see any special syntax to support this? This could be done in Rust. There is,
by the_duke 6y ago
In Zig, as far as I understand, you really just pass an allocator around. I don't see any special syntax to support this?
This could be done in Rust. There is, for example, the simple bump allocator bumpalo [1].
It would be nice if the the std collections supported this (in planning, but hasn't seen much progress), and most dependencies would not be built around a manually passed allocator.
> Rust assumes most of the time you'll be passing around references to values or small structures allocated on the stack.
Can you clarify what you mean here? All of the std collections (Vec, HashMap, etc) use allocation. There are also `Box`, `Rc` and `Arc`, which allocate and are used everywhere.
[1] https://github.com/fitzgen/bumpalo https://github.com/fitzgen/bumpalo
- skohan 6y agoAgain, it's not about what you are able to do in Rust vs. Zig, it's essentially about the API of the language. Zig's semantics around memory management are imperative: i.e. you are telling the compiler when to allocate and deallocate memory. Rust's are declarative: you tell the compiler how the memory for a given value should be managed, and the compiler interprets these requirements to decide when memory should be allocated or deallocated. Again, I do not think this a weakness of Rust, and I do not think it should change. In very many cases, the Rust approach is very helpful. The point is there are also cases where imperative, explicit memory management is desirable.
- the_duke 6y ago> The point is there are also cases where imperative, explicit memory management is desirable. I agree that is the case, and Zigs convention of passing an allocator around and making those calls very explicit has merit. I think you are over-estimating the amount of "magic" in Rust though. The allocation-related logic is not part of the language or the compiler, but comes from the std (or alloc) crate. You just don't usually see a "malloc" call because it is hidden behind types in the standard library, which default to a global allocator. You still "manually" allocate by calling eg `Box::new()`. The only magic is that Rust calls a destructor ( Drop::drop) when a value goes out of scope. Types can implement drop and use it to deallocate or decrement a reference counter. This is made possible by using an affine type system with lifetimes and move semantics. This is conceptually not that different from doing something like `defer allocator.free(x)` in Zig, though less explicit. ps: I realize that conventions make a difference. But nothing in Zig would stop me from having a global variable with an allocator, and using that without passing it around.
- dnautics 6y ago> But nothing in Zig would stop me from having a global variable with an allocator, and using that without passing it around. That's correct and you probably should do that in your own applications, but it will be frowned upon in libraries, and people will not choose to use them if you make that choice. There's also another pattern, where you stuff a pointer to your allocator in your struct and have your "object" carry around its allocation system, you don't have to pass around allocators that way.
- TylerE 6y agoThe point is that the allocator CAN BE specified at call time for the entire stdlib. And it doesn’t have to be just one allocator either, you can easily use multiple allocators simultaneously.