Thanks Miguel and I am not offended.. It sounds you like the proposal and 
your comments were not about the proposal per se but about the cultural 
issues surrounding change and fear of unnecessary growth; here we agree too.


On Friday, August 4, 2023 at 6:47:37 AM UTC-6 Miguel Angel Rivera 
Notararigo wrote:

>
>
> On Thu, Aug 3, 2023, 23:45 DrGo <salah....@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...@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 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/a3d051d9-6576-4bfc-a92b-ecf937dc972fn%40googlegroups.com.

Reply via email to