October 25, 2013
On Friday, 25 October 2013 at 08:27:52 UTC, Namespace wrote:
>
> Something like that: http://forum.dlang.org/thread/l4btsk$5u8$1@digitalmars.com?page=3#post-pfoxyfzyjxqcqwnvgnpi:40forum.dlang.org
>
> Every array has an internal allocator property which can be reset:
> ----
> int[] arr;
> arr.allocator = Mallocator;
> ----
>
> or
>
> ----
> int[] arr;
> arr.useAllocator(Mallocator);
> ----

That's doable.

> But maybe a design without some alias notation would be more preferable:
> ----
> {
>     ScopeAllocator m;
>     int[] arr;
>     arr.useAllocator(m);
>
>     arr ~= 42; /// Use m.allocate
> } /// end of scope: ScopeAllocator collects all remaining memory.
> ----
>
> And:
> ----
> int[] arr;
> assert(arr is null);
> {
>     ScopeAllocator m;
>     arr.useAllocator(m);
>
>     arr ~= 42; /// Use m.allocate
> } /// end of scope: ScopeAllocator collects all remaining memory.
> assert(arr is null);
> ----

That's also doable. TypeInfo will be bloated more and there would be cost of some sort of scope exit, and, ideally, a check that reference does not escape, but this is doable.
October 25, 2013
On Friday, 25 October 2013 at 08:50:23 UTC, Maxim Fomin wrote:
> On Friday, 25 October 2013 at 08:27:52 UTC, Namespace wrote:
>>
>> Something like that: http://forum.dlang.org/thread/l4btsk$5u8$1@digitalmars.com?page=3#post-pfoxyfzyjxqcqwnvgnpi:40forum.dlang.org
>>
>> Every array has an internal allocator property which can be reset:
>> ----
>> int[] arr;
>> arr.allocator = Mallocator;
>> ----
>>
>> or
>>
>> ----
>> int[] arr;
>> arr.useAllocator(Mallocator);
>> ----
>
> That's doable.
>
>> But maybe a design without some alias notation would be more preferable:
>> ----
>> {
>>    ScopeAllocator m;
>>    int[] arr;
>>    arr.useAllocator(m);
>>
>>    arr ~= 42; /// Use m.allocate
>> } /// end of scope: ScopeAllocator collects all remaining memory.
>> ----
>>
>> And:
>> ----
>> int[] arr;
>> assert(arr is null);
>> {
>>    ScopeAllocator m;
>>    arr.useAllocator(m);
>>
>>    arr ~= 42; /// Use m.allocate
>> } /// end of scope: ScopeAllocator collects all remaining memory.
>> assert(arr is null);
>> ----
>
> That's also doable. TypeInfo will be bloated more and there would be cost of some sort of scope exit, and, ideally, a check that reference does not escape, but this is doable.

A dream could come true.
October 25, 2013
On Friday, 25 October 2013 at 08:50:23 UTC, Maxim Fomin wrote:
> On Friday, 25 October 2013 at 08:27:52 UTC, Namespace wrote:
>>
>> Something like that: http://forum.dlang.org/thread/l4btsk$5u8$1@digitalmars.com?page=3#post-pfoxyfzyjxqcqwnvgnpi:40forum.dlang.org
>>
>> Every array has an internal allocator property which can be reset:
>> ----
>> int[] arr;
>> arr.allocator = Mallocator;
>> ----
>>
>> or
>>
>> ----
>> int[] arr;
>> arr.useAllocator(Mallocator);
>> ----
>
> That's doable.
>
>> But maybe a design without some alias notation would be more preferable:
>> ----
>> {
>>    ScopeAllocator m;
>>    int[] arr;
>>    arr.useAllocator(m);
>>
>>    arr ~= 42; /// Use m.allocate
>> } /// end of scope: ScopeAllocator collects all remaining memory.
>> ----
>>
>> And:
>> ----
>> int[] arr;
>> assert(arr is null);
>> {
>>    ScopeAllocator m;
>>    arr.useAllocator(m);
>>
>>    arr ~= 42; /// Use m.allocate
>> } /// end of scope: ScopeAllocator collects all remaining memory.
>> assert(arr is null);
>> ----
>
> That's also doable. TypeInfo will be bloated more and there would be cost of some sort of scope exit, and, ideally, a check that reference does not escape, but this is doable.

