It is not just resistance to change, it is about not adding new features
that add more complexity than value. I am pretty sure people will complain
about Go's error handling even if we use "orelse return err".

Generics add a lot of value, it shows the Go team is open to changes. But
imagine they add any feature people ask, C++ would be simpler than Go.

As I said, I like the proposal, but I have learned that some times, I have
to accept things are not always as I want them to be.

On Fri, Aug 4, 2023, 08:58 Victor Giordano <vitucho3...@gmail.com> wrote:

> As far as I see things there is always room for changes... but changes
> doesn't come without some resistance.. That is natural...
>
> >  Go best features is the lack of new features.
>
> What about generics? That was a major change... It was really necessary or
> not is another topic.
>
> El vie, 4 ago 2023 a las 9:47, Miguel Angel Rivera Notararigo (<
> ntr...@gmail.com>) escribió:
>
>>
>>
>> On Thu, Aug 3, 2023, 23:45 DrGo <salah.mah...@gmail.com> wrote:
>>
>>> @Miguel Angel Rivera Notararigo
>>>
>>> Thanks for taking the time to write...
>>>
>>> In my proposal, people are free to add as much context as they want...
>>>
>>
>> Yeah I know, I like your proposal, it is just how they handle errors in
>> the V programming language, although they use the keyword "or" and have
>> Options/Results.
>>
>> but as a demonstration, I am using the example from
>>> Ross Cox's paper on error handling that is used by all error handling
>>> proposals to show case their approach. I do not think Ross will
>>> take your criticism personally :)
>>>
>>
>> I know, but just because he wrote that, doesn't mean it is the perfect
>> example. If I find myself writing code like that, I would probably hate
>> Go's error handling too, but that might be said for any other feature of
>> the language if I write some bad looking examples.
>>
>> I don't see how he could take my opinion personally, I didn't mean to be
>> rude, I just said it is a bad example. I am not a native speaker, so my
>> apologies if I wrote something rude.
>>
>> I on the other hand take exception to your generalization re people who
>>> complain about error handling in Go.
>>> I am sure you did not make that claim without having some sort of solid
>>> research to support it. But, Go designers themselves admit that this is an
>>> issue and have written
>>> tons on it.
>>>
>>
>> You don't need a research or statistics if the complain is: "I don't want
>> to write 'if err != nil { return err }' every single time".
>>
>> It means they use "if err := w.Close(); err != nil { return err }" for
>> throwing the error, right? It is literally what they said or am I assuming?
>>
>> This same people will complain about your proposal, "I don't want to
>> write 'orelse return err' every single time", and then we will add
>> 'w.Close()!' or 'try w.Close()' to the language, and then we will be very
>> happy with our Go++ wich has 3 ways of doing the same thing.
>>
>>
>>> In one or two replies above we were discussing how error handling
>>> opinions can become religions each with its own priests who think they are
>>> the only saved faction, and that their rituals are the only right approach
>>> for all situations.
>>>
>>
>> I know, as I said, I like your proposal, but one of Go best features is
>> the lack of new features. I am arguing against my own taste, because I like
>> 'w.Close() or return fmt.Errorf("cannot close destination: %v", err)', but
>> I like more the simplicity of Go.
>>
>>
>>> Best wishes,
>>>
>>>
>>> On Thursday, August 3, 2023 at 9:07:52 PM UTC-6 Miguel Angel Rivera
>>> Notararigo wrote:
>>>
>>> func CopyFile(src, dst string) error {
>>> r, err := os.Open(src)
>>> if err != nil {
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>> defer r.Close()
>>>
>>> w, err := os.Create(dst)
>>> if err != nil {
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>>
>>> if _, err := io.Copy(w, r); err != nil {
>>> w.Close()
>>> os.Remove(dst)
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>>
>>> if err := w.Close(); err != nil {
>>> os.Remove(dst)
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>> }
>>>
>>> I think it is a bad example, how do you know where CopyFile failed?
>>>
>>> The "copy ..." part shouldn't be in there, you should add valuable
>>> context to your errors, if CopyFile fails, the caller already knows it was
>>> a copy error because the function has a big "Copy" on his name right? you
>>> should do this instead:
>>>
>>> func CopyFile(dst, src string) error {
>>>   r, errOS := os.Open(src) // Avoid shadowing errors, don't use err
>>>   if errOS != nil {
>>>     return fmt.Errorf("cannot open source: %v", errOS)
>>>   }
>>>
>>>   defer r.Close()
>>>
>>>   w, errCD := os.Create(dst)
>>>   if errCD != nil {
>>>     return fmt.Errorf("cannot create destination: %v", errCD)
>>>   }
>>>
>>>   defer w.Close()
>>>
>>>   if _, err := io.Copy(w, r); err != nil { // Local scope error, so err
>>> is fine
>>>     os.Remove(dst)
>>>     return fmt.Errorf("cannot copy data from source: %v", err)
>>>
>>>   }
>>>
>>>   if err := w.Close(); err != nil {
>>>     os.Remove(dst)
>>>     return fmt.Errorf("cannot close destination", err)
>>>   }
>>> }
>>>
>>> // Caller should do this.
>>> if err := CopyFile("dst.txt", "src.txt"); err != nil {
>>>   // Here is where you should add 'copy' to the error message.
>>>   return fmt.Errorf("cannot copy '%s' to '%s': %v", src, dst, err)
>>> }
>>>
>>> People complaining about Go's error handling regularly don't handle
>>> errors, they just throw them like exceptions.
>>>
>>> If you really hate Go's error handling, just use:
>>>
>>> func catch(err error) {
>>>   if err != nil {
>>>     panic(err)
>>>   }
>>>
>>>   // And use recover somewhere
>>> }
>>>
>>> Which is a bad practice, but at least we (the people who like how Go
>>> handle errors) can still handle our errors without any language change.
>>>
>>> On Tue, Aug 1, 2023, 13:06 DrGo wrote:
>>>
>>> Thanks.
>>> The keystroke saving is not the motivation. The aim is to reduce the
>>> code reader’s mental load. My approach allows for clearer code where the
>>> main program logic is not dwarfed by the error handling code while
>>> maintaining the explicitly of error handling and the possible error-induced
>>> interruption in program flow. It avoids creating new if scope when one is
>>> not desired and offers opportunities for further deduplication of error
>>> handling code although each error is still handled individually. Compare
>>> the following; which one would you prefer to read a lot of?
>>>
>>> - current approach; error handling to program logic ratio: 13:5
>>>
>>> func CopyFile(src, dst string) error {
>>> r, err := os.Open(src)
>>> if err != nil {
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>> defer r.Close()
>>>
>>> w, err := os.Create(dst)
>>> if err != nil {
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>>
>>> if _, err := io.Copy(w, r); err != nil {
>>> w.Close()
>>> os.Remove(dst)
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>>
>>> if err := w.Close(); err != nil {
>>> os.Remove(dst)
>>> return fmt.Errorf("copy %s %s: %v", src, dst, err)
>>> }
>>> }
>>>
>>> - new approach ratio 5:5
>>> 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)
>>> }
>>> }
>>>
>>> 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/36110a8d-a26f-48be-83fd-73af755e88f4n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/36110a8d-a26f-48be-83fd-73af755e88f4n%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/2c9fa4b1-e536-4743-ac20-181e550bd14fn%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/2c9fa4b1-e536-4743-ac20-181e550bd14fn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "golang-nuts" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/golang-nuts/dRLR4hxxI8A/unsubscribe.
>> To unsubscribe from this group and all its topics, 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/CAF9DLCkTKJz8tpOwFQzV%3DoXe6R6aS-0ssnXdwDraDS112gnQ0w%40mail.gmail.com
>> <https://groups.google.com/d/msgid/golang-nuts/CAF9DLCkTKJz8tpOwFQzV%3DoXe6R6aS-0ssnXdwDraDS112gnQ0w%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>
>
> --
> V
>

-- 
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/CAF9DLCn_VWFFocEfR3EmXOuAc7RCJjmCgcayCf_EyfH81P9J_w%40mail.gmail.com.

Reply via email to