4 ms·
From the go FAQ: > Why is len a function and not a method? > We debated this issue but decided implementing len and friends as functions was fine in practice
by urzaj 4y ago
From the go FAQ:
> Why is len a function and not a method?
> We debated this issue but decided implementing len and friends as functions was fine in practice and didn't complicate questions about the interface (in the Go type sense) of basic types.
I imagine similar reasoning applies to "clear" here.
https://go.dev/doc/faq#methods_on_basics https://go.dev/doc/faq#methods_on_basics
- saghm 4y agoThat's a pretty weird rationale IMO. "It doesn't break anything" should be the minimum requirement for a major design choice, but it certainly isn't sufficient on its own. They sort of imply that making it a method would "complicate questions about the interface of basic types", but I don't really understand what that would even mean "in the Go type sense". Are they worried that someone might make an interface with a `Len` method and therefore be able to pass slices and maps to it? That honestly seems like a feature, not a bug, and certainly not worth throwing out the nicer syntax for.
- icholy 4y agoIn Go, it's common to create new types from the built-in ones. Here's an example: https://pkg.go.dev/net/http#Header https://pkg.go.dev/net/http#Header When you create a new type like this, you lose all methods from the original type. If the delete operation was implemented as a method on the `map` type, `Header.Del` would need to convert back to a `map` type to call it. (map[string][]string(h)).Delete(key)
- saghm 4y agoInteresting, I was aware of that newtype wrapper pattern, but I did not realize that methods weren't automatically forwarded to the wrapped type. This isn't the design I'd personally choose, but it does seem more consistent with what I know of Go's philosophy now that I understand this.
- xyzzy_plugh 4y agoIt's hard to articulate but whenever I find myself wishing I could inherit methods in a wrapper type, the design is bad. The designs where it ends up not being necessary are always much friendlier.
- saghm 4y agoYeah, I don't think I disagree there. If you want to automatically delegate methods, you can always use a type alias, and if you want to have delegation but type strictness (i.e. not having the alias and the original being interchangeable), you can do it manually. I think the two things here that I personally don't prefer are not having some way to opt into delegation (e.g. the `Deref`/`DerefMut` traits in Rust) and the more general paradigm of interfaces being implicit (which if I understand correctly is why it would be ambiguous about whether the wrapper types implemented the same interfaces as the wrapped type), but those are much larger philosophical differences. If you do want interfaces and wrapper types to work the way they do in Go, I agree that having a method for length would probably be less consistent with the design philosophy. I do feel like the FAQ could be a bit more explicit about the rationale though; most people who read that page and have that question aren't going to as experienced in Go, so they aren't as likely to read "interfaces on basic types" and go "aha, yes, that would be weird with wrapper types!". That said, I also don't really use Go at all due to the philosophical differences I mentioned above, so maybe my reading isn't going to be representative of their target audience anyhow.