Why the cost of scope(exit)? If ScopeAllocator m get out of scope, the DTor is called and ideally the collect method is called. That's all. Or am I wrong?
October 25, 2013
On Friday, 25 October 2013 at 09:13:45 UTC, Namespace wrote:
>>> But maybe a design without some alias notation would be more preferable:
>>> ----
>>> {
>>>   ScopeAllocator m;
>>>   int[] arr;
>>>   arr.useAllocator(m);
>>>
>>>   arr ~= 42; /// Use m.allocate
>>> } /// end of scope: ScopeAllocator collects all remaining memory.
>>> ----
>>>
>>> And:
>>> ----
>>> int[] arr;
>>> assert(arr is null);
>>> {
>>>   ScopeAllocator m;
>>>   arr.useAllocator(m);
>>>
>>>   arr ~= 42; /// Use m.allocate
>>> } /// end of scope: ScopeAllocator collects all remaining memory.
>>> assert(arr is null);
>>> ----
>>
>> That's also doable. TypeInfo will be bloated more and there would be cost of some sort of scope exit, and, ideally, a check that reference does not escape, but this is doable.
>
> Why the cost of scope(exit)? If ScopeAllocator m get out of scope, the DTor is called and ideally the collect method is called. That's all. Or am I wrong?

Probably because there may be exception thrown between appending to arr and end of block. In this particular case compiler may be smart enough to optimize it away, but dmd optimization capabilities and nothrow is a separate story.
October 25, 2013
On Friday, 25 October 2013 at 08:53:00 UTC, Namespace wrote:
> A dream could come true.

It depends on how Andrei design allocators, Walter's willingness to accept changes and developers to implement it.
October 25, 2013
On Friday, 25 October 2013 at 09:26:46 UTC, Maxim Fomin wrote:
> On Friday, 25 October 2013 at 08:53:00 UTC, Namespace wrote:
>> A dream could come true.
>
> It depends on how Andrei design allocators, Walter's willingness to accept changes and developers to implement it.

Therefore the 'could'. But if this would be implemented, I'm sure that this would give D good advantages to be a real opponent for C++.

We would have then the possibility to manage our memory by ourself. One of D's promises is, that the GC can be disabled. Yes, it can, but then we have many many things which do not work. For example built-in arrays. With the ability of allocators the promise could come true.
October 25, 2013
On Friday, 25 October 2013 at 09:37:23 UTC, Namespace wrote:
>
> We would have then the possibility to manage our memory by ourself. One of D's promises is, that the GC can be disabled. Yes, it can, but then we have many many things which do not work. For example built-in arrays.

Not only arrays, but classes, throwables, scope exits, new operator, nested structs, etc.
October 25, 2013
On Friday, 25 October 2013 at 09:51:40 UTC, Maxim Fomin wrote:
> On Friday, 25 October 2013 at 09:37:23 UTC, Namespace wrote:
>>
>> We would have then the possibility to manage our memory by ourself. One of D's promises is, that the GC can be disabled. Yes, it can, but then we have many many things which do not work. For example built-in arrays.
>
> Not only arrays, but classes, throwables, scope exits, new operator, nested structs, etc.

Thats right.
But I often use temporary arrays, but I still don't like them because they are always consume so much GC memory. But with allocators that would end.
Let us hope that Walter has the right intention and that Andrei design the allocators for this purpose.
October 25, 2013
On Friday, 25 October 2013 at 10:02:08 UTC, Namespace wrote:
> On Friday, 25 October 2013 at 09:51:40 UTC, Maxim Fomin wrote:
>> On Friday, 25 October 2013 at 09:37:23 UTC, Namespace wrote:
>>>
>>> We would have then the possibility to manage our memory by ourself. One of D's promises is, that the GC can be disabled. Yes, it can, but then we have many many things which do not work. For example built-in arrays.
>>
>> Not only arrays, but classes, throwables, scope exits, new operator, nested structs, etc.
>
> Thats right.
> But I often use temporary arrays, but I still don't like them because they are always consume so much GC memory. But with allocators that would end.
> Let us hope that Walter has the right intention and that Andrei design the allocators for this purpose.

Why does it have to be the opaque druntime dynamic array? Why can't you use the hypothetical (planned, rather) std.container.Array that supports custom allocators, or a type of your own design?

Garbage collected memory management is the only memory management paradigm that supports the infinite lifetime model (GC includes automatic reference counting). Swapping it out for a different memory management technique while libraries or parts of the program still rely on infinite lifetime for parts such as the slice concatenation operators and closures is disastrous.

The best strategy for avoiding the global GC is to not use the language features associated with infinite lifetime, which includes slice concatenation and the `new` operator. For implicit allocations like closures, we don't have much of a choice, so here the capability is useful, but for slice operators? Just use a different type!

Currently the `new` operator has capabilities that function calls cannot replicate - namely non-static nested class construction and construction of classes with non-public constructors - but these issues have to be solved anyway to support allocators in general.
October 25, 2013
On Friday, 25 October 2013 at 08:09:30 UTC, Maxim Fomin wrote:
> This is impossible because with() has already another meaning.

I believe Andrei meant using the existing "with" statement as it currently is defined in the language. The function setAllocator would set the given allocator, and return a structure with a destructor. The destructor should be called at the end of the "with" block, and it will set the current allocator back to its old value.

However, it appears that currently this usage of "with" is buggy:
http://d.puremagic.com/issues/show_bug.cgi?id=11351