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

“Everything should be made as simple as possible, but no simpler.” I’ve often felt Go went too far trying to make everything simple, to the point that it’s wrapped around and made things complex.


"Civilization advances by extending the number of important operations which we can perform without thinking of them." --Alfred North Whitehead

Go forces writing loop for removing an element from an array even if the programmer knows it's linear time. Ruby gambles that programmer isn't ignorant - or it's not critical - but allows the convenience every time.

Designing languages is hard.


> Go forces writing loop for removing an element from an array

It does not:

copy(a[i:], a[i+1:]) // Shift a[i+1:] left one index.

a[len(a)-1] = "" // Erase last element (write zero value).

a = a[:len(a)-1]


Having worked a lot with at least a dozen languages, this is definitely on the cumbersome side of the spectrum. And a sibling comment says it doesn't even do what it says on the tin. In what other language does it take two devs to remove an element from an array?


Your code removes by index. This can be done in one line in Go:

    list = append(list[:i], list[i+1:]...)
but to remove by value you need a loop.


This makes it very unclear what's going on. I had to test it to find that this specific use is special cased to not copy. And very surprisingly you don't even have to assign back to the same variable to get this no-copy behavior!

Edit: I didn't do my test quite right. It's not really special-cased. But it's still very surprising to see this happen:

Code:

    s1 := []int{1, 2, 3, 10, 11, 12}
    s2 := []int{4, 5, 6}
    s3 := s1[:2]
    s4 := append(s3[:2], s2...)
    fmt.Println(s1)
    fmt.Println(s4)
Output:

    [1 2 4 5 6 12]
    [1 2 4 5 6]


Yup.

Simple! But not easy. Go is absolutely filled with nuggets like this in my experience. False-simplicity is deeply ingrained in the standard library as well: https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-...


This is a Go idiom, one of the "slice tricks" that you are expected to just know. In fairness every language has its non-obvious idioms.

It may or may not copy.


It’s crazy that the function you call to remove an element from a list is `append`.


If you come at it with the thought that you are creating two sublists (on each side, avoiding the index) you then need to merge them back together. That append reads to just recreate the list from the two parts.


When I see that, I have no idea if it allocates a new array or if it's in place. Which one is it? At least with a delete function it's clear.


In Go it may or may not allocate a new array; it depends on the array's capacity. This means that the resulting slice may or may not alias the original slice.

See this playground for an illustration: https://play.golang.org/p/mOpuGVj2ypG

That uses append to delete, and then modifies element 0 in the result. In the first call, only the new slice is modified. But in the second call, both slices are modified, since they share the same backing array.

I consider this to be one of the worst mistakes of Go, to design a highly multithreaded language in which variable aliasing is a dynamic property. I am convinced that many Go programs have latent races and bugs, invisible to the race detector, and they have not yet been tripped because they have been (un)lucky with the runtime's capacity decisions.


you are right that a loop isn't required, but the point that kind of index / array element juggling is a headache still stands




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

Search: