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.

Reply via email to