Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: math: add Iter #44394

Closed
carnott-snap opened this issue Feb 18, 2021 · 11 comments
Closed

proposal: math: add Iter #44394

carnott-snap opened this issue Feb 18, 2021 · 11 comments

Comments

@carnott-snap
Copy link

carnott-snap commented Feb 18, 2021

background

I have found that over a sufficiently large sample, c style for loops, for v := 0; v < 25; v++ {}, can introduce iterator and comparator bugs. As such I prefer for range [N]struct{}{} {}, or for range make([]struct{}, N) {} for N that is not const, as suggested in #36308 (comment). Unfortunately may people have found this syntax confusing, so I have taken to using iter.N, which uses the make form above, cleans up the syntax, and has a godoc explaining what is going on. But @bradfitz "encourage[s] [people] not to depend on this" and calls it out as "not ideomatic", despite the comment above. As such, I would like to have a discussion about including this to the stdlib.

impl

package math

// Iter returns a slice of n 0-sized elements, suitable for ranging over.
//
// For example:
//
//    for i := range math.Iter(10) {
//        fmt.Println(i)
//    }
//
// ... will print 0 to 9, inclusive.
//
// It does not cause any allocations.
func Iter(n int) []struct{} { return make([]struct{}, n) }

alternatives

nop

We can always do nothing, but I think this syntax is reasonable and improves safety and readability of trivial loops. Clearly we still need the c for syntax for non-trivial cases.

inline

If desired, this could be implemented in a way that the compiler more fully inlines it, especially in cases where the index is unused.

names

I am happy to have this be named something different or live in a different package. math seemed like a decent fit, since there is no numbers, ints, or iter package, and I did not want the stutter of for range math.Range(10) {}, but it would clearly indicate where it was intended to be used.

@gopherbot gopherbot added this to the Proposal milestone Feb 18, 2021
@randall77
Copy link
Contributor

Might have some overlap with #43557

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Feb 19, 2021
@mvdan
Copy link
Member

mvdan commented Feb 19, 2021

I have found that over a sufficiently large sample, c style for loops, for v := 0; v < 25; v++ {}, can introduce iterator and comparator bugs.

Do you have any data or examples to back this up? They are perhaps a bit verbose and easy to mistype if you're not used to the idiom, but in practice I can't remember the last time I saw a bug caused by them directly.

@carnott-snap
Copy link
Author

carnott-snap commented Feb 19, 2021

This seems hard to get good numbers on, and all my anecdotes are proprietary. It is mostly off by one errors, and it is not a deluge, but because iter.N feels like all the other range loops that tends to help with intuition.

@rsc
Copy link
Contributor

rsc commented Jul 28, 2021

This is a language change by another name.
We have a way to write loops.
You are welcome to prefer other ways,
but we don't need to provide a second standard way in Go itself.

@rsc
Copy link
Contributor

rsc commented Jul 28, 2021

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc rsc moved this from Incoming to Active in Proposals (old) Jul 28, 2021
@mdempsky
Copy link
Member

I think this is a cute API, but (1) it seems inappropriate for package math (every existing function in package math has to do with floating point operations), and (2) there's no reason it needs to be in the standard library anyway (e.g., it doesn't expose any new types that separate modules need to agree on for interoperability).

@cristaloleg
Copy link

Also there is a lib for that, no need to change the language 😉 https://github.com/bradfitz/iter

@rsc rsc moved this from Active to Likely Decline in Proposals (old) Aug 4, 2021
@rsc
Copy link
Contributor

rsc commented Aug 4, 2021

Based on the discussion above, this proposal seems like a likely decline.
— rsc for the proposal review group

@bcmills
Copy link
Contributor

bcmills commented Aug 4, 2021

I agree that the three-part for loop is awkward and error-prone (compare #24282), but I also agree that the math package (and the clever []struct{} hack!) doesn't seem like an appropriate long-term fix.

Personally, I hope that after generics land we may get a more holistic “iterator” API, and then we can provide a standard iterator for arithmetic sequences — this seems like a cleaner fit for a future iterators package than for math.

@cristaloleg
Copy link

Regarding iterator #43557

@rsc rsc moved this from Likely Decline to Declined in Proposals (old) Aug 11, 2021
@rsc
Copy link
Contributor

rsc commented Aug 11, 2021

No change in consensus, so declined.
— rsc for the proposal review group

@rsc rsc closed this as completed Aug 11, 2021
@golang golang locked and limited conversation to collaborators Aug 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

No branches or pull requests

8 participants