What is called reference values in Golang?

347 views
Skip to first unread message

T L

unread,
Oct 19, 2016, 6:27:20 AM10/19/16
to golang-nuts
.

Jan Mercl

unread,
Oct 19, 2016, 6:33:09 AM10/19/16
to T L, golang-nuts
On Wed, Oct 19, 2016 at 12:27 PM T L <tapi...@gmail.com> wrote:

Nothing. The language specification does not mention it.

People use that term based on definitions specified for other programming languages, but those are not always equal to each other.
--

-j

adon...@google.com

unread,
Oct 19, 2016, 12:44:26 PM10/19/16
to golang-nuts, tapi...@gmail.com

Jan is write that the term does not appear in the spec, but I think it's possible to come up with a useful definition of a reference type that applies to all ALGOL-like languages: a reference type is one whose values indirectly refer to mutable state.  So, pointers are obviously references, as are slices, maps, and channels.  But a string is not a reference because, although internally it contains a pointer, you cannot mutate the array of bytes to which it refers.  Functions may be references, because a closure may refer to lexically enclosing variables.  Structs and arrays are references if their elements contain references.  An interface value is a reference if its payload contains a references.

The essence of a reference is that copying one creates a new alias for its underlying state, and changes made via one alias are visible to all others.  This definition is not absolute: a pointer to an immutable data structure, for example, can be considered to have "value" (non-reference) semantics since although it points to a variable, that variable can never be changed.


Message has been deleted

T L

unread,
Oct 20, 2016, 3:07:07 AM10/20/16
to golang-nuts, tapi...@gmail.com, adon...@google.com

So reference values must be pointer related? Reference values can be direct pointer values or pointer wrapper values, people can modify the values pointed by the pointers directly or indirectly (through the methods or other mechanisms exposed on the reference value identifier)?

Dave Cheney

unread,
Oct 20, 2016, 4:46:52 AM10/20/16
to golang-nuts, tapi...@gmail.com, adon...@google.com
What is a pointer wrapper value?

in all seriousness, if you review the git history of the Go spec you'll find the word "reference" was purged about two years ago, in effect, to try to stem these discussions.

Val

unread,
Oct 20, 2016, 7:31:25 AM10/20/16
to golang-nuts, tapi...@gmail.com, adon...@google.com
I like Alan's "useful definition" of a semantically reference type, which involves shared mutable state.

About the string type, I also like the implementation detail that
 
var string t = s

is O(1) in memory and running time, i.e. it happens internally to "copy the reference, not the bytes" :  see https://play.golang.org/p/p-PD_yOnw6
It usually doesn't make much of a difference because most strings are short, and also they are not the best data structure to manipulate data (unlike []byte). But I take this implementation detail into account when I want to optimize code, especially to reduce the need for memory allocation.

T L

unread,
Oct 20, 2016, 9:47:36 AM10/20/16
to golang-nuts, tapi...@gmail.com, adon...@google.com


On Thursday, October 20, 2016 at 4:46:52 PM UTC+8, Dave Cheney wrote:
What is a pointer wrapper value?

struct {
   p *T
}
 

in all seriousness, if you review the git history of the Go spec you'll find the word "reference" was purged about two years ago, in effect, to try to stem these discussions.

Yes, I found many old docs and old web pages are still using the word "reference value".
I think it is an unnecessary word. The concepts of values and pointer values are sufficient to understand Golang values well.
 

T L

unread,
Oct 20, 2016, 9:58:46 AM10/20/16
to golang-nuts, tapi...@gmail.com, adon...@google.com


On Thursday, October 20, 2016 at 7:31:25 PM UTC+8, Val wrote:
I like Alan's "useful definition" of a semantically reference type, which involves shared mutable state.

About the string type, I also like the implementation detail that
 
var string t = s

