Hm, yep. Very similar. Interestingly, the only cohesive objections I can see in those threads are to the minor details that are different from what I'm saying. Still, though - at least the idea has been presented before.
Jeremy French 607-444-1725 On Mon, Nov 9, 2020, 2:57 PM Ian Lance Taylor <i...@golang.org> wrote: > 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/CA%2Bj6mhDjFAjpQTcpA3oJfwFKUYdhNn-1jB39FiYoe6nspUTg2g%40mail.gmail.com.