On Thursday, 6 February 2014 at 18:18:49 UTC, Andrei Alexandrescu
wrote:
On 2/6/14, 9:54 AM, Frustrated wrote:
Any time you hard code code something you are also creating
constraints. If people build something on top of what you have
built they inherit those constrains.
Nice thought.
So, why not create a design pattern that allows one, at compile
time, to use any specific memory management technique they want
for the runtime and library(and user code)?
We have a very powerful mechanism for what could be called
"statically deferred committal": templates. Phobos did a great
job at not committing to e.g. range representation or string
representation. It seems to me we have a clean shot at applying
the wealth of knowledge and experience we accumulated with
that, to deferring approaches to allocation.
e.g., switches could be used to recompile the source when a
different pattern is desired or libraries could be created that
use different methods. e.g., phobos64GC.lib.
That won't even be necessary with templates. It would be
necessary if we have some sort of global flag dictating a
fundamental fork.
Yeah, I was thinking templates could be used here to good effect.
To make any of this work, and work efficiently, one must
abstract
what is common between all memory management techniques.
Since allocation is always explicitly defined, it is easy to
handle. Which every memory management technique is used, it
would be called/notified on allocation. The deallocation is the
tricky part. (reallocation is another potential issue)
Yah, std.allocator aims at formalizing that (in an untyped
manner).
yeah, and I think it is definitely a step in the right
direction... Just have to get the core and library to be along
those lines.
For manual memory management the deallocation is explicitly
called by the user. This in and of itself is significant and
either allows the compiler to know that manual memory
management
is used or to replace it with automatic management if desired.
e.g.,
{
auto a = new!strategy A;
release a; // <- explicit deallocation: replaced with
strategy.explicitDeallocation(a);
}
vs
{
auto a = new!strategy A;
// implicit deallocation: compiler inserts
strategy.scopeDeallocation(a);
}
I don't think this works. The scope of "strategy" and "a" may
be unrelated. More importantly a may be escaped (e.g. by
passing it to functions etc) unbeknownst to "strategy", which
in fact suggests that the strategy must be somehow known by "a"
independently.
See the other post about this. scopeDeallocation meant to simply
signal that the scope of a has ended but not necessarily there
are no references to a. Would be used more in AGC and ARC than
anything but could be used in other ways.
The idea, I think, is to have the compiler insert as much
implicit information as possible to handle stuff with the ability
to override with explicit calls and to even override what the
implicit calls do.
It would sort of have the effect of adding "hooks" into the
compiler to tell it what to do on allocations and deallocations.