I do not think this reduces boilerplate code.  This compacts it, which is
different.

I think any one-liner-return-on-err makes the language harder to debug.  It
is very common breakpoints are set for exceptional cases, which tend to be
surprising.  If the test and the return are on the same line then all of
the line-by-line tools will break down, at least a little bit.

If you see:
    x,err := something() ; err != nil {
        handleErrorAndReturn
    }

At the very least, the template will not work for things like one time
retries, if error do something else, log the error and
DoSomethingAdditional().  This would be a sub scope and in golang i would
expect this to have '{}' as part of the scope shift.  If this is
acceptable, then you are very likely to be on a separate line in any
event.  So the original looks like:

  err := io.Copy(w, r) *orelse* {
DoSomethingElse()
}

This means the only 'boilerplate' is 'orelse' <- '; err != nil', which
seems rather expensive for this error handling.

As a slight change of subject, I find the whole discussion about 'saving'
boilerplate to be well over-stated, too much work and energy (at least by
me as an outside observer).  Having something which fits within the design
of the language, making it a developer centric language, would seem to
fight with any one-line-template approach.

tim





The test and the handle all fit on one line.   I dont think having a single
line return, like perl 'next if STATEMENT' style fits within golang
language goals.

On Mon, Jul 31, 2023 at 8:18 AM DrGo <salah.mah...@gmail.com> wrote:

