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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/78bf8c44-d1e4-4f70-a472-69b2746aef1an%40googlegroups.com.