3 ms·
I suppose the distinction you're suggesting here is that in the Zig-like example, two `Foo<T>` can have the same type and different allocators. Author mostly n
by tel 4y ago
I suppose the distinction you're suggesting here is that in the Zig-like example, two `Foo<T>` 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 default does bias Rust toward being uncreative with its choice of allocator.
I wonder, too: in this example, the author notes that because their init function takes an allocator and their event loop doesn't, therefore the event loop does no allocation. But, as long as a global allocator could be accessed from somewhere besides your entrypoint, you could still be calling it. Does Zig offer a capabilities model like that?
All in all, I think this difference is more subtle than Matklad is making it out to be, but I in no way doubt that he's correct. Especially in today's Rust.
Edit: I did some research on Zig and also noticed HashMapUnmanaged which might be more what Matklad was referencing. In pseudo-Rust, it has
impl<K, V> HashMapUnmanaged<K, V> {
fn put<A: Allocator>(&mut self, key: K, value: V, allocator: A);
}
This justifies the statement "Rather, an allocator is passed in explicitly to every method which actually needs to allocate." and makes it much more clear where Zig has gone here.
- steveklabnik 4y agoAh 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.