is O(1) in memory and running time, i.e. it happens internally to "copy the reference, not the bytes" :  see https://play.golang.org/p/p-PD_yOnw6
It usually doesn't make much of a difference because most strings are short, and also they are not the best data structure to manipulate data (unlike []byte). But I take this implementation detail into account when I want to optimize code, especially to reduce the need for memory allocation.

So, comparing two long same stings at the first time may spend much time?

It looks strings are much like interfaces here: https://play.golang.org/p/fEzxkzLfS2
 

T L

unread,
Oct 20, 2016, 10:34:41 AM10/20/16
to golang-nuts, tapi...@gmail.com, adon...@google.com


On Thursday, October 20, 2016 at 9:58:46 PM UTC+8, T L wrote:


On Thursday, October 20, 2016 at 7:31:25 PM UTC+8, Val wrote:
I like Alan's "useful definition" of a semantically reference type, which involves shared mutable state.

About the string type, I also like the implementation detail that
 
var string t = s

is O(1) in memory and running time, i.e. it happens internally to "copy the reference, not the bytes" :  see https://play.golang.org/p/p-PD_yOnw6
It usually doesn't make much of a difference because most strings are short, and also they are not the best data structure to manipulate data (unlike []byte). But I take this implementation detail into account when I want to optimize code, especially to reduce the need for memory allocation.

So, comparing two long same stings at the first time may spend much time?

It looks golang 1.7.1 doesn't release one copy of underlying data after comparings:

https://play.golang.org/p/Lu9FZ9iqn6
https://play.golang.org/p/-wE2oUGce1
 

T L

unread,
Oct 20, 2016, 11:37:50 AM10/20/16
to golang-nuts, tapi...@gmail.com, adon...@google.com


On Thursday, October 20, 2016 at 10:34:41 PM UTC+8, T L wrote:


On Thursday, October 20, 2016 at 9:58:46 PM UTC+8, T L wrote:


On Thursday, October 20, 2016 at 7:31:25 PM UTC+8, Val wrote:
I like Alan's "useful definition" of a semantically reference type, which involves shared mutable state.

About the string type, I also like the implementation detail that
 
var string t = s

is O(1) in memory and running time, i.e. it happens internally to "copy the reference, not the bytes" :  see https://play.golang.org/p/p-PD_yOnw6
It usually doesn't make much of a difference because most strings are short, and also they are not the best data structure to manipulate data (unlike []byte). But I take this implementation detail into account when I want to optimize code, especially to reduce the need for memory allocation.

So, comparing two long same stings at the first time may spend much time?

It looks golang 1.7.1 doesn't release one copy of underlying data after comparings:

https://play.golang.org/p/Lu9FZ9iqn6
https://play.golang.org/p/-wE2oUGce1

filed an issue: https://github.com/golang/go/issues/17526#issuecomment-255142005
and closed by the lighting issue closer. :)
 

Ian Lance Taylor

unread,
Oct 20, 2016, 1:11:32 PM10/20/16
to T L, golang-nuts, Alan Donovan
On Thu, Oct 20, 2016 at 6:47 AM, T L <tapi...@gmail.com> wrote:
>
> On Thursday, October 20, 2016 at 4:46:52 PM UTC+8, Dave Cheney wrote:
>>
>> What is a pointer wrapper value?
>
>
> struct {
> p *T
> }
>
>>
>>
>> in all seriousness, if you review the git history of the Go spec you'll
>> find the word "reference" was purged about two years ago, in effect, to try
>> to stem these discussions.
>
>
> Yes, I found many old docs and old web pages are still using the word
> "reference value".
> I think it is an unnecessary word. The concepts of values and pointer values
> are sufficient to understand Golang values well.

I have a minor objection. I don't know what a "reference value" is.
Alan spoke about "reference types", and sometimes, in the past, before
we realized that it was confusing, the Go docs also talked about
"reference types."

