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: on err { statement } and return! #33177

Closed
sirkon opened this issue Jul 19, 2019 · 6 comments
Closed

proposal: Go 2: on err { statement } and return! #33177

sirkon opened this issue Jul 19, 2019 · 6 comments
Labels
error-handling Language & library change proposals that are about error handling. FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Milestone

Comments

@sirkon
Copy link

sirkon commented Jul 19, 2019

Example:

file := os.Open(fileName) on err {
    return! errors.Wrap(err, "open config file")
}
  1. here <vars> := A on <var> { … } is an equivalent for

    <vars>, <var> := A
    if <var> != nil {
        …
    }
    

    where <var> must implement error.

  2. return! is a shortcut for return statements with error. It substitutes first values with their type zeroes and the last value must be an error. Example:

func F() (string, error) {
    return! errors.New("error")
}

is an equivalent for

func F() (string, error) {
    return "", errors.New("error")
}

So, the first example is an equivalent for (inside the function returning (*os.File, error))

file, err := os.Open(fileName)
if err != nil {
    return nil, errors.Wrap(err, "open config file")
}

Pros:

  1. No magic
  2. This construct can be used to move slowly to stricter error handling. Mandatory on, for instance. I mean this method will work with sum-types as well.

Cons:

  1. It looks like there can be a clashing with named return values
@ianlancetaylor ianlancetaylor changed the title Tired of error handling proposals. So, another one with 2 new constructs. proposal: Go 2: on err { statement } and return! Jul 19, 2019
@gopherbot gopherbot added this to the Proposal milestone Jul 19, 2019
@ianlancetaylor ianlancetaylor added v2 An incompatible library change LanguageChange Suggested changes to the Go language labels Jul 19, 2019
@ianlancetaylor
Copy link
Contributor

The on err part of this looks very similar to #32946 and others.

The return! parse of this looks very similar to #33152.

@sirkon
Copy link
Author

sirkon commented Jul 19, 2019

The on err part of this looks very similar to #32946 and others.

The fact an error variable is explicitly mentioned outside in the same line makes it not very similar I guess. That onErr is a bit too magical.

The return! parse of this looks very similar to #33152.

Yes, sure. The difference I proposed new keyword for such kind of returns, not the change of regular return

@urandom
Copy link

urandom commented Jul 19, 2019

Also: #33029

@donaldnevermore
Copy link

The on part is fine to me. However, the return! looks wierd because I don't know what it means at first sight and I don't want a strange rule to remember.

@RmbRT
Copy link

RmbRT commented Jul 29, 2019

This is an anti-pattern: It's not backward compatible. Old code would suddenly no longer work, because return!value is a valid Go 1 syntax.

@sirkon
Copy link
Author

sirkon commented Jul 31, 2019

This is an anti-pattern: It's not backward compatible. Old code would suddenly no longer work, because return!value is a valid Go 1 syntax.

return? then. And expr on errexpr or err, i.e. or instead of on: may work as nil handling. The more I look at this proposal (I am a starter) the more I like it. Modified one:

file := os.Open(filename) or err {
    log.Error().Err(err).Msg("file not found, fallback to stdin")
    issue os.Stdin // file becomes os.Stdin if failed to open filename
}
file := os.Open(filename) or err {
    return? errors.Wrap(err, "opening config file")
}
var absPathFor map[string]string
…
absPath := absPathFor[relPath] or {
    return? errors.New("no absolute path found for " + relPath)
}

I.e. this extended or would work for both types with error and nilable types. And the shortcut can be introduced:

func Function(…) !(type₁, type₂, …, typeₙ) = func Function(…) (type₁, type₂, …, typeₙ, error)

The implicit error except the case of

func Function(…) error 

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 Suggested changes to the Go language Proposal v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

7 participants