Hacker News new | ask | show | jobs
by tommodev 1185 days ago
Question: what is the reason for the silent copy when append exceeds the original slice cap?

It's a footgun avoided by reading the spec and (maybe) remembering it in practice, but it feels like it would be safer to throw a comp error and force the user to deal with it when a user is trying to exceed the cap of the underlying array?

Alternative is defensively using len() and cap() for slice ops in which case error-ing out feels more ergonomic.

3 comments

Because you would not have any growable vector/list structure otherwise.

The real problem is that Go merrily lets you have copy-and-append operation on a slice (good), subviews of a slice so that you can share subsets of the data without copying it (good), at the same time (very bad: any operation on either will lead to confusion).

In most languages, subslicing gives you something of another type that can't be modified (or at least not accidentally). But in Go, if I call a function `do_smth_with_slice([]byte xs)`, there is no way for me to know whether this function expects `xs` to be mutable or not.

I'm sure that e.g. a C++ function taking an std::view can do some forbidden magic to still modify the underlying data, but at least the original intent is made clear by the argument type.

> Question: what is the reason for the silent copy when append exceeds the original slice cap?

Because Go slices play double duty as vectors. And that is the usual behaviour of a vector.

And the issue is the opposite situation, when appending does not exceed the original slice cap. The entire point of the slice trick is to force a resize (and thus a copy) on append.

> it feels like it would be safer to throw a comp error and force the user to deal with it when a user is trying to exceed the cap of the underlying array?

It would be safer to have not confused slices and vectors, but half-adding that confusion sounds even worse, your suggestion would only keep the worst parts, and would require hand-rolling the rest every time.

Erroring on appending to a slice would require checking every call to append for an error. I'd find it more surprising for append to error on resize since append implies a growable array.