If I may make a suggestion to @ianlancetaylor, I think using the ? for error checking is a fantastic idea, but I think a couple small changes would make this absolutely a game changer and even more Go-like:
To demonstrate my tweak to your idea, imagine this example code:
As you can see this is much shorter! Having the block is always required at the end of the "chain" of question mark statements is more consistent with how `if` statements require a block currently. It also makes the `return err` flow also always visible (no return magic). It also also has a huge advantage of it being much harder to miss a question mark syntactically. as a question mark without a block would be a syntax error.
To demonstrate my tweak to your idea, imagine this example code:
r, err := SomeFunction() if err != nil { return fmt.Errorf("something 1 failed: %v", err) }
r2, err := SomeFunction2() if err != nil { return fmt.Errorf("something 2 failed: %v", err) }
r3, err := SomeFunction3() if err != nil { return fmt.Errorf("something 3 failed: %v", err) }
In the current proposal it would turn into this:
r := SomeFunction() ? { return fmt.Errorf("something 1 failed: %v", err) }
r2 := SomeFunction2() ? { return fmt.Errorf("something 2 failed: %v", err) }
r3 := SomeFunction3() ? { return fmt.Errorf("something 3 failed: %v", err) }
My first suggestion is to keep `err` variables visible. It ends up being not much longer, but it is much more readable and Go-like:
r, err := SomeFunction() ? { return fmt.Errorf("something 1 failed: %v", err) }
r2, err := SomeFunction2() ? { return fmt.Errorf("something 2 failed: %v", err) }
r3, err := SomeFunction3() ? { return fmt.Errorf("something 3 failed: %v", err) }
My second suggestion is to require ? to always have a block, and also allow them to "chain" so only the last statement needs a block:
r, err := SomeFunction() ? r2, err := SomeFunction2() ? r3, err := SomeFunction3() ? { return fmt.Errorf("something 1, 2 or 3 failed: %v", err) }
As you can see this is much shorter! Having the block is always required at the end of the "chain" of question mark statements is more consistent with how `if` statements require a block currently. It also makes the `return err` flow also always visible (no return magic). It also also has a huge advantage of it being much harder to miss a question mark syntactically. as a question mark without a block would be a syntax error.
For example, this is an error:
r, err := SomeFunction() ? // <-- compile error: missing block after ?
And also this is an error:
r, err := SomeFunction() ? r2, err := SomeFunction2() // <-- compile error: missing block after ? r3, err := SomeFunction3() ? { return fmt.Errorf("something 1, 2 or 3 failed: %v", err) }
Thanks for listening! Curious what folks think.