Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Clear mutable semantics or clear immutable semantics but please, don't give us a mushy combination of the two.

In other words, the operation "append to an alias for this slice" should either consistently modify this slice or consistently not modify this slice. Behavior of "sometimes modifies this slice and sometimes doesn't" is, in my opinion, a serious API/language design failure.



The use of `append` is absolutely clear. It always returns a new slice; the compiler forces you to take the value returned.

What scares you is the possibility that the underlying array may be copied to a newer, larger array giving enough space for the appended items. If there exists enough space, why bother with a new allocation? I want `append` to handle this for me. If you want different behavior, you can easily setup your own design with `copy`

Regarding this blog post, if you have multiple slices to the same array and are arbitrarily appending to any of those slices, then your design is wrong to begin with.

This isn't an edge-case but a lack of slice understanding.


You're describing how it actually works which is by way of 'shallow value' semantics which is precisely what the commenter is against. Such semantics requires understanding implementation without a simple opaque description. Either full mutability or 'deep value' semantics is simpler. For instance if the b: = a; followed by a[0] = 2 resulted on a copy on write, then b would be unaffected after the assignment of value. Of course the language and libraries do what they do and the user must be aware. Go was supposed to be easier, so copy-on-write semantics would have made more sense.


I'm not sure what you're trying to say. This is, IMO, nothing more than a lack of understanding. Is the result of `a := make([]struct{}, 0, 1); b := a; b = append(b, struct{}{}); println(len(a), len(b))` also surprising?


Your understanding is incorrect, too. append() only returns a new slice when "the capacity of s is not large enough to fit the additional values", in which case "append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array."

[-] http://golang.org/ref/spec#Appending_and_copying_slices


No, nicksardo's understanding was quite correct. Slices are values, and it is impossible to return the same one, because value semantics don't work like that.

The slice returned only points to a new array when the capacity is not large enough to fit additional values.


You seem to be confusing `array` with `slice`. AFAIK, append always returns a new slice. How could it not, when everything is copy/pass by value? A slice is essentially a struct with fields for len, cap and a pointer to an array.


Go's all about practicality over ideological purity. This article was unsurprising to me ('cuz I know how slices work!), and in fact, is an obvious consequence of the design of slices. Personally I like that design -- it is just enough to be both simple and powerful.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: