The feature I want most, weak *

1,201 views
Skip to first unread message

kpr...@atlassian.com

unread,
Feb 9, 2017, 11:09:38 AM2/9/17
to golang-nuts
The feature I want most in go is automatic reference counting. I don't really care how mainline GC works but I want the language to be open to the possibility of ARC-GC. In order for that to be able to handle cycles you need a weak_ptr type that can requires explicit graduation to a shared_ptr.

What would it mean to add the weak keyword to standard go? As best I can reason it would serve as ownership documentation under trace based and little more so it wouldn't be harmful.  At small run time cost you could with a flag force non-nil values for all implicitly strong / shared pointers which could aid in debugging. Is it a hopeless dream to think this could get added one day?

Thanks

Jesper Louis Andersen

unread,
Feb 9, 2017, 11:31:48 AM2/9/17
to kpr...@atlassian.com, golang-nuts
What is your use case?

The advantage of a GC over something like ARC is that you avoid having to worry about cycles in the heap. Recent GC work has reduced the traditional weakness of Tracing GCs--pauses--into a minimum (reports is 10 microseconds), so the need might not be there.

There is a paper, "A unified theory of Garbage Collection" (2004, Bacon, et.al.)[0], which explains that as you try to optimize something like ARC or a Tracing GC, they tend to end up looking much the same. In ARC, suppose you have a very large linked list of data, or a very large tree, and you remove the final pointer to that very large data structure. A naive ARC system has to remove all of that before it can continue, and this takes time. Your ARC now has pauses, much like a GC. In practice, the ARC has to stagger or cooperate this removal iteratively, but that makes it more in line with a cooperative tracing GC which doesn't stop the world.

In short, the two approaches can end up being more similar than what you expect in the end. Go is already far in its optimization, so it is not that likely it would benefit from suddenly adding the other solution. The ideology is more to avoid allocating in the first place. Look at the sync.Pool API for instance, which is used in order to avoid blindly reallocating data all the time and adding GC pressure where it is not needed.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ian Lance Taylor

unread,
Feb 9, 2017, 11:32:34 AM2/9/17
to kpr...@atlassian.com, golang-nuts
Previous discussion here:

https://groups.google.com/forum/#!topic/golang-nuts/PYWxjT2v6ps

As I mentioned back then, I do not think it would be appropriate to
add them to the language.

One of the indirect consequences of that previous discussion was
sync.Pool, which is a specific form of weak reference.

Ian

kpr...@atlassian.com

unread,
Feb 9, 2017, 7:43:12 PM2/9/17
to golang-nuts, kpr...@atlassian.com
Thx, that looks like an interesting paper. 

kpr...@atlassian.com

unread,
Feb 9, 2017, 7:46:59 PM2/9/17
to golang-nuts, kpr...@atlassian.com
 I'll look into that api and maybe it will solve my problems. Though, to be understood I'm not asking for ARC, I'm asking for a keyword so the spec is compatible with ARC. 

Andy Balholm

unread,
Feb 9, 2017, 8:18:01 PM2/9/17
to kpr...@atlassian.com, golang-nuts
Maybe you could use “notwithstanding". It’s an ignored token in the default Go compiler, and a weak pointer is one that allows an object to be freed notwithstanding any weak references to it…

It’s not in the spec, though, so it might cause problems with other Go implementations such as gccgo. I think gofmt has problems with it too.

Andy

andrey mirtchovski

unread,
Feb 9, 2017, 11:33:15 PM2/9/17
to Andy Balholm, kpr...@atlassian.com, golang-nuts
> Maybe you could use “notwithstanding". It’s an ignored token in the default Go compiler, and a weak pointer is one that allows an object to be freed notwithstanding any weak references to it…

these are gone now: https://twitter.com/rob_pike/status/808784925402898432

Andy Balholm

unread,
Feb 9, 2017, 11:41:33 PM2/9/17
to kpr...@atlassian.com, golang-nuts, andrey mirtchovski
I expect you’re just left with the option of magic comments then, since there’s not going to be much enthusiasm for adding a new do-nothing keyword to the language.

Andy

Ian Lance Taylor

unread,
Feb 9, 2017, 11:55:38 PM2/9/17
to kpr...@atlassian.com, golang-nuts
But you don't need a keyword to get weak pointers. Given the
existence of concurrent GC, the only safe way to use a weak pointer
for anything whatsoever is to call a runtime function that examines
the weak pointer and returns nil if the object is gone or a strong
pointer to the object if it is not. That strong pointer will then
keep the object alive until you discard it. Since you have to call a
runtime function anyhow, putting weak pointers into the language
itself is not necessary. They can be implemented as an opaque type in
the runtime package.

Ian

Keynan Pratt

unread,
Feb 11, 2017, 1:05:29 AM2/11/17
to Ian Lance Taylor, golang-nuts
Yes it CAN be implemented that way, but that throws away type information, and makes code less readable. It also seems to conflate the difference between language and library, i suppose go has already trod that bridge. What I'm asking for is something that can be used to reason about programs at compile time. It seems like an opaque type at runtime wouldn't achieve this. For example, if you where to implement this type could I still do 

var x interface{} = nil

?

If you have weak as a language feature you can make that illegal, insisting that only

var x weak interface{} = nil

