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.