Code in Go that propagates errors can get pretty verbose. For example:
a, err := ...
if err != nil {
return nil, err
}
b, err := ...
if err != nil {
return nil, err
}
In this proposal, the preceding example would be written as:
error a, return (nil,_) := ...
error b, return (nil,_) := ...
This example would be transformed by the compiler to:
a, #unique1 := ...
if #unique1 != #0value {
return nil, #unique1
}
b, #unique2 := ...
if #unique2 != #0value {
return nil, #unique2
}
#unique1
is a unique compiler-generated identifier and #0value
is the
zero value for the relevant type.
The error-return statement begins with the error keyword, followed by a short variable declaration with one or more of the assignments replaced by a return, which, if the value assigned is not the zero value, will be executed. Any _ in the return is the value assigned.
Although the statement begins with the error keyword, the error type is not special per se. The statement begins with the keyword so that the parsing of return statements is not made more complicated. With a look-ahead parser, the error keyword could be omitted.
Multiple return assignments are handled from left to right:
error return _, return nil := ...
would be transformed to:
#unique1, #unique2 := ...
if #unique1 != #0value {
return #unique1
}
if #unique2 != #0value {
return nil
}