I updated to the latest stable version of Zig (0.15.1), and I am really really really missing the original implementation of the ArrayList type, I am really not in the mood for porting all my stuff over from the old type to the new one.
Is there any drop-in replacement that I can use? Was it renamed to something else in the standard library? I personally do not even understand why would they just entirely get rid of such a useful and widely used type like that…
It is a little annoying, but I think Allocators are intended to be passed down through function parameters to wherever they’re needed. It’s a little bit of friction that ends up making everything more readable.
I thought it was a well stablished pattern that structs could simply hold an allocator and use it, and while I do understand the point of this, at the same time I feel like it adds a whole other layer of complexity that doesn’t really make too much sense to me
i guess that’s it though, thank you all for your help!
I think that’s fine for applications themselves, but libraries including std itself probably really should take in an allocator at every function that uses it.
yeah one could do that but it’s also really sad that i’d need to mantain my own version of std.ArrayList when it used to be a readily available type that was pretty much good enough for most things, I think there’s still a case for it being on the STD or at least on some community supported library we can all take from. Not saying it should stay the default because I 100% comprehend why would they do this, but i’d appreciate not adding even more friction to getting things done.
Hahaha no it is not that bad.
I actually got used to it and like it. Not everywhere this 64 bits or more wasted storing the allocator.
I miss more the BoundedArray of which I now use my private copy
It’s good that you’re offering feedback, because these things aren’t set in stone. It’s a safe bet that the default ArrayList will never have an Allocator field again, but the fate of the managed variant is less clear.
Personally, for ArrayLists, I’ve found no real utility in using the managed variants. Just empirically, it seems like there’s always an Allocator nearby when I use them.
You may find the same thing when you take the time to convert your code (which is itself not fun, it’s always less enjoyable to do work which just keeps code running due to changes outside of your control). Or, you may not, in which case, advocate for the managed variant to stick around.
I think there should be default wrapper for array list for sure, for a managed and a bounded variant.
If you only use one allocator in your current context, it in fact makes your code much less readable if you pass it around everywhere, because you already know that you only ever gonna use that one.
So it really is just pollution in those situations.
And yes there are often situations where it makes it more readable, but there is at least just as many where it makes it worse, so the solution is just to provide both.
Same with a bounded implementation. It just gives you more context about the type, which can be very helpful in understanding the code. Having that “bounded” behavior hidden and only visible when you use function on the array list again is just bad.
And again there are also situations where you would want the bounded behavior on a regular array list, but again the solution is to just provide a default wrapper that only works bounded.
You’re in good company, @Robin , @darltrash , and others. One thing to keep in mind is that one important goal is “clarity about what functions result in allocation”. It’s similar with Io, and the new Io paradigm. At least for the lowest level code written in zig, you can be sure, at a glance, that a given function does allocations (or deallocs) if the function is taking an alloc arg, or, perhaps, a struct that contains an alloc arg (i.e., it might not be immediately obvious, but it shouldn’t be too hard to determine).
Certainly, a library might implement, e.g., a ShoppingList or PlayList struct, which MIGHT not even ask the caller to provide an allocator to init, and might assume the responsibility entirely, and make the lib users’ calls to addSong(), and such, completely blind to allocations. But another author might make a similar library that is more ziggish, and exposes the allocator to callers, and many may prefer this, so they can know for sure, without a deep dive, that addSong() results in allocs while, perhaps, rateSong() does not (or maybe does, also!) - such detail would not be as obvious in the first implementation, and many zig coders will tend to want that detail function-by-function. The std has to present in this way in order to enable (and promote) this norm… part of the fabric of the language, which distinguishes it from other languages.
Why can’t both higher level containers (that store their allocator) and lower level containers (that don’t) both be considered ziggish? IMO we shouldn’t discourage people from encapsulating the allocator, when that makes sense. Non-ziggish will be considered “bad” by many people, without considering the specific situation.