Live data from Hacker News

There is no pass by reference in Go

dave.cheney.net

41–50 of 70 posts

Re: There is no pass by reference in Go

#41

Earlier quoted context omitted.

And yet this is the reality we live in. No matter how much talk of "should", the reality stares you implacably in the face. This is a UX problem. Practically speaking, the most important concept is that of cost, which the naive answer covers. The distinction only matters in a language that actually differentiates the two. Otherwise it's little more than trivia, and certainly nothing to get worked up over.

The difference between pass-as-reference and pass-by-reference is more than trivia - if you were ignorant of it in a language, you might find trouble in the future when a function decides to alter its argument values in a way that negatively affects the caller. Part of the reason we should work to clarify the language is to avoid misconceptions about behaviour based on what kind of "reference" is meant.

A language with pointers also allows a function to alter its logical (not syntactical) argument values in a way that negatively affects the caller.

There isn't much practical difference between using

    // void c_func_alters_deref_pfoo(Foo * pfoo)
    Foo foo = { ... };
    c_func_alters_deref_pfoo(&foo);
and

    // void cpp_func_alters_foo(Foo & foo)
    Foo foo = { ... };
    cpp_func_alters_foo(foo);
besides the ability to pass null or otherwise invalid pointers in the C-style version, which can (depending on situation) either simplify your API or be a source of bugs.

Re: There is no pass by reference in Go

#42
post #10

An extended explanation missing from Dave Cheney's answer is that the "reference" etymology has at least 2 meanings. This is why his explanation is virtually the same as the one 20 years ago in the C Language FAQ[1] compiled by Steve Summit. - "reference" definition 1: an alias that cannot be null which is what a "reference type" is in Pascal and C++. This might be thought of as a stricter "computer-science" definiti…

And Java just added to the problem.

For PR reasons, they didn't want to have "pointers" (arithmetic, etc. ew). So Java has "references".

But what happens when you call a method on a null reference? Not NullReferenceException, but NullPointerException.

Re: There is no pass by reference in Go

#43
post #10

An extended explanation missing from Dave Cheney's answer is that the "reference" etymology has at least 2 meanings. This is why his explanation is virtually the same as the one 20 years ago in the C Language FAQ[1] compiled by Steve Summit. - "reference" definition 1: an alias that cannot be null which is what a "reference type" is in Pascal and C++. This might be thought of as a stricter "computer-science" definiti…

Thank you sir for pointing this out. I recently ran into a similar argument with an Oracle trainer whether Java has pass-by-reference semantics. The entire Java community seems adamant that Java has no pass-by-reference, but only pass-by-value. This blog post reminds me of that argument.

In Java, Python, Javascript and many other languages, objects pointers are passed by value, but the contents of which are shared between the caller and the callee, so the modification of which is visible from both sides. If we take the definition of pass-by-reference or call-by-reference semantics to mean that, then these languages are pass by reference by default. Apparently, that's not the definition, which in my opinion is rather strange that we are still stuck in a definition that predates OOP, when people mostly concerned with simple primitive values as opposed to composites.

It appears that Barbara Liskov has recognised this and coined call-by-sharing in 1974. 43 years later, practitioners are still arguing in the C++ frame of mind and failed to disseminate the more modern and suitable term of call-by-sharing. This is rather disappointing to me.

Re: There is no pass by reference in Go

#44
post #33

"Maps and channels are not references." But then refer to the Go team's article on maps: Map types are reference types, like pointers or slices, and so the value of m above is nil; it doesn't point to an initialized map. A nil map behaves like an empty map when reading, but attempts to write to a nil map will cause a runtime panic; don't do that. To initialize a map, use the built in make function: m = make(map[strin…

IMHO saying they are is misleading as this article correctly points out nothing is, and Rob Pike himself has pointed out the same on many occasions. They are referred to as "reference types" because they contain pointers to the underlying data structure. However the thing stored in the variable is more than just a pointer, and it is passed by value.

Knowing the difference can have important ramifications; particularly in the case of a slice which has its header copied when passed to a function.

Re: There is no pass by reference in Go

#45
post #35
post #10

An extended explanation missing from Dave Cheney's answer is that the "reference" etymology has at least 2 meanings. This is why his explanation is virtually the same as the one 20 years ago in the C Language FAQ[1] compiled by Steve Summit. - "reference" definition 1: an alias that cannot be null which is what a "reference type" is in Pascal and C++. This might be thought of as a stricter "computer-science" definiti…

Aren't reference variables just syntactic sugar on top of pointers? I've seen this debate about pointers vs. references so many times that I'm starting to think I might be missing something.

This has always bugged me too. I don't understand why people make such a big deal about pass-by-value and pass-by-reference when the latter is essentially a small layer of syntactic sugar over the former. Anything you can do with reference variables can be done with pointers, with a few more characters (and arguably easier to read, if you're not used to reference variables), so from a semantic point of view it doesn't add anything new.

PBV and PBR seems to be a tiny distinction and yet, we have blog posts and interview questions and online debates about whether a language falls into the first or second category.

Re: There is no pass by reference in Go

#47
post #10

An extended explanation missing from Dave Cheney's answer is that the "reference" etymology has at least 2 meanings. This is why his explanation is virtually the same as the one 20 years ago in the C Language FAQ[1] compiled by Steve Summit. - "reference" definition 1: an alias that cannot be null which is what a "reference type" is in Pascal and C++. This might be thought of as a stricter "computer-science" definiti…

And Java just added to the problem. For PR reasons, they didn't want to have "pointers" (arithmetic, etc. ew). So Java has "references". But what happens when you call a method on a null reference? Not NullReferenceException, but NullPointerException.

>For PR reasons, they didn't want to have "pointers" (arithmetic, etc. ew). So Java has "references"

Well, it's just a rename for PR reasons. They actually don't have pointers.

>But what happens when you call a method on a null reference? Not NullReferenceException, but NullPointerException.

That's because it's the underlying pointer access that causes the exception. Doesn't mean the reference is itself a pointer -- it just abstracts over one.

Re: There is no pass by reference in Go

#48
post #10

An extended explanation missing from Dave Cheney's answer is that the "reference" etymology has at least 2 meanings. This is why his explanation is virtually the same as the one 20 years ago in the C Language FAQ[1] compiled by Steve Summit. - "reference" definition 1: an alias that cannot be null which is what a "reference type" is in Pascal and C++. This might be thought of as a stricter "computer-science" definiti…

And Java just added to the problem. For PR reasons, they didn't want to have "pointers" (arithmetic, etc. ew). So Java has "references". But what happens when you call a method on a null reference? Not NullReferenceException, but NullPointerException.

They also insists Java is pass-by-value whereas technically it's pass-by-value for primitive unboxed types and call-by-sharing for others. The reason of which escapes me.

Re: There is no pass by reference in Go

#49
C# has a name for Go's object semantics: Marshal By Reference. This means that when an object features in a call, the GC pointer aka reference is passed (by value) rather than the object value itself. This reference is fundamentally different from the reference concept in C++. So the term reference is semantically overloaded and means different things in different programming languages. However, the phrase "pass by reference" is language independent and the author is correct, it doesn't have those semantics.

Re: There is no pass by reference in Go

#50
When teaching, rather than using a special name like "pointer", wouldn't it be better to simply explain that it's a variable that holds a memory address? Once a student (e.g. who only knows a high-level language) understands that they now have to think about memory explicitly, then the behavior of such a variable will become obvious. AFAIU there are only two special features of pointers: the dereference operation and the additive arithmetic which increments in strides according to their type.
Post reply on HN