RFC: moving forward with @nogc Phobos
Sean Kelly via Digitalmars-d
digitalmars-d at puremagic.com
Tue Sep 30 09:10:43 PDT 2014
On Monday, 29 September 2014 at 10:49:53 UTC, Andrei Alexandrescu
wrote:
>
> The policy is a template parameter to functions in Phobos (and
> elsewhere), and informs the functions e.g. what types to
> return. Consider:
>
> auto setExtension(MemoryManagementPolicy mmp = gc, R1, R2)(R1
> path, R2 ext)
> if (...)
> {
> static if (mmp == gc) alias S = string;
> else alias S = RCString;
> S result;
> ...
> return result;
> }
Is this for exposition purposes or actually how you expect it to
work? Quite honestly, I can't imagine how I could write a
template function in D that needs to work with this approach.
As much as I hate to say it, this is pretty much exactly what C++
allocators were designed for. They handle allocation, sure, but
they also hold aliases for all relevant types for the data being
allocated. If the MemoryManagementPolicy enum were replaced with
an alias to a type that I could use to at least obtain relevant
aliases, that would be something. But even that approach
dramatically complicates code that uses it.
Having written standards-compliant containers in C++, I honestly
can't imagine the average user writing code that works this way.
Once you assert that the reference type may be a pointer or it
may be some complex proxy to data stored elsewhere, a lot of
composability pretty much flies right out the window.
For example, I have an implementation of C++
unordered_map/set/etc designed to be a customizable cache, so one
of its template arguments is a policy type that allows eviction
behavior to be chosen at declaration time. Maybe the cache is
size-limited, maybe it's age-limited, maybe it's a combination of
the two or something even more complicated. The problem is that
the container defines all the aliases relating to the underlying
data, but the policy, which needs to be aware of these, is passed
as a template argument to this container.
To make something that's fully aware of C++ allocators then, I'd
have to define a small type that takes the container template
arguments (the contained type and the allocator type) and
generates the aliases and pass this to the policy, which in turn
passes the type through to the underlying container so it can
declare its public aliases and whatever else is true
standards-compliant fashion (or let the container derive this
itself, but then you run into the potential for disagreement).
And while this is possible, doing so would complicate the
creation of the cache policies to the point where it subverts
their intent, which was to make it easy for the user to tune the
behavior of the cache to their own particular needs by defining a
simple type which implements a few functions. Ultimately, I
decided against this approach for the cache container and decided
to restrict the allocators to those which defined a pointer to T
as T* so the policies could be coded with basically no knowledge
of the underlying storage.
So... while I support the goal you're aiming at, I want to see a
much more comprehensive example of how this will work and how it
will affect code written by D *users*. Because it isn't enough
for Phobos to be written this way. Basically all D code will
have to take this into account for the strategy to be truly
viable. Simply outlining one of the most basic functions in
Phobos, which already looks like it will have a static
conditional at the beginning and *need to be aware of the fact
that an RCString type exists* makes me terrified of what a
realistic example will look like.
More information about the Digitalmars-d
mailing list