I don't think we ever talked about "reference values." Perhaps a
"reference value" is a value whose type is a "reference type."
However, people (not Go people, computer programming people in
general) also talk about "passing by reference" as opposed to "passing
by value", so combining the two opposing terms "reference" and "value"
into a single phrase is confusing.

Ian

T L

unread,
Oct 21, 2016, 1:47:21 AM10/21/16
to golang-nuts, tapi...@gmail.com, adon...@google.com

This faq, "Why are maps, slices, and channels references while arrays are values?", https://golang.org/doc/faq#references.
thinks maps, slices, and channels are references. I think the "references" here means "reference values".


 

Marvin Renich

unread,
Oct 21, 2016, 8:37:15 AM10/21/16
to golang-nuts
* T L <tapi...@gmail.com> [161021 01:47]:
> This faq, "Why are maps, slices, and channels references while arrays are
> values?", https://golang.org/doc/faq#references.
> thinks maps, slices, and channels are references. I think the "references"
> here means "reference values".

That's not the way I read it. The question is contrasting references
and values, as if they are two distinct things. Nowhere does it use the
phrase "reference value". Note that maps, slices, and channels are all
types, adding further evidence that "reference type" would fit better
than "reference value". Also, in that paragraph, it says "changing
these types to act as references...." The word value does not occur in
that sentence, but type does.

...Marvin

Ian Lance Taylor

unread,
Oct 21, 2016, 9:40:09 AM10/21/16
to T L, golang-nuts, Alan Donovan
> This faq, "Why are maps, slices, and channels references while arrays are
> values?", https://golang.org/doc/faq#references.
> thinks maps, slices, and channels are references. I think the "references"
> here means "reference values".

As Marvin said in his reply, it doesn't.

I'm not trying to say that "reference value" could not have a meaning.
I'm saying that I've never seen that phrase before, and given the long
history of discussions using these words I find it confusing.

Ian

Henrik Johansson

unread,
Oct 21, 2016, 9:53:14 AM10/21/16
to Ian Lance Taylor, T L, golang-nuts, Alan Donovan
The confusion I have had is rather with nilability.
A channel can be nil even though it is not explicitly a pointer.

The whole "call by reference" debate is fun but usually with beer...

--
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,
Oct 21, 2016, 10:01:43 AM10/21/16
to Henrik Johansson, T L, golang-nuts, Alan Donovan
On Fri, Oct 21, 2016 at 6:52 AM, Henrik Johansson <dahan...@gmail.com> wrote:
> The confusion I have had is rather with nilability.
> A channel can be nil even though it is not explicitly a pointer.

It's a basic design decision in Go that every type has a zero value.
For the "reference types" (pointer, channel, map, slice, interface)
that zero value is named "nil".

Ian

Henrik Johansson

unread,
Oct 21, 2016, 10:15:52 AM10/21/16
to Ian Lance Taylor, T L, golang-nuts, Alan Donovan
Yes and once that was clear it quickly became familiar but to people from other languages (a mix between Java and C perhaps) it can be confusing.

At first it bummed me out that these where special but it is easy to get used to it.

T L

unread,
Oct 21, 2016, 11:15:34 AM10/21/16
to golang-nuts, dahan...@gmail.com, tapi...@gmail.com, adon...@google.com

I have a question, should the following type be called reference type?

type T struct {
p *int
}
 

Ian

T L

unread,
Oct 21, 2016, 11:18:08 AM10/21/16
to golang-nuts, ia...@golang.org, tapi...@gmail.com, adon...@google.com


On Friday, October 21, 2016 at 9:53:14 PM UTC+8, Henrik Johansson wrote:
The confusion I have had is rather with nilability.
A channel can be nil even though it is not explicitly a pointer.

Someone think pointers should be distinguished from channel/map/slice/interface/function.
For example, like other languages, still use null for pointer zero values.
 

Alan Donovan

