Go is not really 'pass by value' when passing slices. It just passes the pointer value instead of doing a deep copy(copying the backing array). When trying to grow a slice in a function, the result is unpredicted because of 'apend' implicitly choosing to allocate memory or not. In addition, it is not concurrent-safe to pass mutable data. To avoid the safety problem, you have to copy stuff and consequently suffer a performance penalty. A better way to solve the problem is to introduce immutibilty. If one day immutibilty is introduced in Go 2(or 3), i wish slices are really passed by value. Then everything is passed by value as default with the immutable data passed by reference. You can still use pointers to pass mutable data just like using '_' to explicitly ignore error handling.
Now in WAT 1,
func grow(s []int) { // s is deep copied.
s = append(s, 4, 5, 6) // changing 's' does not effect original slice.
}
Explicitly pass mutable slice,
func grow(s *[]int) { // s is referenced.
*s = append(*s, 4, 5, 6) // changing 's' will always effect origin slice.
}
Now in WAT 1,
Explicitly pass mutable slice, Explicit is better than implicit.