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: Go 2: permit two clause for statement #21855

Closed
briansan opened this issue Sep 13, 2017 · 6 comments
Closed

proposal: Go 2: permit two clause for statement #21855

briansan opened this issue Sep 13, 2017 · 6 comments
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Milestone

Comments

@briansan
Copy link

briansan commented Sep 13, 2017

I don't want to speak for other developers, but a very quick and dirty (yet effective) construct that I typically use for resilient code is the following retry pattern:

for {
  if err := try_something(); err == nil {
    break
  }
  fmt.Println("something went wrong, trying again in 5s", "err", err.Error())
  time.Sleep(5 * time.Second)
}

For a brief moment, I thought I could brilliantly shorten this to the following:

for err := try_something; err != nil; {
  fmt.Println("something went wrong, trying again in 5s", "err", err.Error())
  time.Sleep(5 * time.Second)
}

only to face palm myself about a minute later for neglecting the fundamentals of a for loop.

That being said, I believe that it would be a perfect addition to Go 2.0 (as this would be a language breaking change) to add support for such a construct by allowing the for loop to only contain a single semicolon, that is:

for err := try_something; err != nil {
  fmt.Println("something went wrong, trying again in 5s", "err", err.Error())
  time.Sleep(5 * time.Second)
}

Where the first clause is executed before every iteration of the loop and the second is the condition that breaks if true, else executes the block.

Thoughts?

@gopherbot gopherbot added this to the Proposal milestone Sep 13, 2017
@davecheney
Copy link
Contributor

davecheney commented Sep 13, 2017 via email

@dsnet
Copy link
Member

dsnet commented Sep 13, 2017

This sounds like a library rather than a language change. Even then there are many ways that retries can be done. Is the retry delay the same, is it an exponential backoff, is it geometric? How many times does it retry before giving up?

Even if it were a library, why does it have to be in the standard library?

@dsnet dsnet added v2 An incompatible library change LanguageChange Suggested changes to the Go language labels Sep 13, 2017
@ianlancetaylor ianlancetaylor changed the title proposal: Support resilient retry syntax in Go 2.0 proposal: Go 2: permit two clause for statement Sep 13, 2017
@ianlancetaylor
Copy link
Contributor

I think the basic proposal here is to change the for statement to add a two-clause variant, in which the initialization statement is executed each time around the loop.

We've considered this in the past and rejected it because it means that the presence or absence of a semicolon, which can be rather subtle, makes a big difference to the program. For example, currently

for f() { ... }

executes while f() returns true. With this change one might accidentally write

for f(); { ... }

which looks quite similar but is in fact an infinite loop that executes a each time around the loop.

This is not to say that we should not consider this again. I just want to explain why we have rejected the idea in the past.

@neild
Copy link
Contributor

neild commented Sep 13, 2017

Requiring content in both clauses would avoid the subtle trap @ianlancetaylor mentions.

for f(); { ... } // compilation error: second clause must not be empty

There is a second subtlety, however, which could not be as easily avoided:

for err := f(); err != nil {
  // f() executes before each iteration.
}

for err := f(); err != nil; {
  // f() executes only once.
}

@briansan
Copy link
Author

briansan commented Sep 13, 2017

Thank you for all the feedback; I do agree with your points that there are nuances to this feature that could potentially cause more problems than solve. Feel free to close

@robpike
Copy link
Contributor

robpike commented Sep 13, 2017

As Ian said, we discussed this in the past and decided it was too dangerous.

@robpike robpike closed this as completed Sep 13, 2017
@golang golang locked and limited conversation to collaborators Sep 13, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

7 participants