people.sort_by_key(|person| person.name); // sort_by is also an option...
I think it's worth calling out exactly what is happening in the Go example:
- We create a closure that captures the people slice
- We pass the people slice and the closure to the Slice function
- The Slice function mutates the people slice, and because the closure captured the slice it sees these mutations too
I get why the Go team wrote sort.Slice like that, and it was perhaps the best they could have done with the language features...But I think we're going to have to agree to disagree on how wonderful it is compared to other languages ;).
No disagreement, having used Python a lot and finding it much nicer for this case. My compliments to Go on this were relative to the just how tedious the “implement this sort interface” method was that TFA was describing. sort.Slice is definitely still pretty rote (I think I write the same Less() function 90% of the time?), but it’s at least fewer characters of rote!
It's worth noting though that Go's way is just 40 characters more than Python with an inline comparison function and Go's verbosity.
If I need to reverse the order, it looks easier to do with Go (just reverse the operator) than with Python and Rust way (I guess both have something like an "order" additional parameter).
Rust and Python both feel more elegant but I actually like Go's way.
Go's method is like that because it didn't have generics, but it does have the advantage of allowing you to sort more complicated things, e.g. indexes into other data structures, or computed values.
Sorting by key is a special case (admittedly the most common special case).
Agreed! https://pkg.go.dev/sort#Slice is wonderful. (Added a bit after this article was written, I think.)