golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.26k stars 17.57k forks source link

proposal: Go2: error handling with #err suffix #67251

Closed mainjzb closed 1 month ago

mainjzb commented 4 months ago

Go Programming Experience

4 years

Other Languages Experience

C, C++, Java, Dart, zig, rust

Related Idea

Proposal

scr: https://github.com/mainjzb/goerr

Make # as error symbol, I believe people can learn and understand it quickly. (Maybe other symbol replace it)

#@ as handler error symbol. Help people read code and simplify code.

I have read go/issues/21161 My imaging is something similar to that.

before

n, err := io.Write(x) // 1. err as value
n, _ := io.Write(x)  // 2. ignore error

// 3. return error immediately、
n, err := io.Write(x)
if err != nil {
   return 0, err
}

// 4. wrap additional information
n, err := io.Write(x)
if err != nil {
   return 0, fmt.Error("tcp closed: %w", err)
}

// 5. panic err
n, err := io.Write(x)
if err != nil{
    panic(err)
}

now

n := io.Write(x) #err       // 1. err as value

n := io.Write(x) #@ignore   // 2. ignore error

n := io.Write(x) #@done     //  3. return error immediately、

n := io.Write(x) #@wrap("tcp closed: %w") // 4. wrap additional information

n := io.Write(x) #@must     // 5. panic err
  1. err as value. everything is like before. just error at suffix.
  2. ignore error. make it no easier to ignore error than before. Encourage people with additional information. igmore 6 char more than other 4 char
  3. return error immediately. Many times, Especially in libiary. we just need returen error nothing need to do. For example: url.parseAuthority
  4. wrap additional information. maybe more easy way is #@wrap equal to #@wrap("io.Wirite err:"), omit parameter make it easier for people to handle error instead of ignore error.
  5. Many third-party libraries have MustXxx() and Xxx() two sets api. Now we just need only one. Just like go keyword, we no longer need sync and async functions.

People should reduce the discussion of compilation details. Focusing on achieving agreement on lang style.

Method chaining

move error to suffix have other benefit that separate return value and error. now we can Method chaining. Some people dislike Method Chaining but I like it.

func div(a, b float64) (float64, error) {...}
func sum(a, b float64) (float64, error) {...}

func handler() (float64, error){
  res := sum(div(0,7), div(4,5)) #err
  if err != nil{
      log.Error("do calc err: ", err)
      return 0, err 
  }
  return res, nil
}

Is this change backward compatible?

No

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

This is an orthogonal new feature that can be used not only for error handling, but also to reduce repetitive boilerplate in other cases.

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

Most language errors are more complex. Only by making people aware that this is complex can they pay attention to it

Cost Description

No response

Changes to Go ToolChain

All of them.

Performance Costs

Compile time: extra injection work. Run time cost: none.

Prototype

No

ianlancetaylor commented 4 months ago

Thanks, but this is not like anything else in Go. A change in Go for error handling has to do more than just reduce error boiling boilerplate: it has to fit into the rest of the language.

ianlancetaylor commented 4 months ago

Based on the discussion above and the emoji voting, this is a likely decline. Leaving open for four weeks for final comments.

findleyr commented 1 month ago

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