Python lacks a reserved keyword for this use, and I can count the ones not using “self” in instance methods and “cls” in class methods that I’ve encountered on the fingers of my left foot.
But, yeah, weak convention plus no keyword promotes needless chaos.
The above does not match my experience in maintaining large go codebases because of proper code reviews and expectation of writing maintainable code.
> interface{} everywhere because of no generics
It would be good to know the domain here. Looking at my own fair share of Go code in productive systems (probably around 100-200 KLOC, written over the last 6 years), interface{} is really really rare. It appears in some library functions which genuinely accept basically any type, in the same way as json.Marshal(), fmt.Printf() or sql.Stmt.Execute() in std.
Other than that, I don't think I've ever had a case where I used interface{} instead of defining a more specific interface (plus adapter types to implement that interface on foreign types if necessary).
The only big mess that I've come across in Go land is kubernetes/client-go. I can't wait for generics to replace this metastasizing heap of autogenerated code.
While that's technically true, it doesn't work out in practice because people look to the standard library as "the way" to write golang. It's basically an implied rule and I haven't seen anyone not folllow it so far.
> It would be good to know the domain here
Both infrastructure level work as well as CRUD type work.
> interface{} is really really rare
We have to use them everywhere for things like JSON parsing, config file handling, and pagerduty integration. Not to mention wrappers around SQL handling (e.g. batch inserts, pagination, etc.)
Generics will fix some things in the language, but not all. There are too many issues with it like the ones I already mentioned. It's still a very cludgy language to work with.
I assume you're not referring to things like json.Marshal(), where the function argument is legitimately of type interface{} since it really accepts any value.
Hence I'm going to assume that you're referring to situations where a value can have one of multiple types (e.g. a float value that sometimes gets provided as a string). It's true that people sometimes unmarshal into interface{} and then type-assert in those scenarios, but that use of interface{} is a code smell that should be flagged in review. The proper way is to unmarshal into a custom type with a json.Unmarshaler implementation that accepts all possible input formats (and vice versa for json.Marshaler if encoding is required). This is a real-world example from one of my codebases: https://github.com/sapcc/limes/blob/d833228e976ac1ddc4b95779...
Just as a start: variables names should always be clear by context. You only see the one letter ones if its literally the next line or similar use case. Also, bare interface{} should basically never be the case for a function signature.
None of the code you've described thus far would pass a proper review.
This claim keeps getting repeated with absolutely nothing to back it up, other than repeating what the golang authors claimed.
I work on a large golang code base, and it's quite horrid. The IDE experience is terrible. It's hard to navigate the code base, due to things like types unintentionally implementing interfaces because they happen to match on some of their function declarations. No proper visibility rules (only "public" and "package private"). interface{} everywhere because of no generics (I'm aware that's being worked on). Single character variable names are popular because the golang authors write code that way and it's seen as "smart". No reserved "this" or "self" keyword to declare methods means that every type will have its own single letter self variable which you have to look up every time. Error handling is terrible, and I've seen many insidious cases of mishandled errors. Null pointers are still a thing. The list goes on.
Edit: not to mention things like the language is against quick prototyping (heavy friction due to things like unnused imports or variables, and a very verbose language), as well as the lack of mature libraries such as JDBI or Dapper.