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: syntactic sugar for return fmt.Errorf #56159

Closed
hherman1 opened this issue Oct 11, 2022 · 4 comments
Closed

proposal: Go 2: syntactic sugar for return fmt.Errorf #56159

hherman1 opened this issue Oct 11, 2022 · 4 comments
Labels
error-handling Language & library change proposals that are about error handling. FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@hherman1
Copy link

Author background

  • Would you consider yourself a novice, intermediate, or experienced Go programmer?
    Experienced

  • What other languages do you have experience with?

Java, Python, Haskell, C

Related proposals

  • Has this idea, or one like it, been proposed before?
    I've read through a lot, but not all, of the existing error handling proposals. This one might have been proposed before and I missed it, but I haven't seen it yet.
    • If so, how does this proposal differ?
      It's smaller in scope than a lot of the solutions I read.
  • Does this affect error handling?
    Yes
    • If so, how does this differ from previous error handling proposals?
      It is focused on exactly one type of error handling, not a broad class.
  • Is this about generics?
    No
    • If so, how does this relate to the accepted design and other generics proposals?

Proposal

  • What is the proposed change?

Add a new keyword, e.g try to be used as follows:

val, err := doSomething()
try err: ret1, ret2, fmt.Errorf("doing something: %w", err)
...

In this case, if err == nil then try will return the values on the right of the colon. If err == nil, the routine proceeds. The try keyword would require it's argument to have type error.

  • Who does this proposal help, and why?

Most of my error handling has the form:

if err != nil {
    return fmt.Errorf("context: %w", err)
}

It requires a bit of typing and visual space. It's not too bad, but it is a bit of a nuisance. The aim of this proposal is to change Go programming in precisely this one case, and nowhere else. If you have any sort of complexity in your error handling, you would continue to use the rest of the language to manage your errors. However, in this specific case you can save a bit of typing and a bit of vertical space in your function.

I believe these are the main complaints from those who are bothered by error handling, and they would be satisfied with this proposal.

  • Please describe as precisely as possible the change to the language.

A new keyword would be added, try, which would be used in the form try [error]: [values...]. [error] would be filled by an expression evaluating to type error. [values...] can be filled by anything you could write after return. If [error] evaluates to a non-nil error, [values...] would be returned.

In other words, this:

val, err := doSomething()
try err: ret1, ret2, fmt.Errorf("doing something: %w", err)
...

Is exactly equal to:

val, err := doSomething()
if err != nil {
    return ret1, ret2, fmt.Errorf("doing something: %w", err)
}
...
  • What would change in the language spec?

I can return to this question and add details if what I wrote above is at all compelling or original.

  • Please also describe the change informally, as in a class teaching Go.

Use the try keyword as shorthand for simple error checking. You try an error, and if it is not nil, your function will return everything you passed to try.

  • Is this change backward compatible?
    I think so, but I'm not sure. I don't see how this could be parsed as valid go code in existing versions, so it seems like a purely additive change, and thus backwards compatible.
    • Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit.
      Show example code before and after the change.
    • Before
    • After
  • Orthogonality: how does this change interact or overlap with existing features?
    This has a clear, very specific use case, in which it can be preferred to existing features. It is not usable in any other cases. Thus I think it avoids confusing the use of other features.
  • Is the goal of this change a performance improvement?
    No
    • If so, what quantifiable improvement should we expect?
    • How would we measure it?

Costs

  • Would this change make Go easier or harder to learn, and why?
    Harder to learn. We would introduce a new keyword, with an unusual syntax (would hope someone has an idea on how to make it prettier, or more familiar). It raises the question "why is this feature only for error handling?".
  • What is the cost of this proposal? (Every language change has a cost).
    I believe the main cost is cognitive. It might also introduce churn as people rush to rewrite large swaths of perfectly fine error handling code. It also requires new muscle memory from devs, who are used to the if err != nil pattern.
  • How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?
    I suppose they would all need to learn how to handle this keyword, so presumably all of them.
  • What is the compile time cost?
    I believe this should be extremely cheap at compile time, as it is a very simple translation.
  • What is the run time cost?
    I don't believe there is any additional run time cost in the cases where this will be used.
  • Can you describe a possible implementation?
    I don't know enough about the compiler to be useful here. I'm worried about how parsable this would be. But it seems like a simple thing to implement, if you can parse it. I can imagine how to do the AST generation.
  • Do you have a prototype? (This is not required.)
    No I don't.
@gopherbot gopherbot added this to the Proposal milestone Oct 11, 2022
@hherman1
Copy link
Author

I hope I'm not wasting your time! I've read many of the error handling proposals over the years, and this has been bouncing around in my head for a while. I don't think I've seen something exactly like it, yet. Hopefully I'm not wrong.

@ianlancetaylor ianlancetaylor added LanguageChange v2 A language change or incompatible library change error-handling Language & library change proposals that are about error handling. labels Oct 11, 2022
@ianlancetaylor
Copy link
Contributor

See #40432 for a meta-issue. This seems similar to #32611.

@hherman1
Copy link
Author

hherman1 commented Oct 11, 2022

Oh, ya that's nearly identical to what I'm proposing here. I guess what I've proposed incorporates critique 1 from that proposal. However, if reducing boilerplate is inadequate for this kind of language change (which seems fair to me), then I don't think my proposal is meaningfully different.

I'm going to leave the proposal open so you might confirm that ^ this is true, but I'm happy to close this.

Thanks for the quick response

@seankhliao
Copy link
Member

Duplicate of #32611

@seankhliao seankhliao marked this as a duplicate of #32611 Oct 12, 2022
@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Oct 12, 2022
@golang golang locked and limited conversation to collaborators Oct 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
error-handling Language & library change proposals that are about error handling. FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

4 participants