Go: proposal: Go 2: expand power of range for slices/arrays

Created on 27 Jan 2020  Â·  7Comments  Â·  Source: golang/go

This proposal wishes to expand the power of the range keyword when applied to slices and arrays.

Note: If you don't want to use the features, your code will LOOK EXACTLY THE SAME.

Currently:

s := []string{}

for idx, v := range s {}

Proposal:

  1. Iterate forwards (with superfluous +)
for idx, v := range +s {}

*Equivalent:
for idx := 0; idx < len(s); idx++ {
    v := s[idx]
} 
  1. Iterate backwards
for idx, v := range -s {}

*Equivalent:
for idx := len(s) - 1; idx >= 0; idx-- {
    v := s[idx]
} 
  1. Iterate from middle outwards
for idx, v := range ±s {}

*Equivalent:
mid := (len(s) - 1) >> 1
for j := 0; j < len(s); j++ {
    var idx int
    if j%2 == 0 {
        idx = mid - j/2
    } else {
        idx = mid + (j/2 + 1)
    }

    v := s[idx]
}
Go2 LanguageChange Proposal

Most helpful comment

The middle-out range is rarely useful, and the syntax is cryptic. That doesn't seem like a good addition to the language.

How often does one want to iterate backward? It's already possible to do so, in a way that is clear and easy to understand. The single - character seems small for something that will be rarely used.

Also, the - will only be meaningful for slices and arrays, not for maps or channels.

Iterating backward can be done with the usual range, with just one extra line.

    for i := range s {
        v := s[len(s) - 1 - i] // reverse iteration
        ...
    }

This proposal does not seem compelling.

All 7 comments

Additional Notes:

  1. ± is used to start from middle and go to right initially
  2. ∓ is used to start from middle and go to the left initially
  3. Iterating from middle outwards has (rare) but important use cases such as in divide and conquer algorithms.
  4. I found use for it in my strconv.ParseComplex PR.
  5. The use case is rare. But when a developer needs it, they will find the character for it, despite it not being readily available on the keyboard.

where do I save it?

Add it as a comment to this issue. Thanks.

Iterating from the middle seems like too rare a use case to bake into the language - I've personally never encountered it. Iterating in reverse is something I've needed a few times myself; it may be worth adding, if only to help avoid off-by-one errors.

I think the syntax you're proposing is too cryptic, though. I would rather implement this as a reversed built-in (not a keyword, because that'd be a breaking change) instead. Also, if we had generics plus some way to implement custom iterators that work with range, it wouldn't even have to be in the language itself.

While this is clever, I'm not sure if I like it. Go has very few symbols that aren't universally understood (:= and <- are the only ones off the top of my head) so adding -slice doesn't seem right. I sortof like @dpinela's idea of a reversed(slice) builtin though.

The middle-out range is rarely useful, and the syntax is cryptic. That doesn't seem like a good addition to the language.

How often does one want to iterate backward? It's already possible to do so, in a way that is clear and easy to understand. The single - character seems small for something that will be rarely used.

Also, the - will only be meaningful for slices and arrays, not for maps or channels.

Iterating backward can be done with the usual range, with just one extra line.

    for i := range s {
        v := s[len(s) - 1 - i] // reverse iteration
        ...
    }

This proposal does not seem compelling.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

natefinch picture natefinch  Â·  3Comments

mingrammer picture mingrammer  Â·  3Comments

michaelsafyan picture michaelsafyan  Â·  3Comments

OneOfOne picture OneOfOne  Â·  3Comments

longzhizhi picture longzhizhi  Â·  3Comments