February 04, 2014 Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Consider we add a library slice type called RCSlice!T. It would have the same primitives as T[] but would use reference counting through and through. When the last reference count is gone, the buffer underlying the slice is freed. The underlying allocator will be the GC allocator. Now, what if someone doesn't care about the whole RC thing and aims at convenience? There would be a method .toGC that just detaches the slice and disables the reference counter (e.g. by setting it to uint.max/2 or whatever). Then people who want reference counting say auto x = fun(); and those who don't care say: auto x = fun().toGC(); Destroy. Andrei |
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tue, 04 Feb 2014 18:51:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > Consider we add a library slice type called RCSlice!T. It would have the same primitives as T[] but would use reference counting through and through. When the last reference count is gone, the buffer underlying the slice is freed. The underlying allocator will be the GC allocator. Doesn't that mean it lives in the GC heap and is scanned along with all the other data in the GC heap (and triggers GC cycles)? What is the benefit? > Now, what if someone doesn't care about the whole RC thing and aims at convenience? There would be a method .toGC that just detaches the slice and disables the reference counter (e.g. by setting it to uint.max/2 or whatever). > > Then people who want reference counting say > > auto x = fun(); > > and those who don't care say: > > auto x = fun().toGC(); Shouldn't the default be what is expected now? That is, I don't want to have to change all my code to return RCSlice!T instead of T[]. I admit, I don't know how that would work... -Steve |
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tue, 04 Feb 2014 15:51:35 -0800, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > Consider we add a library slice type called RCSlice!T. It would have the same primitives as T[] but would use reference counting through and through. When the last reference count is gone, the buffer underlying the slice is freed. The underlying allocator will be the GC allocator. > > Now, what if someone doesn't care about the whole RC thing and aims at convenience? There would be a method .toGC that just detaches the slice and disables the reference counter (e.g. by setting it to uint.max/2 or whatever). > > Then people who want reference counting say > > auto x = fun(); > > and those who don't care say: > > auto x = fun().toGC(); > > > Destroy. > > Andrei I am assuming that you ignoring cyclic-refs for now. And dealing with them would mean that you would need something like: auto @weak x = fun(); Since the compiler cannot figure out that this is supposed to be weak or not it would assume strong as that is the majority. Second thought. Why is their an extra step for those of us who don't want the GC. I know there has to be an extra step for some people, but I feel that we should make the simplest option the default and then open up avenues for more advanced control for people who want it. ARC is not as simple to understand as a GC for newbies, and ARC requires more careful control, so why not make getting into ARC a little harder, that way we prevent heartache for new people. So something more like: auto x = fun().toARC(); I can't imagine any situation where you could go from ARC to GC that could not also go from GC to ARC, they have to be equivalent operations to do that anyways. In the design world you make the simple option easy and more the more advanced options harder to get at to reduce the chance that the user accidentally shoot themselves in the foot. And the guys who want to the advanced options are power users anyways, they expect to have to work at it a little more. Related third thought. This goes against the current paradigm and will subtly break existing D code that has cyclic-refs in it. -- Adam Wilson GitHub/IRC: LightBender Aurora Project Coordinator |
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Wilson | He said *new* library type, so obviously it would not break existing code since nothing uses it.
Wednesday, 5 February 2014 at 00:07:30 UTC, Adam Wilson wrote:
> On Tue, 04 Feb 2014 15:51:35 -0800, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>
>> Consider we add a library slice type called RCSlice!T. It would have the same primitives as T[] but would use reference counting through and through. When the last reference count is gone, the buffer underlying the slice is freed. The underlying allocator will be the GC allocator.
>>
>> Now, what if someone doesn't care about the whole RC thing and aims at convenience? There would be a method .toGC that just detaches the slice and disables the reference counter (e.g. by setting it to uint.max/2 or whatever).
>>
>> Then people who want reference counting say
>>
>> auto x = fun();
>>
>> and those who don't care say:
>>
>> auto x = fun().toGC();
>>
>>
>> Destroy.
>>
>> Andrei
>
> I am assuming that you ignoring cyclic-refs for now. And dealing with them would mean that you would need something like:
>
> auto @weak x = fun();
>
> Since the compiler cannot figure out that this is supposed to be weak or not it would assume strong as that is the majority.
>
> Second thought. Why is their an extra step for those of us who don't want the GC. I know there has to be an extra step for some people, but I feel that we should make the simplest option the default and then open up avenues for more advanced control for people who want it. ARC is not as simple to understand as a GC for newbies, and ARC requires more careful control, so why not make getting into ARC a little harder, that way we prevent heartache for new people. So something more like:
>
> auto x = fun().toARC();
>
> I can't imagine any situation where you could go from ARC to GC that could not also go from GC to ARC, they have to be equivalent operations to do that anyways.
>
> In the design world you make the simple option easy and more the more advanced options harder to get at to reduce the chance that the user accidentally shoot themselves in the foot. And the guys who want to the advanced options are power users anyways, they expect to have to work at it a little more.
>
> Related third thought. This goes against the current paradigm and will subtly break existing D code that has cyclic-refs in it.
|
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu:
> auto x = fun().toGC();
Recently I remember Kenji saying that we are now almost able to implement "dup" in library code. If that happens, why don't you call it "dup"?
Bye,
bearophile
|
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to woh | On Tue, 04 Feb 2014 19:15:24 -0500, woh <wojw@yahoo.com> wrote:
> He said *new* library type, so obviously it would not break existing code since nothing uses it.
I think the possible goal is that phobos functions that now return slices would return this (at some point in the future), to give the option of using RC or GC with any phobos calls.
-Steve
|
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Tue, 04 Feb 2014 19:42:55 -0500, bearophile <bearophileHUGS@lycos.com> wrote:
> Andrei Alexandrescu:
>
>> auto x = fun().toGC();
>
> Recently I remember Kenji saying that we are now almost able to implement "dup" in library code. If that happens, why don't you call it "dup"?
No, toGC does not create a copy. It just detaches the RC component, and relies on GC to clean up the resulting slice (I assume typeof(fun().toGC()) == T[])
dup would imply that you wanted a copy in addition to the reference-counted version. In fact, you may want a copy that is also reference counted.
-Steve
|
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Wilson | On Tue, 04 Feb 2014 16:07:29 -0800, Adam Wilson <flyboynw@gmail.com> wrote: > On Tue, 04 Feb 2014 15:51:35 -0800, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > >> Consider we add a library slice type called RCSlice!T. It would have the same primitives as T[] but would use reference counting through and through. When the last reference count is gone, the buffer underlying the slice is freed. The underlying allocator will be the GC allocator. >> >> Now, what if someone doesn't care about the whole RC thing and aims at convenience? There would be a method .toGC that just detaches the slice and disables the reference counter (e.g. by setting it to uint.max/2 or whatever). >> >> Then people who want reference counting say >> >> auto x = fun(); >> >> and those who don't care say: >> >> auto x = fun().toGC(); >> >> >> Destroy. >> >> Andrei > > I am assuming that you ignoring cyclic-refs for now. And dealing with them would mean that you would need something like: > > auto @weak x = fun(); > > Since the compiler cannot figure out that this is supposed to be weak or not it would assume strong as that is the majority. > > Second thought. Why is their an extra step for those of us who don't want the GC. I know there has to be an extra step for some people, but I feel that we should make the simplest option the default and then open up avenues for more advanced control for people who want it. ARC is not as simple to understand as a GC for newbies, and ARC requires more careful control, so why not make getting into ARC a little harder, that way we prevent heartache for new people. So something more like: > > auto x = fun().toARC(); > > I can't imagine any situation where you could go from ARC to GC that could not also go from GC to ARC, they have to be equivalent operations to do that anyways. > > In the design world you make the simple option easy and more the more advanced options harder to get at to reduce the chance that the user accidentally shoot themselves in the foot. And the guys who want to the advanced options are power users anyways, they expect to have to work at it a little more. > > Related third thought. This goes against the current paradigm and will subtly break existing D code that has cyclic-refs in it. > Ok, disregard my previous post. I think I understand better what Andrei is driving at, but it's not obvious, better examples are needed. But more to the point this is going to make us all equally miserable. The ARC guys don't get the compiler support needed to make ARC fast. It completely ignores cyclic-refs inside the slice. It doesn't solve the primary ARC-camp complaint about the reliance on the GC. The GC now guys have more hoops to jump-through when working with Phobos. And it increases complexity and cognitive load all around. -- Adam Wilson GitHub/IRC: LightBender Aurora Project Coordinator |
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 4 February 2014 at 23:51:35 UTC, Andrei Alexandrescu wrote:
> Consider we add a library slice type called RCSlice!T. It would have the same primitives as T[] but would use reference counting through and through. When the last reference count is gone, the buffer underlying the slice is freed. The underlying allocator will be the GC allocator.
>
> Now, what if someone doesn't care about the whole RC thing and aims at convenience? There would be a method .toGC that just detaches the slice and disables the reference counter (e.g. by setting it to uint.max/2 or whatever).
>
> Then people who want reference counting say
>
> auto x = fun();
>
> and those who don't care say:
>
> auto x = fun().toGC();
>
>
> Destroy.
>
> Andrei
RC need GC to collect loops. So you want to have the GC at the lowest level.
That being understood, I'd rather connect things the other way around.
auto x = foo();
auto x = foo().toRC();
|
February 05, 2014 Re: Idea #1 on integrating RC with GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Tue, 04 Feb 2014 17:12:37 -0800, deadalnix <deadalnix@gmail.com> wrote: > On Tuesday, 4 February 2014 at 23:51:35 UTC, Andrei Alexandrescu wrote: >> Consider we add a library slice type called RCSlice!T. It would have the same primitives as T[] but would use reference counting through and through. When the last reference count is gone, the buffer underlying the slice is freed. The underlying allocator will be the GC allocator. >> >> Now, what if someone doesn't care about the whole RC thing and aims at convenience? There would be a method .toGC that just detaches the slice and disables the reference counter (e.g. by setting it to uint.max/2 or whatever). >> >> Then people who want reference counting say >> >> auto x = fun(); >> >> and those who don't care say: >> >> auto x = fun().toGC(); >> >> >> Destroy. >> >> Andrei > > RC need GC to collect loops. So you want to have the GC at the lowest level. > > That being understood, I'd rather connect things the other way around. > > auto x = foo(); > auto x = foo().toRC(); The ARC crowd is going to hate this because it's still a GC allocation then you hook it to RC. So they can still have random GC pauses. -- Adam Wilson GitHub/IRC: LightBender Aurora Project Coordinator |
Copyright © 1999-2021 by the D Language Foundation