The builtin package is the exception because it’s “built in.” No matter what package you’re in, you call the builtin
len function with just
len(thing). My point about
int is that it’s a built in type like
len is a built in function. You can’t build your own
int type without the built in
len just is special just like slices and maps just are special in that they are the only generic types in the language. You can’t write a generic stack type in Go, but you can build a stack type on top of slices. The builtin types are fundamental building blocks that you build larger constructs around/on top of.
The language designers could have decided to have no built in types or functions and instead have a
go, etc. package so that you have things like
sys.Append, etc., but they didn’t. They also didn’t out any methods on built in types which is why it’s
slice = append(slice, value) instead of
Having methods without classes is not an afterthought. It was deliberate. Go’s designers didn’t want inheritance, but they did want polymorphism. They wanted compile-time type safety but they didn’t want types to need to list every interface they wanted to implement. They didn’t want operator or function overloading, etc.
I didn’t like Go when I started using it in 2016. Up until this year, I preferred C# or Python. A common complaint about Go is that the language seems to be arbitrarily opinionated about its features or design decisions. That’s probably true in some ways. For me, now that I’m used to its quirks, it’s easier for me to write boring concurrent code that’s easy to read, reason about and change. It’s also probably made me a better C# and Python programmer