Live data from Hacker News

There is no pass by reference in Go

dave.cheney.net

61–70 of 70 posts

Re: There is no pass by reference in Go

#61
post #29
post #26

Earlier quoted context omitted.

You are correct that C also does not have pass-by-reference. However, the second listing is a C++ program, not a C program, and C++ very much has pass-by-reference. The C++ program demonstrates true aliases, as you can tell from the output of the printf (see comment on same line).

I have always found that is conflating the semantics of using with the method of passing . Even with/out aliases you are still passing a reference.

I don't think that's accurate. I can pass something locally declared as int to a fn that takes int& according to it's signature. It seems that's precisely what the confusion is about :)

Re: There is no pass by reference in Go

#62
post #21

Earlier quoted context omitted.

In all of those cases, you're probably passing a reference by value, semantically. ("Probably", because you didn't specify which languages, so I'm making an educated guess.) The usual litmus test is having two objects (or ints or whatever), write a fn `swap(a, b)` where the two are swapped after the call is over. Can't do that in Java or Go or Python or C; but you can in e.g. C++ and you sorta-can in Lisp. In C++, yo…

Just to be clear, the rules of your swap challenge are that the arguments of the function have to be ints, not allowed to be int *, right? Also you say "two objects", but if the objects were compound, e.g. arrays, then I could write swap in C.

Yes. It's about swapping the arguments. With a struct or an array or a pointer or whatever, you're not swapping the arguments themselves; but the fact that there are so many things that do something slightly similar probably illustrates the limited utility of pass-by-reference.

Re: There is no pass by reference in Go

#63
post #60

Earlier quoted context omitted.

