Go Programming Experience

Intermediate

Other Languages Experience

Javascript, Lua

Related Idea

  • [ ] Has this idea, or one like it, been proposed before?
  • [x] Does this affect error handling?
  • [ ] Is this about generics?
  • [x] Is this change backward compatible? Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit

Has this idea, or one like it, been proposed before?

No, not to my knowledge in this fashion.

Does this affect error handling?

Yes.

I believe my idea is a less verbose, non-breaking, syntactic sugar for error handling that could be a more idiomatic way of handling errors.

Is this about generics?

No.

Proposal

I propose to add an error switch construct that is similar to the type switch construct that exists in Go, and (I'm less confident about this) to allow errors as conditions, or allow errors to be converted to bools. See the end of the proposal for code samples.

Language Spec Changes

Conditional statements, type conversion and assertions.

Informal Change

  1. You can use a switch statement to check for specific error values and types instead of using the errors.Is and errors.As functions and creating temporary variables, etc.
  2. You can use an error value as a condition to check if it is nil or not.

Is this change backward compatible?

Yes, error handling as it is currently could still be used as an explicit style if my proposal is implemented.

Orthogonality: How does this change interact or overlap with existing features?

It alleviates the high foot traffic of repetitious error handling without inventing a completely new syntax.

Would this change make Go easier or harder to learn, and why?

I believe it would it make easier to learn primarily because it's easier to read:

integer, err := strconv.Atoi("-42")
if err {
   panic(err)
}

"Convert -42 as a string to an integer, and if there was an error, panic with said error."

Cost Description

As Mr. Griesemer wrote on The Go Blog, introducing this would be a new idiomatic way that everyone would have to start writing error handling code. That may be moot due to the fact my change does not break existing error-handling Go code, but I digress. In addition, users who are new to Go may conflate "errors as conditions" as truthiness from other languages, and may introduces proposals like it in the future (I am against truthiness in conditionals for Go code). But, if the conversion of error to bool is implemented, that may alleviate that, but also be verbose.

Changes to Go ToolChain

No response

Performance Costs

No response

Prototype

  1. Error switch construct
func parseInteger(input string) (int, error) {
    integer, err := strconv.Atoi("-42")
    switch err := err.(error) {
    case nil:
        return integer, nil
    case strconv.ErrRange:
        return 0, errors.New("input integer out of range")
    case *strconv.NumError:
        return 0, fmt.Errorf(`failed to convert input "%d" to integer: %s`, err.Num, err.Err)
    default:
        panic(err)
    }
}

Equivalent:

func parseInteger(input string) (any, error) {
    integer, errConvert := strconv.Atoi("-42")
    var errNum *strconv.NumError
    if errConvert == nil {
        return integer, nil
    } else if errors.Is(errConvert, strconv.ErrRange) {
        return 0, errors.New("input integer out of range")
    } else if errors.As(errConvert, &errNum) {
        return 0, fmt.Errorf(`failed to convert input "%d" to integer: %s`, errNum.Num, errNum.Err) {
    } else {
        panic(errConvert)
    }
}

2a. Errors as conditions:

integer, err := strconv.Atoi("-42")
if err {
    panic(err)
} else if !err { // Contrived I know, but to demonstrate inversion
    println("Hooray!")
}

Equivalent:

integer, err := strconv.Atoi("-42")
if err != nil {
    panic(err)
} else if err == nil { // Contrived I know, but to demonstrate inversion
    println("Hooray!")
}

2b. Converting error to bool 2a. Errors as conditions:

integer, err := strconv.Atoi("-42")
if bool(err) {
    panic(err)
} else if !bool(err) { // Contrived I know, but to demonstrate inversion
    println("Hooray!")
}

Equivalent:

integer, err := strconv.Atoi("-42")
if err != nil {
    panic(err)
} else if err == nil { // Contrived I know, but to demonstrate inversion
    println("Hooray!")
}

Comment From: seankhliao

As the blog you link to indicates:

We will also close all open and incoming proposals that concern themselves primarily with the syntax of error handling, without further investigation.

Comment From: sorucoder

What does "without further investigation." mean in this context? Surely it does not mean without consideration?

Comment From: seankhliao

It does mean we will not consider any changes to error handling syntax for the foreseeable future.