Live data from Hacker News

Why I’m not leaving Python for Go

uberpython.wordpress.com

91–100 of 245 posts

Re: Why I’m not leaving Python for Go

#91
post #53

If you use a language that uses error codes, then you're forced to explicitly think about what to do in every single error case (or not, and accept the consequences). This can add a lot of mental overhead, but can result in a much more robust and well-thought-out program. But because more logic is involved period (to handle the robustness), the program is necessarily more complex. If you use exception handling, then…

I would guess that most (99%) of C programmers are lazy or has an rapid programming style then. Its a rare thing to see C source code that even do the simple thing like wrapping every write/read/print call with a loop that detects eintr. In my years of programming, I have yet to stumble on a other programer who even knows that one should be doing this. Looking at c libraries and their example code, almost every time,…

In Go if you use the return value of a function you must also assign the error to something, either a variable or explicitly ignore it by assigning it to _. It was designed this way specifically to avoid the problem of not checking error conditions in C code.

Re: Why I’m not leaving Python for Go

#92
post #71

Exceptions are like garbage collection. Garbage collection relieves you from the drudgery, accounting and bureaucracy of manual memory management and indirectly leads to more expressive forms of programming once function boundaries are freed from having to specify who owns the data being passed back and forth. But you still need to be aware of space vs time usage, you still need to know where memory is being allocate…

>In the hands of someone who knows what's going on, programs get much simpler

I never really got this argument. With RAII types that have value semantics (ala shared_ptr) what is so difficult about memory management in C++? I guess there are reference cycles, but weak_ptr can help there. Manual ref-counting (like a COM AddRef/Release pattern) can be tricky, but that is where attention to detail, code reviews and basic competence come in. RAII wrappers with value semantics help here too. Most problems I have seen with that have been people simply not bothering to learn even the basics or using "smart" objects without understanding how they work or how to use them properly, which really isn't that hard, honestly.

>that isn't IMHO a good reason to dislike the "magic" behaviour of exceptions.

Agreed, my primary pain point around exceptions is people that write functions that mutate some state and are interrupted in the middle via an exception and stack unwind leaves objects in some franken-state. Transactional semantics in the face of exceptions don't just happen except in trivial cases (i.e. functions that don't mutate state or have trivial unwind semantics where they must only restore say a single mutated value).

That said the same problem exists anytime there is state mutation and multiple, failure exit paths. For some reason I guess the code I have seen using error code return style tends to handle this better. Could just be some kind of selection bias.

Re: Why I’m not leaving Python for Go

#93
post #87
post #5

Earlier quoted context omitted.

What is it about panic/recover that forking the language , not merely using Go in a non-idiomatic way, would be necessary? I could see forking it to add generics in a way that the official guys aren't satisfied with, but why is that needed to use another style of error handling?

Anyone using panic/recover across API boundaries to emulate exceptions should have their brains gofmt-d. But so far I have not noticed anyone doing this, perhaps because actually returning and handling errors properly is not as much of an issue as most people make it to be.

I personally like Go's error handling so I wouldn't consider doing it, but what exactly would be the issue with doing so?

The reasons not to that I have seen are all basically boil down to "Because you're not supposed to, it's not what it's for". Because of how recover works it certainly wouldn't make sense to use it exactly the same as try/catch is generally used, but what exactly would be the problem with using panic/recover for more common cases (less 'exceptional' cases...) if we've already decided to not value writing idiomatic code?

It strikes me as a terrible idea, but try/catch does too.. I guess I don't understand why it would be even worse than that.

Re: Why I’m not leaving Python for Go

#94

If you use a language that uses error codes, then you're forced to explicitly think about what to do in every single error case (or not, and accept the consequences). This can add a lot of mental overhead, but can result in a much more robust and well-thought-out program. But because more logic is involved period (to handle the robustness), the program is necessarily more complex. If you use exception handling, then…

Or, ya know, you just do:

  if (!herp_derp()){
  ...
  }
or

  if (herp_derp() > 0){
  ...
  }
and don't actually check any of the error cases that you should be checking, like return = -1, -2, -3 etc.

Re: Why I’m not leaving Python for Go

#95

If you use a language that uses error codes, then you're forced to explicitly think about what to do in every single error case (or not, and accept the consequences). This can add a lot of mental overhead, but can result in a much more robust and well-thought-out program. But because more logic is involved period (to handle the robustness), the program is necessarily more complex. If you use exception handling, then…

"Of course, you can add more code to deal individually with each of the exceptions in more robust ways, even to the point of wrapping each statement in its own try/catch block, but then it's no different in practice from returning error codes." It is very different. With a try/catch block, you can see the normal logic flow of your code in one place, separated from the error handling logic. If you wrap each and every…

Not at all. If a function can't or shouldn't be responsible for handling an error, it can return that error. The result is that the error passes back up the call stack until something handles it.

It's very similar to exceptions, except you have to consciously choose to do it. That's a virtue to me.

