Thanks for the valuable feedback,
The verbosity of error handling is the number one concern for Go developers 
in the most recent survey. So there is a need for doing something about 
it.. except that there are many possibly conflicting requirements outlined 
by the Go team. 
The problem with the abbreviated if err!= nil in your example:
  if x,err := something() ; err != nil {
        handleErrorAndReturn
    }
is that x is local to the if scope and often that won't work forcing the 
more verbose:
   x,err := something()
  if err != nil {
        handleErrorAndReturn
    } 
If you have few of those as is the case in io programs; there is real 
impact on the readability of the code.
the oresle approach avoids that problem (the x stays in the scope of the 
func).

   x,err := something() orelse {
        handleErrorAndReturn
    } 
You do not think this is a significant  reduction in boilerplate? The only 
thing that will do a better job is a try-catch which is not acceptable to 
the Go team (fortunately). 

why the line-by-line would break with orelse? they are working fine with 
the one-liner you cited:
  if x,err := something() ; err != nil 

Why it won't work with one time retires? That is like one time retires 
won't work in an if-else block.

Thanks again,

On Monday, July 31, 2023 at 3:59:50 PM UTC-6 Tim Casey wrote:

>
>
> 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....@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...@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/9453a6fe-04c2-4c6d-88e9-4ec1cbd59361n%40googlegroups.com.

Reply via email to