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/7f52cab8-7829-4e8e-9bf4-b1878c3bc7aen%40googlegroups.com.

Reply via email to