> Me too but I do not have high hopes
>
>
> On Monday, July 31, 2023 at 12:10:24 AM UTC-6 Mark wrote:
>
>> Given that this proposal is to reduce boilerplate, and assuming the
>> semantic issues could be solved, it seems to me that the 'return' is
>> redundant (i.e., could be implicit) and that 'orelse' could be done with
>> the existing 'else' keyword, i.e.,
>>
>> ```
>> result, err := someCall() else rest, err
>> ```
>> Anyway, I really do hope the long-winded error syntax gets solved somehow!
>>
>> On Monday, July 31, 2023 at 5:41:49 AM UTC+1 DrGo wrote:
>>
>>> func myFirstFunction() (string, err) {
>>>
>>>    result, err := myFunction() orelse return rest, err
>>>
>>> }
>>>
>>> On Sunday, July 30, 2023 at 9:27:27 PM UTC-6 Marcello H wrote:
>>>
>>>> I think the current error handling is just fine.
>>>> For the extra typing, they invented keyboard snippets and such.
>>>>
>>>> But for this proposal, I would like to see how a return with multiple
>>>> values would look to get a better understanding.
>>>> ```
>>>> // translate this in the proposed solution?
>>>> func myFirstFunction() (string, err) {
>>>>    result, err := myFunction()
>>>>    if err != nill {
>>>>        return rest, err
>>>>    }
>>>> }
>>>> ```
>>>>
>>>> Op maandag 31 juli 2023 om 04:32:01 UTC+2 schreef DrGo:
>>>>
>>>>> Another possibility Jeremy is that the orelse block is executed if any
>>>>> of the returned error values is not nil.
>>>>>
>>>>> On Sunday, July 30, 2023 at 8:14:58 PM UTC-6 DrGo wrote:
>>>>>
>>>>>> Thanks...
>>>>>> yes indeed. Too many requirements but I think this solution comes
>>>>>> close to meeting them. If a rare function returns more than one error 
>>>>>> value
>>>>>> (yet to see one in the wild) then the compiler should reject orelse use 
>>>>>> and
>>>>>> the user can fallback on the (the if err!= nil) approach.
>>>>>>
>>>>>> On Sunday, July 30, 2023 at 6:02:57 PM UTC-6 Jeremy French wrote:
>>>>>>
>>>>>>> Also, errors are values, which means - although uncommon - a
>>>>>>> function could return two or more error values.  Which would orelse
>>>>>>> evaluate?  Even if you arbitrarily chose one, that would violate the
>>>>>>> explicit vs implicit code flow principle.
>>>>>>>
>>>>>>> My sympathies, OP.  I too hate the "if err!= nil" boilerplate, and
>>>>>>> have suggested my own idea for fixing it, which was similarly dismantled
>>>>>>> for good reasons by those more knowledgeable than me.  The truth is, 
>>>>>>> this
>>>>>>> problem/issue has so many restrictions placed on it (currently idiomatic
>>>>>>> principles, backwards compatibility promise, explicit vs implicit, etc)
>>>>>>> that the set of possible solutions is VERY narrow, possibly infinitely 
>>>>>>> so.
>>>>>>>
>>>>>>> On Sunday, July 30, 2023 at 3:51:49 PM UTC-4 Brian Candler wrote:
>>>>>>>
>>>>>>> err := io.Copy(w, r) *orelse* {
>>>>>>> w.Close()
>>>>>>> os.Remove(dst)
>>>>>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>>>>>> }
>>>>>>>
>>>>>>> My question still stands. Semantically, what value exactly does the
>>>>>>> "orelse" condition test is not equal to nil?
>>>>>>>
>>>>>>> - does it test the value from the preceding assignment? If so, is
>>>>>>> "orelse" only valid immediately following an assignment expression? The
>>>>>>> original posting didn't say this.  And if it *is* linked to an 
>>>>>>> assignment
>>>>>>> expression which assigns multiple values, does it only look at the last
>>>>>>> value? (Again, that was not specified)
>>>>>>>
>>>>>>> - does it always test a variable called "err"? The original posting
>>>>>>> said it was equivalent to "if err!=nil" but a later post contradicted 
>>>>>>> this
>>>>>>>
>>>>>>> - does it test the value from the 'return' expression at the end of
>>>>>>> the block following orelse? Except in this case, it can't because it's
>>>>>>> buried inside fmt.Errorf
>>>>>>>
>>>>>>> On Sunday, 30 July 2023 at 17:55:34 UTC+1 DrGo wrote:
>>>>>>>
>>>>>>> Good point Harri,
>>>>>>>
>>>>>>> This is what the correct version will look like using this proposal
>>>>>>>
>>>>>>> func CopyFile(src, dst string) error {
>>>>>>> r, err := os.Open(src) *orelse* return fmt.Errorf("copy %s %s: %v",
>>>>>>> src, dst, err)
>>>>>>> defer r.Close()
>>>>>>>
>>>>>>> w, err := os.Create(dst); *orelse* return fmt.Errorf("copy %s %s: %v
>>>>>>> ", src, dst, err)
>>>>>>> err := io.Copy(w, r) *orelse* {
>>>>>>> w.Close()
>>>>>>> os.Remove(dst)
>>>>>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>>>>>> }
>>>>>>>
>>>>>>> err := w.Close() *orelse* {
>>>>>>> os.Remove(dst)
>>>>>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> In a more complex func, the error formatting/handling code can be
>>>>>>> further deduplicated by extracting it into a closure.
>>>>>>> e.g.,
>>>>>>>
>>>>>>> func CopyFile(src, dst string) error {
>>>>>>> copyErr:= func(err error) {
>>>>>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>>>>>> }
>>>>>>> r, err := os.Open(src) *orelse* return copyErr(err)
>>>>>>> defer r.Close()
>>>>>>>
>>>>>>> w, err := os.Create(dst); *orelse* return copyErr(err)
>>>>>>> err := io.Copy(w, r) *orelse* {
>>>>>>> w.Close()
>>>>>>> os.Remove(dst)
>>>>>>> return copyErr(err)
>>>>>>> }
>>>>>>>
>>>>>>> err := w.Close() *orelse* {
>>>>>>> os.Remove(dst)
>>>>>>> return copyErr(err)
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> On Sunday, July 30, 2023 at 8:17:31 AM UTC-6 Harri L wrote:
>>>>>>>
>>>>>>> IMHO, you have used the irrelevant example (== 2nd code block) from
>>>>>>> Russ Cox's paper. The paper says:
>>>>>>> > This code is not nice, not clean, not elegant, *and still wrong:*
>>>>>>> like the previous version, it does not remove dst when io.Copy or
>>>>>>> w.Close fails.
>>>>>>>
>>>>>>> I want to compare your proposal with the third example from the
>>>>>>> paper, which does (proper) error annotation and cleanup. Thanks.
>>>>>>> On Sunday, July 30, 2023 at 8:57:15 AM UTC+3 DrGo wrote:
>>>>>>>
>>>>>>> I looked at the long list of proposals to improve error handling in
>>>>>>> go but I have not seen the one I am describing below. If I missed a 
>>>>>>> similar
>>>>>>> , can you pls direct me to where I can find it. If not what do you 
>>>>>>> think of
>>>>>>> this approach.
>>>>>>>
>>>>>>> This involves introducing a new keyword "orelse" that is a syntactic
>>>>>>> sugar for an "if err!=nil" block.
>>>>>>>
>>>>>>> The example code in Russ Cox's paper[1] will look something like
>>>>>>> this:
>>>>>>>
>>>>>>> func CopyFile(src, dst string) error {
>>>>>>>
>>>>>>> r, err := os.Open(src) orelse return err
>>>>>>>
>>>>>>> defer r.Close()
>>>>>>>
>>>>>>> w, err := os.Create(dst) orelse return err
>>>>>>>
>>>>>>> defer w.Close()
>>>>>>>
>>>>>>>   err = io.Copy(w, r) orelse return err
>>>>>>>
>>>>>>> err = w.Close() orelse return err
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> It is an error to not return an error from an orelse block.
>>>>>>>
>>>>>>> In my eyes, this has the same explicitness and flexibility of the
>>>>>>> current style but is significantly less verbose. It permits ignoring the
>>>>>>> error, returning it as is or wrapping it. Because orelse is not used for
>>>>>>> any other purpose, it would be easy for reviewers and linters to spot 
>>>>>>> lack
>>>>>>> of error handling.
>>>>>>>
>>>>>>> It also works well with named returns. e.g.,
>>>>>>>
>>>>>>> func returnsObjorErro() (obj Obj, err error) {
>>>>>>>
>>>>>>>   obj, err := createObj() orelse return  //returns nil and err
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> otherwise orelse is like "else" so e.g., it can be followed by a
>>>>>>> block if additional cleanup or error formatting etc is needed before
>>>>>>> returning, eg
>>>>>>> w, err := os.Create(dst) orelse {
>>>>>>>   ....
>>>>>>>   return err
>>>>>>> }
>>>>>>>
>>>>>>> Similarity to "else" hopefully means that it is easy to learn. It is
>>>>>>> obviously backward compatible
>>>>>>>
>>>>>>> What do you think?
>>>>>>>
>>>>>>> [1]
>>>>>>> https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md
>>>>>>>
>>>>>>> --
> 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/b87365af-9a72-4f8d-ad0b-1ee69cc1ad35n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/b87365af-9a72-4f8d-ad0b-1ee69cc1ad35n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAMyFqkQof71j5wUEk3RGPUyE6o5u-8NydzwHzk9%2BqtBdc4zu1g%40mail.gmail.com.

Reply via email to