> They actually don't have pointers. They do. Everywhere. Every Java variable of Object type is a pointer. (Also, they're all nullable....ugh.) If Java had real references (see original comment by jasode) you'd be able to write something like C#'s int.TryParse ( https://msdn.microsoft.com/en-us/library/f02979c7(v=vs.110).... ).

> Every Java variable of Object type is a pointer. No, it's a reference. It just has a pointer underneath. > If Java had real references (see original comment by jasode) you'd be able to write something like C#'s int.TryParse If Java had one specific type of references. The common use of the term though is still what Java has.

> The common use of the term though is still what Java has.

The way you are defining "reference" makes it immaterially different from "pointer".

Can a pointer be null? Yes, in C.

Can a "reference" be null? Yes, in Java.

Can a pointer be used in arithmetic operations? Yes, in C.

Can a pointer not be used in arithmetic operations? Yes, in Go.

If this is really the common definition, it isn't a useful one.

Re: There is no pass by reference in Go

#64
post #60

Earlier quoted context omitted.

> Every Java variable of Object type is a pointer. No, it's a reference. It just has a pointer underneath. > If Java had real references (see original comment by jasode) you'd be able to write something like C#'s int.TryParse If Java had one specific type of references. The common use of the term though is still what Java has.

> The common use of the term though is still what Java has. The way you are defining "reference" makes it immaterially different from "pointer". Can a pointer be null? Yes, in C. Can a "reference" be null? Yes, in Java. Can a pointer be used in arithmetic operations? Yes, in C. Can a pointer not be used in arithmetic operations? Yes, in Go. If this is really the common definition, it isn't a useful one.

Whether a thing can be null or not is orthogonal to whether it is a pointer or a reference.

The main difference in this definition is on whether you need to dereference to access the value pointed at (like you do in C) or not.

Re: There is no pass by reference in Go

#65
post #64

Earlier quoted context omitted.

> The common use of the term though is still what Java has. The way you are defining "reference" makes it immaterially different from "pointer". Can a pointer be null? Yes, in C. Can a "reference" be null? Yes, in Java. Can a pointer be used in arithmetic operations? Yes, in C. Can a pointer not be used in arithmetic operations? Yes, in Go. If this is really the common definition, it isn't a useful one.

Whether a thing can be null or not is orthogonal to whether it is a pointer or a reference. The main difference in this definition is on whether you need to dereference to access the value pointed at (like you do in C) or not.

Not sure I understand you. A concrete PHP example:

   function noop($a, $b) {
     $tmp = $a;
     $a = $b;
     $b = $tmp;
   }

   function swap(&$c, &$d) {
      $tmp = $c;
      $c = $d;
      $d = $tmp;
   }

   $first = [1, 2];
   $second = [3, 4];
   noop($first, $second);
   swap($first, $second);
   
$a and $b work much differently than $c and $d.

I would call the first two pointers (to [1,2] and [3,4]), and the latter two references (to $first and $second). What would you call them?

(Note: the latter function is impossible to write in Java.)

Re: There is no pass by reference in Go

#66
post #20

Earlier quoted context omitted.

Indeed. Definition 2 is broadly in line with what "reference" means in general usage, while definition 1 is a term of art in the vocabulary of certain languages. Before languages had reference types or pointers, the distinction between pass-by-reference and pass-by-value (or also pass-by-name in Lisp and Algol) told you important things about the semantics of the language, such as whether a function you called could…

It may be what reference means, but just because a language has references doesn't mean that it is passing-by-reference. There are plenty of languages that allow actual pass-by-ref, like C++. The usual litmus test is writing a function that takes two ints (not int refs!) and they're swapped at the end. In C++, you can tell because of "int&" in the signature of the function you're calling; as opposed to plain int. In…

"If I call a function f(a, b), I know that a, b are still pointing at the same object in e.g. Python."

  def f(x):
    global a
    a = "No, you don't"

  a = "I know"
  f(a)
  print a
This counterexample may be far-sought, but it is a minimal version of what can easily happen in larger programs that have shared mutable state.

But yes, call by reference can be confusing. It also can be very useful, though. That's why many modern languages have call by reference, but also require callers to specify it at each call site. I think that gives you the best of both worlds.

Re: There is no pass by reference in Go

#67
C++:

  void f(map m)
  {
  	m[0] = 0;	
  }

  int main() {
  	map t;
  	t[0] = 1;
  	f(t);
  	cout 
prints 1.

Go:

  func f(m map[int]int) {
  	m[0] = 0
  }

  func main(){
  	var t = make(map[int]int)
  	t[0] = 1
  	f(t)
  	fmt.Println(t[0])
  }
Prints 0.

So in C++ maps are passed by value. In Go they are passed by, hmm, "not value".

Go could have made maps similar to C++ maps and then people could use a pointer to a map when they wanted that. As it stands maps are "different" which is not a big deal once you're used to it but still makes things a little weird if you're coming from C++.

Re: There is no pass by reference in Go

#68
post #64

Earlier quoted context omitted.

Whether a thing can be null or not is orthogonal to whether it is a pointer or a reference. The main difference in this definition is on whether you need to dereference to access the value pointed at (like you do in C) or not.

Not sure I understand you. A concrete PHP example: function noop($a, $b) { $tmp = $a; $a = $b; $b = $tmp; } function swap(&$c, &$d) { $tmp = $c; $c = $d; $d = $tmp; } $first = [1, 2]; $second = [3, 4]; noop($first, $second); swap($first, $second); $a and $b work much differently than $c and $d. I would call the first two pointers (to [1,2] and [3,4]), and the latter two references (to $first and $second). What would…

>I would call the first two pointers (to [1,2] and [3,4]), and the latter two references (to $first and $second). What would you call them?

In the first case, $a and $b pass the arrays by copying their values. The second example uses references.

Java can't do the change visible externally because it passes its references by value -- but that's not a necessity for all languages with references.

As the PHP manual itself says: "References in PHP are a means to access the same variable content by different names. They are not like C pointers; for instance, you cannot perform pointer arithmetic using them, they are not actual memory addresses, and so on".

Re: There is no pass by reference in Go

#69

However, Go has pointers (just not pointer arithmetic): https://tour.golang.org/moretypes/1 Does anyone know of an imperative language doesn't have references, but also doesn't have pointers? Perhaps using something like copy-on-write to pass variables to functions.

[deleted]

Re: There is no pass by reference in Go

#70
post #59

Earlier quoted context omitted.

I've got a credit in a game by pointing out that the reason the teams tools kept segfaulting was because the authors believed that if they had a reference they didn't need to check it for null. Unfortunately, they'd assign these references from pointers that could totally be null, and didn't error check at that point. References in C++ can totally be null.

That's undefined behavior. References in valid C++ cannot be null.

I can write a method that is valid C++, but it gets called by something that isn't valid C++. If I don't check for null references, then my method will crash. My method is valid C++, and yet it gets a null reference. So clearly, references in valid C++ can be null, and must be checked for.
Post reply on HN