On Mon, Nov 9, 2020 at 11:20 AM Jeremy French <ibi...@gmail.com> wrote: > > First, the caveat. I know error handling is a long-standing discussion. I > know there has been lots of debate on error handling, and it can seem like > there are no more new ideas to be had on the topic. And I have looked at > several/most of the most popular proposals, and there are quite a few that > bear similarity but are critically different in important aspects to this > proposal. If this has been proposed before with the same effective > fingerprint, I haven't been able to find it after several hours of due > diligence. I'm interested in hearing any and all (well-reasoned) thoughts on > the matter, but if there's a flaw in my logic, I don't see it yet. > > In short, the proposal is to create a conditional return statement, e.g. > "returnif" of the form: > returnif [bool], [returnvalue],... > > This is syntactic sugar for: > if [bool] { > return [returnvalue],... > } > > of which, the immediate benefit is: > returnif err!=nil, err > > or alternatively: > > returnif myErrorChecker(err), myErrorWrapper(err, "Some text.") > > Here's my reasoning. Go Error Handling in is current form is extremely > correct, precise, explicit, and clear. All very good things. Really the > only problem with it is the repetitious verbosity. A programmer's > instinctive reaction to repetitious verbosity is to wrap it in a function. > The infamous "if err != nil {return err}", although repetitious and > ubiquitous, cannot effectively be encapsulated to "return > someErrorChecker()", because the return statement is unconditional. Once I > start a statement with return, nothing I can do later in the statement or > within a called function can change whether or how that return alters flow > control. This, I think, is the quintessential problem with the current error > handling methodology. This proposal addresses that without sacrificing any > of the good things about error handling in Go. Error handling is still > explicit. Errors can still be treated as values. Proper error handling and > annotating is blessed but optional. The behavior of defer is unaffected. It > is still simple to understand, and easy to read. And it's entirely backwards > compatible. > > Also, while the most obvious benefit is in error handling, this is not > technically just an error handling solution. It is completely unopinionated > on the type of values it returns, or whether they qualify as an error or not. > I can foresee enterprising gophers finding other uses for this keyword, and > quite possibly even new useful design patterns could emerge as a result. > > Possible Objections: > > It could be seen to violate the "one way to do things" principle. However, > > It violates this rule much less than almost all of the other proposals for > error handling. > If, under the covers, it's just code substitution, then there's still only > one actual avenue of execution in the compiled objects. > There is precedent for this type of shortcut when the benefits are so > widespread and the sugar improves readability. For example, > } else if isTrue { > doSomething() > } > is sugar for > } else { > if isTrue { > doSomething() > } > } > > "It's just a variation on other existing proposals." > > This proposal avoids or addresses all the objections listed in the error > handling meta issue #40432, and as such, may be a variation, but varies > sufficiently to create a different result set. > From the meta issue: > > The check/handle proposal. > > One major reason this was rejected was a lack of clarity between handle and > defer. > > The try proposal. > > One major reason this was rejected was the additional flow control: a complex > expression using try could cause the function to return. Go currently has no > flow control constructs at the expression level, other than panic which does > more than just return from a function. > > Special characters, often ! or ?, that insert an error check in a function > call or assignment. > > These are typically rejected because they are cryptic. Often a single ! or > other character leads to a change in flow control. > > Simplifications of if err != nil, to reduce boilerplate. > > These are typically rejected either because they don't reduce the boilerplate > enough to make it worth changing the language, or because they are cryptic. > > What about edge cases? How to handle else clauses or additional conditional > logic based on error type etc.? > > It's my belief that else clauses too rare to justify additional syntax. If > you need an else/else if clause, you can use the existing syntax and lay out > your conditionals on more lines. Also - you know - any code after a return > statement is essential an else clause anyway. > By making [bool] an expression, any additional logic may be handled by the > programmer in a determinant function that returns a boolean. This puts this > type of flow control in the hands of the developer. > The short statement currently available with if and for statements (if > err:=doSomething(); err != nil) could be implemented in a similar fashion, > but my personal vote would be to disallow it, as most of the simplicity and > clarity of this proposal could be lost down that rabbit hole. > > I believe the most critical difference between this proposal and previous > ones is that this proposal addresses the core issue more directly. The > central problem to the current error handling methodology is not actually > specific to error handling. That's just where it's most visible. The core > problem is essentially the fact that a child function cannot affect the > conditional return of a parent function (barring further conditional logic), > even with explicit permission by the parent function. This is not true with > any other form of flow control. This is why the current methodology feels > wrong to developers, because they are disallowed from encapsulating > repetitious logic in a way that is consistent with other flow control > statements. > > Anyway, that's my argument. If anyone knows of a previous proposal that this > duplicates, and/or knows why that one didn't/couldn't work, I'd be grateful > for the explanation.
For the record, similar but not quite identical: https://github.com/golang/go/issues/21161#issuecomment-366766924 https://github.com/golang/go/issues/32811#issuecomment-508776641 Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcUm8UUXaKyYUBPq3QcJSoyB%2BVerRNj8WVCng0ruzhUBcQ%40mail.gmail.com.