But now I have to understand what m.Range does, and I can't assume it's a slice or a map etc. Prior to this change, you could almost always correctly assume what a for loop is doing as it was very primitive.
It's changes like this that will make Go less productive for users over time, IMO. Java-fication.
You put your cursor on the "Range" portion of m.Range, and hit "Jump to Definition".
You can also just not import things that do crazy things with iterators. Based on the history of the community, that will actually be fairly easy. I'm yet to see anything crazy with generics get into a library that I use. I'm abundantly positive there's going to be a dozen "hey let's go do crazy things with rangefunc" libraries in the next couple of weeks, probably some will even make it to HN (with predictable comments bemoaning how complicated Go is getting even though these libraries have an expected use rate in the low dozens of people in the next few years), but the odds of them penetrating into common practice remain low. (Higher than previous attempts at such libraries, because rangefunc fixes some basic issues with them. But still low overall, I think.)
I think you could go many, many years programming Go in the next few years and not encounter any funny iterators in real code. If you just assume the iterator is doing what it looks like it should be doing and isn't doing anything funny, you're going to be 99%+ correct in the Go programming world.
> You put your cursor on the "Range" portion of m.Range, and hit "Jump to Definition".
Well, that's one reason why people usually run away from languages high in magic like Java/JS to something like Go: not needing a fancy IDE to make sense of what's happening with a single line of code.
I'll agree with you that it is a very "mild" case of magic, or maybe this doesn't qualify as magic at all because Go doc is pretty good. But having to build the docs and then learning what m.Range does adds extra inconvenience to what until now was just an eyeball scan operation of the "for" line.
Even if you don't have any help from an LSP, I don't really see how this change adds any meaningful complexity.
With `for x, y := range m.Range`, you know you are iterating over something, and you are getting an `x` and a `y`. For the purposes of understanding the range block and what it does, it doesn't really matter what `m.Range` is, only that it allows iteration. Just like you don't care in <=1.22 land whether `m.Range` is a slice, map, or channel, because for the purposes of understanding the code, that doesn't matter.
It's changes like this that will make Go less productive for users over time, IMO. Java-fication.