Live data from Hacker News

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

jvns.ca

91–100 of 176 posts

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

#91
post #78

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!

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…

Immutable by default doesn't mean you have to write your program as a giant copy-aon-write or log-structured architecture. You can still commit all your shared global program state behind a mutex/rwlock crimes when that makes sense. But you can contain write access to that data to the places where it's needed.

And at the function-local level move elision should turn copy-and-modify to in-place modification if the original is no longer used.

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

#92
post #86

It's sad that most of the items are clear language design mistakes stemming from the creators not learning from other languages. Go is a missed opportunity. Item after item of "yeah that wouldn't happen in rust". The list feels like it's meant to blame the programmer, but that ain't right.

This drives me crazy. Go essentially doubles down on all the programming language mistakes we spent decades discovering and finding solutions for.

When people ask all those questions about why software is still so terrible in all sorts of ways, a large part of the answer is languages like C, C++, JavaScript, Python, and now Go.

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

#93
post #78

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!

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…

"Immutable by default is only really possible now that we have gobs of memory though"

I don't think so, actually. It's just changing the default. A choice to have types like Java's String which are always immutable might drive up memory usage, but just realising that the defaults are wrong and altering the language doesn't impact this at all, instead it makes your programs more explicit about what's actually happening.

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

#94

thing := Thing{...} other_thing := thing pinter_to_same_thing := &thing ALL types in go are being copied by value. There is no such thing as a "reference" in this language. Even a slice or map is just a small struct with some syntactic sugar provided by the language, and when you assign a slice to another variable, you are, in fact, creating a copy of that struct.

My pet peeve with slices and maps is that they hide a reference to the actual structure, and you are never sure of what you are modifying, or the performance impact when moving around big structures.

Example with slices: https://go.dev/play/p/8arcUrGU4SU

Example with maps: https://go.dev/play/p/eq8i6z8a4jN

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

#95
post #53

The semantics of when stuff is copied, moved, or passed by reference are all over the place in language design. C started with the idea that functions returned one int-sized value in a register. This led to classic bugs where the function returns a pointer to a local value. Compilers now usually catch this. C eventually got structure return by copy. Then C++ added return value by move, and automatic optimization for…

Actually Go is always pass by value. Even when you pass the pointer you’ll get a copy of it.

What matters is that a function can modify the value pointed at, without necessarily returning it.

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

#96
For me, who came from PHP, the way Go works seemed the most natural. PHP is also one of very few (old) languages which makes everything pass-by-value (except for objects, which initially also were pass-by-value but it was so confusing for people coming from other languages that they changed it).

Treating everything as a value IMO is quute nice _if you except it_, because it eliminates a whole class of possible side effects from mutating the value inside the receiver, without requiring extra complexity like immutability in the language itself.

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

#97
Something that strikes me about Go's approach here, and the explanations in many of the posts on this page, are that they're all focused on what is happening under the hood: What memory are we pointing at, what's being copied, is it a pointer etc etc.

Whereas if we start from a point of view of "What semantics and performance guarantees do we desire?", we might end up with a more coherent user-facing interface (even if internally that leads to something more complex).

Personally, my mental model is often influenced by Python - where a name is distinct from a variable, but this distinction doesn't seem to appear in many other languages.

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

#98
post #94

thing := Thing{...} other_thing := thing pinter_to_same_thing := &thing ALL types in go are being copied by value. There is no such thing as a "reference" in this language. Even a slice or map is just a small struct with some syntactic sugar provided by the language, and when you assign a slice to another variable, you are, in fact, creating a copy of that struct.

My pet peeve with slices and maps is that they hide a reference to the actual structure, and you are never sure of what you are modifying, or the performance impact when moving around big structures. Example with slices: https://go.dev/play/p/8arcUrGU4SU Example with maps: https://go.dev/play/p/eq8i6z8a4jN

No, there is no "hiding" of a "reference". There is copying a struct:

    s2 := s1
This copies the struct in `s1` into a new name `s2`. This struct contains, among other things, a pointer to the backing array. Therefore, when you assign to the slice

    s2[0] = "bye"
You assign to the same backing array. Slices are not arrays. Copying a slice copies a struct containing a pointer to an array. A similar situation holds true for maps. The same logic that is universal throughout the language, aka. "Go only ever copies things by value" holds true for all of these types.

https://go.dev/ref/spec#Slice_types

"A slice, once initialized, is always associated with an underlying array that holds its elements. A slice therefore shares storage with its array and with other slices of the same array; by contrast, distinct arrays always represent distinct storage."

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

#99
post #53

The semantics of when stuff is copied, moved, or passed by reference are all over the place in language design. C started with the idea that functions returned one int-sized value in a register. This led to classic bugs where the function returns a pointer to a local value. Compilers now usually catch this. C eventually got structure return by copy. Then C++ added return value by move, and automatic optimization for…

Well, that's another nice thing with Rust. Maybe it's not the saviour language but at least it brings clarity to ownership of values.

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

#100
post #78

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!

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…

Immutability isn’t a new idea, and you don’t need “gobs of memory.” Erlang was developed in the 80’s.
Post reply on HN