|
Your examples aren't quite equivalent -- `people` in Go refers to a contiguous chunk in memory of size len(people) x sizeof(People). Thus, in the Sort() method, there needs to be something that binds the sort-algorithms need to swap elements to the specific code to swap that many bytes. Go does this, at the cost of some boilerplate, with the ByAge interface. (And other languages have more elegant ways to do this.) But we are doing something you can't do at all in Python (barring specialized array modules or similar). The equivalent of the Python code would be something like: package main
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%s: %d", p.Name, p.Age)
}
func main() {
people := []interface{}{
Person{"Bob", 31},
Person{"John", 42},
Person{"Michael", 17},
Person{"Jenny", 26},
}
fmt.Println(people)
SortBy(people, func(a, b interface{}) bool {
return a.(Person).Age < b.(Person).Age
})
fmt.Println(people)
}
where we have a library function // SortBy can sort anything -- just give a comparison function.
func SortBy(elts []interface{}, less func(a, b interface{}) bool) {
sort.Sort(byFunc{elts, less})
}
type byFunc struct {
elts []interface{}
less func(a, b interface{}) bool
}
func (a byFunc) Len() int { return len(a.elts) }
func (a byFunc) Swap(i, j int) { a.elts[i], a.elts[j] = a.elts[j], a.elts[i] }
func (a byFunc) Less(i, j int) bool { return a.less(a.elts[i], a.elts[j]) }
This is exactly the same, expect for instead of saying "Give me .age" like we do in Python, we have to explicitly cast and say "I'm expecting a person, give me .Age". |
How it's laid out in memory is tangential to the original critique - namely, that Go introduces complexity by not having parametric polymorphism.
> But we are doing something you can't do at all in Python (barring specialized array modules or similar).
Python not only allows this (I don't see why it wouldn't), it has built-in support for an equivalent for sorting via rich comparison methods [1]. The point is, though, that you don't have to.
As for the Go example, it's not equivalent because you're writing your own boilerplate code. And it's throwing static typing out the window, which doesn't seem very idiomatic.
1: https://wiki.python.org/moin/HowTo/Sorting#Odd_and_Ends