Phobos 3 Discussion Notes - 02-01-2024
Paul Backus
snarwin at gmail.com
Wed Feb 7 16:20:31 UTC 2024
On Wednesday, 7 February 2024 at 10:10:27 UTC, Atila Neves wrote:
> On Wednesday, 7 February 2024 at 05:55:04 UTC, Paul Backus
> wrote:
>> In my proposal, when you use a library container (like an
>> array, a hash table, a binary tree, etc.), you can specify
>> what type of allocator you want to use as a template parameter
>> (as in, `Array!(int, GC)`). It will probably default to the
>> GC, but you can just as easily use malloc, or even a custom
>> allocator that you write yourself.
>
> The problem with this approach, as C++ found out, is that
> `Vector!(int, MyAlloc)` is a different type from `Vector!(int,
> YourAlloc)`. The way I got around that is by defaulting to a
> global allocator. This has its drawbacks as well of course,
> because now everything is a virtual call.
Yes, I'm aware of this problem, but I don't see a way around it.
The thing is, the compiler has to know what allocator you're
using at compile time in order to infer the correct function
attributes for the container. If you want `Array!int` to default
to using the GC, but also work in `@nogc` code when you're using
`malloc`...how would that even work?
I have two potential mitigations for this problem in mind.
The first is to realize that D already has a solution for writing
data-structure-agnostic code: ranges! If `Array` implements all
of the relevant range interfaces, the rest of your code doesn't
have to depend on any single concrete `Array` type--it can just
depend on the range interface.
If you really need a concrete type, there's always
`std.range.interfaces`, although that does come with some
sacrifices (virtual calls, not `@safe` or `@nogc`, etc.).
The second is to have the allocator library provide a
runtime-polymorphic allocator, which users can depend on if they
absolutely need a single concrete container type for whatever
reason. We'd have to make some serious tradeoffs between runtime
overhead and attribute compatibility, and it's possible that no
one-size-fits-all solution exists, but in principle, it can be
done.
Finally, on the subject of global allocators: I don't think
having a global allocator is a good idea, period, whether it's
used as a default or not. Containers generally cannot tolerate
having their allocators mutated "behind their backs," and a
user-accessible global variable would make it very easy and
tempting to write code that does this.
More information about the Digitalmars-d
mailing list