is allowed, and any program written for a compiler that enforces non-nullable strong pointers would be valid to compile with the official compiler. Fast compile time is great, it's part of the reason I love go. But it would be nice to have a flag I can turn on that gets me some of those wonderful correctness checking features that you see in languages with stronger type systems. Avoiding nulls just seems like the bare minimum. So those are the things we theoretically get. On the other hand what is the cost of adding this? I suspect it is (very) small and I also acknowledge it will never get added. I just think that's a shame.  

On Thu, Feb 9, 2017 at 11:04 PM, Keynan Pratt <kpr...@atlassian.com> wrote:
> In this scenario how does the runtime distinguish between a weak and strong
> pointer? how does a developer ensure they are dealing with a weak or strong
> pointer when declaring a struct?

In general, please reply to the mailing list, not just to me.  Thanks.

A weak pointer has the opaque type runtime.WeakPointer.  It has methods
    Set(interface{})
    Get() interface{}
The runtime can tell a weak pointer because it is the value stored in
a runtime.WeakPointer.  The developer can ensure they are dealing with
a weak pointer by writing runtime.WeakPointer rather than *T.

On Sat, Feb 11, 2017 at 1:32 AM, Ian Lance Taylor <ia...@golang.org> wrote:
On Thu, Feb 9, 2017 at 11:04 PM, Keynan Pratt <kpr...@atlassian.com> wrote:
> In this scenario how does the runtime distinguish between a weak and strong
> pointer? how does a developer ensure they are dealing with a weak or strong
> pointer when declaring a struct?

In general, please reply to the mailing list, not just to me.  Thanks.

A weak pointer has the opaque type runtime.WeakPointer.  It has methods
    Set(interface{})
    Get() interface{}
The runtime can tell a weak pointer because it is the value stored in
a runtime.WeakPointer.  The developer can ensure they are dealing with
a weak pointer by writing runtime.WeakPointer rather than *T.

Ian

Wojciech S. Czarnecki

unread,
Feb 11, 2017, 4:58:37 AM2/11/17
to golan...@googlegroups.com
Dnia 2017-02-11, o godz. 17:04:58
Keynan Pratt <kpr...@atlassian.com> napisał(a):

> On the other hand what is the cost of adding this?
> I suspect it is (very) small

I suspect it is (very) easy to assess: simply clone
the go repo and do implement weak as you sketched it.

See e.g. https://github.com/waterlink/go

Hope this helps,
TC

--
Wojciech S. Czarnecki
^oo^ OHIR-RIPE

Ian Lance Taylor

unread,
Feb 13, 2017, 1:04:28 AM2/13/17
to Keynan Pratt, golang-nuts
On Fri, Feb 10, 2017 at 10:04 PM, Keynan Pratt <kpr...@atlassian.com> wrote:
> Yes it CAN be implemented that way, but that throws away type information,
> and makes code less readable.

The question of compile-time type information boils down to the generics issue.

> It also seems to conflate the difference
> between language and library, i suppose go has already trod that bridge.
> What I'm asking for is something that can be used to reason about programs
> at compile time. It seems like an opaque type at runtime wouldn't achieve
> this. For example, if you where to implement this type could I still do
>
> var x interface{} = nil
>
> ?
>
> If you have weak as a language feature you can make that illegal, insisting
> that only
>
> var x weak interface{} = nil
>
> is allowed, and any program written for a compiler that enforces
> non-nullable strong pointers would be valid to compile with the official
> compiler. Fast compile time is great, it's part of the reason I love go. But
> it would be nice to have a flag I can turn on that gets me some of those
> wonderful correctness checking features that you see in languages with
> stronger type systems. Avoiding nulls just seems like the bare minimum. So
> those are the things we theoretically get. On the other hand what is the
> cost of adding this? I suspect it is (very) small and I also acknowledge it
> will never get added. I just think that's a shame.

I'm sorry, but that doesn't seem to me like Go. Go is a language with
a simple type system. I can understand how weak pointers could fit
into Go. But once you start saying that we are going to reject
storing nil in an interface value unless it is weak, then you are
greatly complicating the type system. The cost of adding that kind of
complexity to the language is high. The cost is not in
implementation--though I don't see offhand how to implement it, since
now non-weak interfaces have no zero value--the cost is in requiring
everybody learning the language to learn a complex new concept.

Ian

Keynan Pratt

unread,
Feb 13, 2017, 6:18:55 AM2/13/17
to Ian Lance Taylor, golang-nuts
"""
But once you start saying that we are going to reject

storing nil in an interface value unless it is weak, then you are
greatly complicating the type system. 
"""
With regards to controls on nil this is a static analysis tool, not something I expect to be forced on anyone.
As I understand it all interface types carry their concrete type with them, and this would only complain about the assignment of (nil, nil), it would not effect the zero value.
Users of the official golang compiler would never even need to be told this is a thing. the golang compiler only needs to quietly throw away the weak keyword when it is found in type declaration such that any code written to an experimental fork could be safely built with the official compiler.


Axel Wagner

unread,
Feb 13, 2017, 7:04:04 AM2/13/17
to Keynan Pratt, Ian Lance Taylor, golang-nuts
You can already achieve all of this without any kind of language change or cooperation from the go-team. Just add an annotation in a comment (e.g. "//foo:weak") on declarations of "weak" pointers and then have the tool look for them and do its analysis.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages