Small language change for additional type safety (Go2?)

238 views
Skip to first unread message

Andrew Phillips

unread,
Aug 2, 2022, 1:12:01 AM8/2/22
to golang-nuts
Just thought I'd run this one by you...

I used to often forget to specify the 2nd variable in a for-range:

    sum := ""
    for v := range []string{"1", "2", "3"} {
        sum += v
    }

luckilly (or because Go is so good at type safety) this generates the error:

  invalid operation: sum += v (mismatched types string and int)

I used to do this quite a bit which lead (when using an int slice) to one (maybe more that I haven't found yet :) bugs.  But for someone coming from a language with a for-range statement (like Python) it seems this type of bug is even more common:

    sum := 0
    for v := range []int{1, 2, 3} {
        sum += v // no error as they're both int
    }

Ideally you write tests to catch these sorts of things, but even with 100% coverage poor tests may not reveal the bug.  Then, if you're lucky, you get unexpected results or it could leave a nasty bug lurking in some rarely-executed piece of code.

A small fix to the language would avoid this problem.  If for-range indices had a different type then the above code could produce an error like.

  invalid operation: sum += v (mismatched types int and for range index)
 
The name of the new type could be something like intforrangeindex.  Perhaps something shorter, like intindex, if searching existing (Go 1) code reveals no potential conflicts, which I suspect it wouldn't.

BTW My gut was that intindex should be a signed int type but maybe unsigned would not be a problem.

This would be a proposal for Go 2 as it would not be backward compatible.  However, existing code could be easily converted (go fix ?) by just adding a type cast.  For example, if the above code was actually intended it could be written as:

    sum := 0
    for v := range []int{1, 2, 3} {
        sum += int(v)
    }

I think this is a small but worthwhile addition to type safety.

Note that go vet does not currently detect this problem but maybe it should.  A language change is better though, since not all code is vetted.

I was also thinking that intindex could be a hidden internal type but of course you can declare a loop index like this:

    var i int // type would change to intindex in Go 2
    for i = range []int{1, 2, 3} {
        sum += i
    }

Marcello H

unread,
Aug 3, 2022, 8:44:43 AM8/3/22
to golang-nuts
I would vote against it.
The thing is, if you try to cover this for a mistake, then we can cover every mistake, right?
There is probably a linter which can check this, or you can write a linter yourself.
(Also, if you happed to make this mistake more than once, tell your fellow developers, that they have to have extra attention when you write a loop.)


Op dinsdag 2 augustus 2022 om 07:12:01 UTC+2 schreef aphill...@gmail.com:

Andrew Phillips

unread,
Aug 4, 2022, 7:41:40 AM8/4/22
to golang-nuts
Hi Marc, thanks for your comment:
>  The thing is, if you try to cover this for a mistake, then we can cover every mistake, right?
Not at all.  I think the idea is to try to catch at compile-time common mistakes, that are easily made, can be missed during testing and can have serious consequences.  There have been numerous additions to the language for this reason and many other proposals some of which will probably be implemented in Go2 (eg https://github.com/golang/go/issues/20733 which I also thought of).

I guess it comes down to an assessment of how common this is, seriousness etc.  I couldn't find a discussion of this anywhere but in my experience it is a very common problem for beginners but something we experienced Gophers forget about.


>  There is probably a linter which can check this, or you can write a linter yourself.
This is not a general solution for the millions of beginner Go programmers.  Moreover, most do not run linters or even know what is available.  And really the only Go "linter" (in the sense I think you mean) should be go vet.  (Golint is more about style guidelines. Other linters that people have written have good ideas but should be added to the official tools - go vet of better the compiler - to be useful.)

It would be a (small) step if go vet detected the problem but many don't use go vet. My understanding of the unofficial current strategy for handling dubious code is:

1. "go vet" to report the problem if it's possible that the code could be correct AND there is no simple workaround to avoid it
2. compiler error is there is dubious code that could be clarified with a simple code change (like type cast)

Thanks again for the feedback.  It has helped me clarify what I want to say in the proposal.

Marcello H

unread,
Aug 5, 2022, 3:49:54 PM8/5/22
to golang-nuts
Ok, I get your point. And I for sure don't mind, as long as it is optional.

Op donderdag 4 augustus 2022 om 13:41:40 UTC+2 schreef aphill...@gmail.com:
Reply all
Reply to author
Forward
0 new messages