Re: Why I’m not leaving Python for Go

#96
post #70

Earlier quoted context omitted.

The following illustrates how you use Go errors as if they were exceptions: func A() error { err := compute.Something() if err != nil { return err } return nil } Throwing errors up the return chain using error values is really very little different than throwing up the return chain using exceptions, except that now there is only one way to return, and it is always clearly marked. You return where you say "return". An…

How is that different from func A() error { return compute.Something() }

The example is easier to extend to include additional logic after the call or another return value.

Re: Why I’m not leaving Python for Go

#97
post #93
post #87

Earlier quoted context omitted.

Anyone using panic/recover across API boundaries to emulate exceptions should have their brains gofmt-d. But so far I have not noticed anyone doing this, perhaps because actually returning and handling errors properly is not as much of an issue as most people make it to be.

I personally like Go's error handling so I wouldn't consider doing it, but what exactly would be the issue with doing so? The reasons not to that I have seen are all basically boil down to "Because you're not supposed to, it's not what it's for" . Because of how recover works it certainly wouldn't make sense to use it exactly the same as try/catch is generally used, but what exactly would be the problem with using pa…

Because one of the nice things about Go is that I don't have to worry about this.

Is not just unidiomatic code in itself, but it creates unidiomatic APIs that behave in ways Go programmers don't usually have to worry about.

Unlike Python programmers, who should always be worrying about what exceptions any function or method they call could throw, hell, even setting a property or adding an item to a map or list can throw all kinds of exceptions. And this is rarely documented, and when it is documented it is usually incomplete, because whoever wrote that code doesn't know what exceptions might be thrown by any other code he calls.

Re: Why I’m not leaving Python for Go

#98

Heh, I thought the answer was "Because my blog is named uberpython and it would be way confusing." :-) But error handling is one of those topics that really gets people going. From ABEND in the old IBM batch days, to uncatchable signals like SEGV in unix and uncaught exceptions in C++ or Java. I tend to come down on the "decide what you are going to do in the code, right where the error occurs" flavor of the argument…

The problem I found is #1 is hard. In C# if I want to just exit/return an HTTP error I ignore the exception and it happens. In Go for the majority of cases I have to check the error and call a panic function. I wrote a helper function to do this - it takes one parameter and panics if not nil. 2 and 3 I've found to be at little less verbose as there's no try {...} catch{...} around it. It seems a nice way of avoiding…

Have you seen the Error function in the HTTP package? http://golang.org/pkg/net/http/#Error

Re: Why I’m not leaving Python for Go

#99

If you use a language that uses error codes, then you're forced to explicitly think about what to do in every single error case (or not, and accept the consequences). This can add a lot of mental overhead, but can result in a much more robust and well-thought-out program. But because more logic is involved period (to handle the robustness), the program is necessarily more complex. If you use exception handling, then…

I certainly agree that if you are thinking carefully about the code, either way should work just fine. As someone who likes C and Python I understand that both ways can make robust software, and it took me a little time to accept exceptions at all. More broadly, most of the languages that are widely used can write decent software.

I think this is a matter of what you prefer the program to do by default, when something clearly wrong has happened, but no error-handling code has been written: you may prefer such code to halt, or you may prefer it to keep on trucking.

If you use exceptions, you have to think about it IF you want the program to keep on trucking. Otherwise you can just let exceptional circumstances take care of themselves - if the program stops immediately, it cannot then behave incorrectly.

As a default failure mode, I do prefer the program to halt and decline to further cock up the situation (forcing me and my tests to deal with the condition) than for the program to silently swallow the error and continue as a default (forcing me to thoroughly check error codes everywhere up front out of pure fear that I will miss a condition).

This is just a convention and either one works.

If Go can become a better version of C then I might switch out C for Go. This isn't by any means going to cause me to give up Python because I use C for very specific reasons (when it is totally OK for reasons of speed or control to write a decent amount more code, and have it read more cryptically, and have to take care of many more low-level details).

Re: Why I’m not leaving Python for Go

#100
post #97
post #93

Earlier quoted context omitted.

I personally like Go's error handling so I wouldn't consider doing it, but what exactly would be the issue with doing so? The reasons not to that I have seen are all basically boil down to "Because you're not supposed to, it's not what it's for" . Because of how recover works it certainly wouldn't make sense to use it exactly the same as try/catch is generally used, but what exactly would be the problem with using pa…

Because one of the nice things about Go is that I don't have to worry about this. Is not just unidiomatic code in itself, but it creates unidiomatic APIs that behave in ways Go programmers don't usually have to worry about. Unlike Python programmers, who should always be worrying about what exceptions any function or method they call could throw, hell, even setting a property or adding an item to a map or list can th…

Well right, I get all of that.

Just to be clear though, there is no point "adding" exceptions to Go because the functionality is already there, just named something else and meant to be used in a completely different way?

Post reply on HN