Speaking of clobbering each other, min and max are names I had used for variables and functions all over the place. Suddenly they go and add global generic min/max functions and I'm shadowing like crazy.
I still don't understand why they aren't in a package, or better yet why they didn't just make math.Min and math.Max generic?
The windows headers are so convoluted and huge that I just copy the necessary declarations into my own mini header. It’s a bit annoying at first but saves a lot of headache later.
> or better yet why they didn't just make math.Min and math.Max generic?
I don't know Go, but my first thought would go to lol no generics. Now that they do have generics I guess they could do it, but backwards compatibility may require them to use other names than `math.Min` and `math.Max`.
(Note: Go did have some generic built-in constructs from the start, and could have included `min` and `max`, similar to how OCaml did it. At the same time, you don't want too many primitives in your language if you can help it.)
C++ programmers have had this problem in win32 since C++14 when they added std::min and std::max, whereas MSVC has offered those as built in functions since the 1990s
AMEN! I have been tired of packages, coding languages, everything being common nouns that don't even care if they duplicate each other for a long time. Mostly because it's confusing but this particular complaint gets me a lot. I'm glad to see someone else talking about this.
In retrospective, I think it's obvious that Go's decision to have package and variable names be in the same namespace was a mistake. It is the main reason why people overuse single letter variable names, and have debates such as the one in the linked post.
I am guessing that using a different operator (e.g. rate::NewLimiter()) was deemed inelegant, but it would have avoided a whole set of problems.
retrospective? It was one of the first silly gotchas I hit picking up the language. And the stdlib authors chose those package names!
It's funny how when I was using Go, I couldn't wait until it got generics (which was only a matter of time despite the party line). When it finally got them, I was versed enough in the edges and nature of the language/ecosystem that I didn't really care anymore and moved on. I am glad that Go rose to popularity because it brought to light opinions that weren't all that popular: memory layouts matter and error values (rather than exceptions). I still prefer a sound type system over nil/zero values though.
Totally agree, it’s a bit of a strange design choice. I’d be curious to read about the tradeoffs made here, as it must have come up while developing the language.
Agree with it or not, it’s recommended by the docs:
> It's helpful if everyone using the package can use the same name to refer to its contents, which implies that the package name should be good: short, concise, evocative. By convention, packages are given lower case, single-word names; there should be no need for underscores or mixedCaps.
Maybe the convention of single-letter variable names was meant to play nicely with this too (again, agree with it or not).
Can’t say I really care about this issue that much, it’s occasionally a slight nuisance, but show me a programming language that doesn’t have the occasional slight nuisance.
An explicit scope resolution operator would be a better solution than forcing package name changes, as called out by another commenter. Maybe that was left out to keep it simple? If anyone knows of a Go blog post about the decision to omit this feature I’d be curious to see it!
Counterpoint: His variable name of rate isn't really descriptive, which is almost worse than the package naming complaint.
What kind of rate? Time or volume or...something else entirely? Otherwise, the variable will be scoped within a function and go doesn't really promote global variables as a best practice.
I once worked under someone who felt strongly about us importing modules instead of classes. So instead of
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer()
we were told to change it to
from sklearn.feature_extraction import text
tfidf = text.TfidfVectorizer()
to be compliant. Guess what variable name everyone used to store document text in every file.
Until this article, I always blamed this on the decision to blindly import modules instead of... well... whatever makes sense. Now I'm realizing if we all avoid common names for packages then this whole class of issue goes away.
> Until this article, I always blamed this on the decision to blindly import modules instead of... well... whatever makes sense. Now I'm realizing if we all avoided common names for packages then there would not have been an issue.
If your solutions depends on others to "do the right thing", it often isn't a viable solution.
However, how you import something in your own files, is something you most likely control.
Having a global style policy (for imports) doesn't seem like relying on others to "do the right thing". It's just style and is completely arbitrary.
Someone probably encountered a problem with having a mishmash of ways people do imports and thus began the policy. It's the type of policy where someone heaved a great big sigh and said, "this is why we can't have nice things."
I was specifically referring to the "Now I'm realizing if we all avoided common names for packages then there would not have been an issue" part as relying on others to do the right thing.
Having a internal policy about how to import something wouldn't be relying on others to do the right thing.
This is one of the benefits of having all your libraries/modules in a monolithic repo: You can refactor the names of everything pretty easily. It'd be a BIG commit but it's still a trivial task to rename something like `text` to `textual` or `text_anal` everywhere it's being used.
I've done it before. It's the type of thing where you'll find out immediately if you screwed up somewhere but modern IDEs usually do a pretty good job at such things (the free version of PyCharm will do it real fast and then you never have to open it again if it's not your thing).
Misses one other important point: if you search for a common name you will get results from all over. If the name isn't a common noun any search engine can find relevant results.
The Go language is full conventions like this that are put on the programmer to make up for shortcomings brought about by the simplicity of the language.
My preference is common nouns, generally it's the most concise and precise naming, I understand the issue in Go however, so the argument carries weight. What I would say is redundant verbosity is a fair halfway house.
Namespacing in languages such as Rust (modules) are probably most favourable to me, i.e. f64::min/max ~ u64::min/max or a hypothetical crypto::rand() math::rand().
Also, in the spirit of inclusion & not making people uncomfortable suggesting certain packages, don't name them ... well, I don't know how to call this, but here's an example:
> Variable names in Go are camel case, so ratelimit will never clobber a variable name. Even if it that wasn’t the case, having variables called rate, limit, or rateLimiter is plausible and even likely, but ratelimit? Not a thing.
Not to say it invalidates the whole article or anything, but in what world would "ratelimit" never be used as a variable name? That still feels like a fairly reasonable name for a variable if we're ignoring the camel-case requirement.
The idea here is that many programmers would call it rateLimit, if they use CamelCase naming. If they don't, at least they can just switch to camelcase once they realize the issue, while that is not an option for single noun names
I wonder if this only counts for variable names in English? For example, if you're making a package that you would name, 'rate' perhaps translate that to a different language before naming your package. Examples:
tasa - Spanish
uku - Hawaiian
sats - Danish
...or just be clever and call it something like 'irate' (the Apple version? haha).
I still don't understand why they aren't in a package, or better yet why they didn't just make math.Min and math.Max generic?