Title: A sneaky Golang bug
Date: 2023-08-02 13:15

Today at work, I needed a function in [Go](https://go.dev/) to remove
duplicates from a slice, and thus wrote something like this using the
[generic](https://go.dev/doc/tutorial/generics)-based
[slices](https://pkg.go.dev/golang.org/x/exp/slices) package:

```go
func removeDuplicates(s []mytype) []mytype {
    slices.SortFunc(s, less)
    slices.CompactFunc(s, eq)
    return s
}
```

Can you spot the bug? Here are the prototypes of the two functions:

```go
func SortFunc[E any](x []E, less func(a, b E) bool)
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S
```

The first has no return value, while the second does, unused in our case, hence
the bug. It's *interesting* to note that the go compiler is perfectly happy
with this, and doesn't issue any warning: it was *extraordinarily fun* to pinpoint.

I reached out to [Ian Lance Taylor](https://airs.com/ian/) who
[implemented](https://cs.opensource.google/go/x/exp/+/03df57b9a50843fbf23bf90375d6584bcc8ea13d)
those functions in 2021 and he pointed me to [Go Slices: usage and internals
](https://go.dev/blog/slices-intro). Things indeed do become obvious once 
looking at the [implementation of
`slice`](https://github.com/golang/go/blob/master/src/runtime/slice.go):

```go
type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}
```

Both `slices.SortFunc` and `slices.CompactFunc` are taking a slice as
parameter, and not a pointer to a slice, meaning that any changes to `len` and
`cap` will be local to the function.

Anyway, There is a [proposal](https://github.com/golang/go/issues/20803) to require
return values to be explicitly used or ignored open since 2017, but it didn't
go anywhere for now. There is also [another proposal](https://github.com/golang/go/issues/20148)
to make `go vet` better at highlighting error mishandling, as well as [errcheck](https://github.com/kisielk/errcheck),
but those wouldn't really help in this case.

