proposal: Go 2: `onErr` simple macro for common case error handling. A #32437 counter-proposal.

This is a counter-proposal to the #32437. It uses the on err words proposed in #32611and #32848 but unlike #32611 it is specifically restricted to the ubiquitous and a defacto standard err identifier (variable) followed by a block, control-flow statement; or a call to the built-in panic() function.

Usage examples

c, err := fn()
onErr continue

c, err := fn()
onErr {
    x++
    break
}

if r, err := fn(); onErr && triesleft > 0 {
  triesleft--
  continue retry
}

if c, err := fn(); onErr {
    return 0, err
}

Go Specification amendments

Operators

log_op = "||" | "&&" .

Statements addition:

ctlflstmt       = ( ReturnStmt | BreakStmt | ContinueStmt | GotoStmt )
OnErrStmt       = "onErr" ctlflstmt
OnErrSimpleStmt = "onErr" ( block | log_op )

Blocks addition:

6.  ctlflstmt statement in the OnErrStmt is considered to be in its own implicit block.

onErr macro

to be added after Defer_statements.

The onErr macro simplifies repeatable error handling, checking whether err variable is not nil. Ie. the very onErr always is expanded to mean if err != nil. The err identifier must be in the scope.

After an onErr either a block, or five possible statements are allowed: continue, break, return, goto, and a call to panic(…) built-in. Then expansion occurs:

  1. The onErr always is expanded to the if err != nil statement.
  2. If there is a block or a logical or or and operator after the onErr, expansion ends.
  3. If there is an allowed statement, it acts as given in an implicit curly braces.

Implementation:

after recognizing an onErr token, hardcode the if err != nil template and subparse rest of the line. The core of the expansion likely will land somewhere within parser.go:2040 scope in the case _Onerr:

A macro?

@griesemer suggested that try is just a macro. So I dare to propose a macro too, based on an ‘invisible semicolons’ precedence and with a straightforward implementation.

thats all,

enjoy!

ohir


Edits:

  • added explicit log_op to allow expansion in expression chains. Add usage example for it.

1 thought on “proposal: Go 2: `onErr` simple macro for common case error handling. A #32437 counter-proposal.

  1. As you’ve noted, this is short-hand for if err != nil in all cases. Personally I do not think this is a particularly useful construct nor does it add any more value beyond saving a handful of characters (as well as allowing syntax such as onErr continue, which is effectively a text substitution that also expands to include braces).

    I feel like this adds extra cognitive overload, without really delivering value to developers (my 2c!).

    Go need a hygienic macro feature where we can define macros ourselves

    I’m a big -1 on this idea – it will lead to everyones codebase being ‘specialised’, with custom macros and definitions all over the place. Switching between projects because a huge mental burden, and it starts to smell of similar features in other, older languages that quickly grow out of control.

Comments are closed.