Description
Author
Consider myself as intermediate go developer.
Experience: 2 years in production with go.
Other language experience: the most experience is in Js, tried many interesting things from LLVM IR to Nim and Odin.
Related proposals
Has this been proposed before? Variations have been proposed, this is discussed in the proposal.
Affect error handling: yes
Would this change make Go easier or harder to learn, and why?
This will make go harder by one middle-sized manual page. This will not be mandatory-to-use.
Proposal
Updated by comments at 19.01.23
Add a new "function" type template
, special expression
type for code blocks and inline
function for expression
insertion to template
. As example
template orPanic(err error, log expression) {
if err != nil {
inline(log)
panic(err)
}
}
func main() {
file, err := os.Open(filename)
orPanic(err, { log.Println(err) })
_, err = file.WriteString("example string")
orPanic(err, { log.Println(err) })
fmt.Println("string wrote")
}
should work as
func main() {
file, err := os.Open(filename)
if err != nil {
log.Println(err)
panic(err)
}
_, err = file.WriteString("example string")
if err != nil {
log.Println(err)
panic(err)
}
println("string wrote")
}
The most important difference between func
and template
is that func
share variables with template
, and template
is only a template of actions to insert to func
.
It seems like universal try
should be added to builtin library
template try(err error, catch expression) {
if err != nil {
inline(catch)
}
}
Why not use special keywords like try, catch and others?
The first reason is my personal reason - I wrote this sentence after monthly reading of other proposals on this topic which make me unhappy.
I selected Go as my primary language because of it's simplicity and human readability and i think new keywords will make it Java.
The second reason is that error handling problem is not error handling problem at all, it's a problem of template code which enrage developers. Now it's about errors, next we'll find some old-new places needs in template code problem solving.
Backward compatibility:
Full because no any go program in world use template
keyword.
Example code:
func OnRequest(response http.ResponseWriter, request *http.Request) {
onError := template(err error, status int) {
if err != nil {
response.WriteHeader(status)
return
}
}
...
onError(json.NewDecoder(req.Body).Decode(...), http.StatusBadRequest)
...
}
should work as
func OnRequest(response http.ResponseWriter, request *http.Request) {
...
err := json.NewDecoder(req.Body).Decode(...)
if err != nil {
response.WriteHeader(http.StatusBadRequest)
return
}
...
}
func main() {
_, err := os.Open(...)
try(err, { return }) // universal try from builtin example (above) usage
}
func ShouldReturn() (*Example, err) {
err := ...
try(err, { return nil, err }) // universal try from builtin example (above) usage
}
should work as
func main() {
_, err := os.Open(...)
if err != nil {
return
}
}
func ShouldReturn() (*Example, err) {
err := ...
if err != nil {
return nil, err
}
}
Cost of this proposal:
Tools to rework: compiler, vet, gopls
Compile time cost: grows with the size of the project, seems like generics cost
Runtime cost: no cost
Possible implementation:
The most stupid is read code for template and insert it on the next read, but it's not a go way.
I tried to write prototype as preprocessor but didn't finish it.