Live data from Hacker News

Go structs are copied on assignment (and other things about Go I'd missed)

jvns.ca

141–150 of 176 posts

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#142
post #123

Earlier quoted context omitted.

Is it not pass-by-reference by some technicality? In the mutation example you suggest, if a reference to x isn't being passed into foo, how could foo modify x? I would sooner believe the example is showing you shadowing the z argument to foo, than foo being able to modify the in-parameter sometimes even if it's pass by value.

"In the mutation example you suggest, if a reference to x isn't being passed into foo, how could foo modify x?" Because it is passing a pointer by value under the hood. This is the part that messes everyone up. Passing pointers by value is not what passing by reference used to mean. And it matters, precisely because that is extremely realistic Python code that absolutely will mess you up if you don't understand exact…

Sure, but in the traditional sense of pass-by-reference you could say it's just always pass-by-value, and that value is always a reference. It's just not a helpful thing to say. (In those traditional pass by reference languages, was it impossible to pass a scalar to a function?)

Passing a pointer-by-value similarly seems to be avoiding the point; if you tell me Python is always pass-by-value I'll expect an object I pass to a function to be a copy & not a reference, thus not be able to be mutated, and that's not the case.

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#143

Earlier quoted context omitted.

Is it not pass-by-reference by some technicality? In the mutation example you suggest, if a reference to x isn't being passed into foo, how could foo modify x? I would sooner believe the example is showing you shadowing the z argument to foo, than foo being able to modify the in-parameter sometimes even if it's pass by value.

> In the mutation example you suggest, if a reference to x isn't being passed into foo, how could foo modify x The important point is that it's not "a reference to x" that gets passed, it's a copy of x's value. x's value, like the value of all Python variables, is a reference to some object. The same thing applies to setting variables in Python in general: x = {1:2} # x is a new variable that references some dict y =…

This is what confuses me; it sounds like what you're saying is Python isn't pass-by-reference, it's pass-by-value, and that value is sometimes a reference?

Honestly, "x's value, like the value of all Python variables, is a reference to some object" makes me think it's more accurate to call Python pass-by-reference only.

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#144

Earlier quoted context omitted.

You are splitting hair, Maps are effectively references. That's like saying C++ doesn't have references since it's just a pointer being copied around

No, there is a real difference, this is not splitting hairs. Go is always pass-by-value, even for maps [0]: x := map[int]int{1: 2} foo(x) fmt.Printf("%+v", x) //prints map[1:2] func foo(a map[int]int) { a = map[int]int{3: 4} } In contrast, C++ references have different semantics [1]: std::map x {{1, 2}}; foo(x); std::print("{%d:%d}", x.begin()->first, x.begin()->second); //prints {3:4} void foo(std::map & a) { a = st…

foo is receiving a mutable reference and it can't modify the map without those changes leaking out permanently to the caller: https://go.dev/play/p/DXchC5Hq8o8. Passing maps by value would have prevented this by copying the contents.

It's a quirk of C++ that reference args can't be replaced but pointer args can.

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#145

Earlier quoted context omitted.

> There's a good argument for immutability by default, but many programmers dislike all the extra declarations required. That's one little reason why Rust is loved by many: immutability by default. Meanwhile, it's not even possible in Go to declare immutable variables!

I hope it gets added, it adds so much safety to the language. Mind you, Go is not a very safe language in general, its type system is pretty loose compared to e.g. Java or Typescript. I don't believe it wants to be though.

[dead]

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#146
post #120

Earlier quoted context omitted.

I hope it gets added, it adds so much safety to the language. Mind you, Go is not a very safe language in general, its type system is pretty loose compared to e.g. Java or Typescript. I don't believe it wants to be though.

It is possible to add more immutability in Go. There are many proposals for this: https://github.com/go101/go101/wiki/Go-immutable-value-propo... . The main reason nothing happened in this direction is the core team think it is not important enough.

It's tough to retrofit new restrictions to old code. C/c++ code still doesn't have "const" everywhere it could. You have to make the default immutable - write "var" or "mut", not "const" - or it doesn't get used everywhere it should. But that breaks old code.

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#147
post #59

Earlier quoted context omitted.

C++ is a live language, C# has out parameters.... there's stuff out there. The classic example of "pass by copy-reference is less expressive" is you can't have pass a reference to number and have the caller modify it. You have to explicitly box it. I understand you understand this, but it's worth considering when thinking about whether the distinction means absolutely nothing at all.

> The classic example of "pass by copy-reference is less expressive" is you can't have pass a reference to number and have the caller modify it. This is really not true. Depending on how your language implements pass-by-reference, you can pass a reference to an int without boxing in one of two ways: either pass a pointer to the stack location where the int is stored (more common today), or simply arrange the stack in…

Hmmm... yeah that's a good point. Though I would contend that the fact that languages do not do this is indicative of... something.

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#148
post #118
post #78

Earlier quoted context omitted.

Immutable by default is only really possible now that we have gobs of memory though. I'm not even sure it's likely to stay popular: the demands of data processing at scale mean we're all likely to be routinely handling gigantic datasets which we don't want to copy all over the place. The real problem is just visibility: am I editing a copy of the original? Who else can edit the original? Who's going to? I'd argue tho…

LLVM will transform your mutable program into immutable one anyway because otherwise it's much harder if not impossible to write a lot of optimizations or validations. You can collapse a lot of the additional copies at compile time even for C

That's not really the same thing though - that's a choice of representation for optimization purposes. LLVM won't turn a pointer access into a value copy - it can't, because that would change program behavior.

The distinction here is that in a lot of cases, you really do want to edit data in one location and there's no good reason for it to be copied except that it makes the program easier to reason about (exceptions apply for when things like cache locality considerations come into play).

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#149

Earlier quoted context omitted.

most of the time when people don't ask questions in industry, it isn't because they already know the answers, it's because they don't care what the answers are blogging is culturally different because there's way more exhibitionism involved

Don't you think, as others in this thread are saying, that one reason people don't ask questions is because they're afraid to admit their lack of knowledge? We've probably all been in one of those meetings where something is being proposed, and everyone is nodding vaguely along but you're not sure the proposal is correct. Do you ask a clarifying question (and risk seeming foolish for not knowing something obvious) or…

> Do you ask a clarifying question (and risk seeming foolish for not knowing something obvious) or just let it pass because everyone else seems happy with it?

Two different kinds of foolish here: etiquette or technical

In some meetings if it's management and senior leadership grilling a design, if some unrelated IC butts in with a bunch of questions that are 5 steps behind everyone else it's sort of a faux pas

Re: Go structs are copied on assignment (and other things about Go I'd missed)

#150

Earlier quoted context omitted.

No, there is a real difference, this is not splitting hairs. Go is always pass-by-value, even for maps [0]: x := map[int]int{1: 2} foo(x) fmt.Printf("%+v", x) //prints map[1:2] func foo(a map[int]int) { a = map[int]int{3: 4} } In contrast, C++ references have different semantics [1]: std::map x {{1, 2}}; foo(x); std::print("{%d:%d}", x.begin()->first, x.begin()->second); //prints {3:4} void foo(std::map & a) { a = st…

foo is receiving a mutable reference and it can't modify the map without those changes leaking out permanently to the caller: https://go.dev/play/p/DXchC5Hq8o8 . Passing maps by value would have prevented this by copying the contents. It's a quirk of C++ that reference args can't be replaced but pointer args can.

The point is that the local variable referencing the map is a different entity than the map itself. Foo gets a copy of that local variable, and the copy references the same map object.

And the fact that C++ references can be used for assignment is essentially their whole point, not "a quirk".

Post reply on HN