unread,
Oct 21, 2016, 11:20:44 AM10/21/16
to T L, golang-nuts, dahan...@gmail.com
By the definition I gave, yes, because an instance of T contains a reference to an int variable.  All copies of a given T value share the same int variable, and a change to that variable by any one will be observed by all the others.

T L

unread,
Oct 21, 2016, 11:31:59 AM10/21/16
to golang-nuts, tapi...@gmail.com, dahan...@gmail.com, adon...@google.com

I have never seen an official definition for "reference type". My understanding is "reference type is a pointer type or a pointer wrapper type", right?
 

Paul Borman

unread,
Oct 21, 2016, 11:37:21 AM10/21/16
to Alan Donovan, T L, golang-nuts, dahan...@gmail.com
I think you should clarify that this is because T only contains pointers.  If T were:

type T struct {
    i int
    p *int
}

then it would suddenly become  non-reference type, as defined in this thread, as a change to i will not be noticed by other copies of a given T.

    -Paul

--
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.

T L

unread,
Oct 21, 2016, 11:50:28 AM10/21/16
to golang-nuts, adon...@google.com, tapi...@gmail.com, dahan...@gmail.com


On Friday, October 21, 2016 at 11:37:21 PM UTC+8, Paul Borman wrote:
I think you should clarify that this is because T only contains pointers.  If T were:

type T struct {
    i int
    p *int
}

Ian says slice is also a reference type. This type declaration is much like slice type:

type Slice struct {
array *internalArray
len int
cap int
}
 

then it would suddenly become  non-reference type, as defined in this thread, as a change to i will not be noticed by other copies of a given T.

    -Paul
On Fri, Oct 21, 2016 at 8:20 AM, 'Alan Donovan' via golang-nuts <golan...@googlegroups.com> wrote:
On 21 October 2016 at 11:15, T L <tapi...@gmail.com> wrote:
On Friday, October 21, 2016 at 10:01:43 PM UTC+8, Ian Lance Taylor wrote:
On Fri, Oct 21, 2016 at 6:52 AM, Henrik Johansson <dahan...@gmail.com> wrote:
> The confusion I have had is rather with nilability.
> A channel can be nil even though it is not explicitly a pointer.

It's a basic design decision in Go that every type has a zero value.
For the "reference types" (pointer, channel, map, slice, interface)
that zero value is named "nil".

I have a question, should the following type be called reference type?

type T struct {
p *int
}

By the definition I gave, yes, because an instance of T contains a reference to an int variable.  All copies of a given T value share the same int variable, and a change to that variable by any one will be observed by all the others.

--
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.

Paul Borman

unread,
Oct 21, 2016, 11:53:45 AM10/21/16
to T L, golang-nuts, Alan Donovan, dahan...@gmail.com
Well, from that standpoint, any structure that has a pointer is a reference type.

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.

T L

unread,
Oct 21, 2016, 11:59:43 AM10/21/16
to golang-nuts, tapi...@gmail.com, adon...@google.com

Is it a good idea to remove the reference words from faq?
Go spec did this 3 years ago.
 

Alan Donovan

unread,
Oct 21, 2016, 12:10:24 PM10/21/16
to T L, golang-nuts
I am now enlightened as to why my colleagues were so eager to banish this term from our documentation.

Ian Lance Taylor

unread,
Oct 21, 2016, 1:13:43 PM10/21/16
to T L, golang-nuts, Alan Donovan
On Fri, Oct 21, 2016 at 8:59 AM, T L <tapi...@gmail.com> wrote:
>
> Is it a good idea to remove the reference words from faq?
> Go spec did this 3 years ago.

The question makes sense and needs an answer. If someone can rewrite
it to avoid the use of the word "reference" while also making it more
clear, then, sure.

Ian

Caleb Spare

unread,
Oct 21, 2016, 1:16:39 PM10/21/16
to Ian Lance Taylor, T L, golang-nuts, Alan Donovan
"goference"
Reply all
Reply to author
Forward
0 new messages