Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upspec: reference-like properties of channels, slices, and maps not well specified #5083
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Owner changed to @griesemer. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Issue #6529 has been merged into this issue. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nathany
Aug 7, 2014
Contributor
Someone once explained them to me as types containing _unexported pointers_. That seems to align with the sliceHeader example in http://blog.golang.org/slices.
Someone once explained them to me as types containing _unexported pointers_. That seems to align with the sliceHeader example in http://blog.golang.org/slices. |
robpike
added
accepted
Documentation
labels
Aug 7, 2014
robpike
assigned
griesemer
Aug 7, 2014
griesemer
referenced this issue
Dec 8, 2014
Closed
spec: maps, channels (and to a lesser extent) slices don't say that they are reference types #6529
Zaerei
referenced this issue
Dec 27, 2014
Closed
spec: possible danger w.r.t. slices and append #9458
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
adonovan
Mar 14, 2015
Concluding a recent thread https://groups.google.com/d/topic/golang-nuts/86N_xtgcZqo/discussion, I think the the burden is on the spec to make clear
- that a 'map' value is a reference to an opaque data structure
- that make(map) creates an instance of this data structure and returns a reference to it
- that copying a 'map' value creates a new alias to the same instance of that data structure
- that the effect of m[k]=v updates made via one reference are visible to all aliases
- that a 'map' value may be safely represented by an unsafe.Pointer (as rsc told me)
and on the memory model to state
- that this data structure is analogous to a variable
- that m[k] and range operations on a map are analogous to reads of that variable
- and that m[k]=v and delete operations are analogous to writes.
adonovan
commented
Mar 14, 2015
|
Concluding a recent thread https://groups.google.com/d/topic/golang-nuts/86N_xtgcZqo/discussion, I think the the burden is on the spec to make clear
and on the memory model to state
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ianlancetaylor
Mar 15, 2015
Contributor
I remain unconvinced that we should enforce in the language spec that a map value may be represented by an unsafe.Pointer. We don't specify the internal format of slices or interface values or channels, and I don't think we should specify maps.
|
I remain unconvinced that we should enforce in the language spec that a map value may be represented by an unsafe.Pointer. We don't specify the internal format of slices or interface values or channels, and I don't think we should specify maps. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
adonovan
Mar 15, 2015
I understand your concern. The (reflect.Value).Pointer method seems to suggest that a map value is just a pointer, but it's not clear what it actually commits us to.
It would be nice if the language provided a reliable and portable way for programs to detect cycles in arbitrary object graphs. This requires a robust notion of identity for maps, channels, functions, and slices. (reflect.Value).Pointer + unsafe.Pointer is sufficient for the first three; slices require runtime.SliceHeader + unsafePointer, which is not portable.
adonovan
commented
Mar 15, 2015
|
I understand your concern. The (reflect.Value).Pointer method seems to suggest that a map value is just a pointer, but it's not clear what it actually commits us to. It would be nice if the language provided a reliable and portable way for programs to detect cycles in arbitrary object graphs. This requires a robust notion of identity for maps, channels, functions, and slices. (reflect.Value).Pointer + unsafe.Pointer is sufficient for the first three; slices require runtime.SliceHeader + unsafePointer, which is not portable. |
rsc
added this to the Unplanned milestone
Apr 10, 2015
rsc
removed
priority-soon
labels
Apr 10, 2015
cespare
referenced this issue
Sep 26, 2016
Closed
Remove inappropriate "references" words in go faqs. #17228
randall77
referenced this issue
Apr 18, 2017
Closed
Spec does not fully define map/struct assignment #20016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alercah
Apr 30, 2017
After running into this one again myself, here's a thought. I think the issue is actually most significant for maps and channels, because they refer to programmer-invisible common state. While slices and pointers refer to common state as well, this state is much more explicitly exposed to the programmer for these types, while map and channel state is completely opaque. Functions are in practice similar as well, but because there are no modifying operations on functions, this is irrelevant (an implementation which actually passed around executable code would perhaps have authors in need of a stern talking to, but would not otherwise be an issue).
So I think this could be resolved by:
- Invent the concept of an underlying map/channel to which a map and channel value refer (except for nil). I chose "underlying" because it is already in use for slices.
- Specify that map and channel operations other than assignment operate on the underlying object.
makereturns a value pointing to a new underlying object. - Clarify pointers by specifying that a non-nil pointer points to an addressable value, called the underlying variable. Explicitly specify that taking the address of a composite literal is a shorthand for declaring it as a variable and taking its address, to ensure that the value is always addressable.
- Clearly specify the effect of assignment:
a. For numeric, boolean, and string types, direct value assignment.
b. For array and struct types, elementwise assignment per these rules.
c. For interface types, assignment of the value per these rules (provide an example like https://play.golang.org/p/Eh3BwAWYI3 since this behaviour can be nonintuitive).
d. For map, pointer, slice, and channel types, setting the underlying object and, in the case of a slice, also length and capacity.
e. Function types should probably be dinstinguished on their own, and we vaguely say that after assignment, the variable assigned to refers to the same function as the value being assigned.
Thoughts?
alercah
commented
Apr 30, 2017
•
|
After running into this one again myself, here's a thought. I think the issue is actually most significant for maps and channels, because they refer to programmer-invisible common state. While slices and pointers refer to common state as well, this state is much more explicitly exposed to the programmer for these types, while map and channel state is completely opaque. Functions are in practice similar as well, but because there are no modifying operations on functions, this is irrelevant (an implementation which actually passed around executable code would perhaps have authors in need of a stern talking to, but would not otherwise be an issue). So I think this could be resolved by:
Thoughts? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
griesemer
May 9, 2017
Contributor
@alercah Thanks for your suggestions! I can't respond in a meaningful way at the moment as this is a non-urgent issue and I haven't spent any time thinking about it more seriously. Just wanted to acknowledge that your feedback is appreciated.
|
@alercah Thanks for your suggestions! I can't respond in a meaningful way at the moment as this is a non-urgent issue and I haven't spent any time thinking about it more seriously. Just wanted to acknowledge that your feedback is appreciated. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alercah
May 9, 2017
For sure! Some follow-up clarifications:
- I found the section about composite literal being a shorthand for declaring a variable and taking its address, it just wasn't where I expected it so I missed it when writing the above comment.
- For interface assignment, it should also obviously assign the type too.
- See also my comments in #20181
alercah
commented
May 9, 2017
|
For sure! Some follow-up clarifications:
|
robpike commentedMar 19, 2013