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/CAPUu9suo4k_0qF1HjVAYX0W%2BkNoqrT02cX8pxdoa4F1qx9g0Kg%40mail.gmail.com.

Reply via email to