Wait, by saying it would be nice to have the GC not trace elements between len and cap, you mean it would be nice to have GC recognize unreferenced elements of a slice between len and cap and free them (presumably if they are pointer or interface types)?
OK, I would say Go has quirks but I'm the type of an engineer who doesn't expect things to work as I like them but I dig how it actually works and live with that. In my opinion Go (or the Go tutorials) advertise slices too much, perhaps the problem is that there's no handy builtin list type with nice language sugar. A fix for the situation of the topic could be implemented by the slice type. Imagine, if a slice value not only shared the pointer to the underlying buffer but also a list with references to all other slices holding on to the underlying buffer then such operation as s = s[x:y] could walk the list, find and free all unreferenced values in the underlying buffer (perhaps even assigning zero value to have consistent behavior regardless of []T or []*T). Such operation would be deterministic. Of course there could be an optimization in place, whenever the slice was derived from a named array, just keep some flag instead of the list of references to all other slices. I don't see how GC could achieve that in a consistent way since the GC may not even do the swipe between calls like s = s[:x]; s = s[:cap(x)]. Unfortunately I'm afraid that this would break some existing code (even if we also trim the cap property) thus keeping in mind the original notion of a slice as a window to some array makes sense to me. As a side note, I think the append function has quirks too, so it's easy to make mistakes until you dig into it. The function signature shows it returns a new slice so it's easy to jump to conclusion that you can safely modify the new slice without affecting the original one, or on the other hand jump to conclusion that writes made to this slice would be seen in other slices. It all depends how you initially form the idea of what the slice type is. On Friday, March 27, 2020 at 1:06:16 AM UTC+1, Keith Randall wrote: > > It's common practice to *write* to elements between the length and > capacity of a slice. Usually, you use append to do that. > It's bad practice to *read* elements between the length and capacity. > Which you can't do with a simple indexing op, of course. You would have to > reslice larger and then index. > In that sense, it would be nice to have the GC not trace elements between > len and cap. They should be dead if you never read them, only write them. > It's hard to do in the GC, it requires a language change, etc. But it would > be nice. > > > On Thursday, March 26, 2020 at 12:29:04 PM UTC-7 leszek...@gmail.com > wrote: > >> >> >> >>> I disagree. I do that all the time. It's also how `append` was >>> implemented before it existed as a predeclared function. It's also, FWIW, >>> used in bytes.Buffer <https://golang.org/src/bytes/buffer.go#L107>. I >>> agree that unless your API is very clear about it, you shouldn't really >>> access a slice past the length for one of your arguments. But there *are* >>> APIs where it's clear that's happening (e.g. anything having "append" in >>> it's doc-string) and there are use-cases where you control the slice for >>> its entire lifetime and where it can make code more readable. >>> >> >> I didn't even know that append wasn't there, but since we have it isn't >> it meant to be used in the first place? >> Of course if we check the capacity, expanding past len is safe, like >> s[:cap(s)]. I would check the capacity only in case when I really don't >> want to end with a new slice buffer as a result of appending more than the >> available space. >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/4975efcd-4d31-4be0-9b34-03d125f096a9%40googlegroups.com.