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