Live data from Hacker News

Why I’m not leaving Python for Go

uberpython.wordpress.com

31–40 of 245 posts

Re: Why I’m not leaving Python for Go

#31
post #18

Earlier quoted context omitted.

That's not the same as handling an error in a central spot automatically.

Handling errors in one spot doesn't work for all situations, though, right? Especially in an OO environment an object may need context for retrying a request, or some other kind of error decision making. So in practice some exceptions percolate through the object graph, while others are handled in-house, so to speak.

It works for most situations. If you need retry logic - exceptions is the wrong way to go. Errors returned by the standard library are most likely not errors you want to retry by default.

Re: Why I’m not leaving Python for Go

#32
post #17

Earlier quoted context omitted.

I cant follow. Throw/Catch is as powerful as a error return value but it does not let you ignore errors without writing any code.

Unless they're unchecked exceptions, of course. In Python, all exceptions are unchecked. The proliferation of checked exceptions all throughout the code is a whole other ball of wax.

Checked exception need to be handled properly. It depends on the sanity of the API. However, the standard way how to handle checked exception is a lot easier to maintain than error return values.

Re: Why I’m not leaving Python for Go

#33
post #15

Psh, obviously trigger_doomsday_device will only respond to an http POST. Once again the president has been saved, thanks to HTTP Pedantry.

> HTTP Pedantry

I propose a new HTTP verb, MEH, to address the belief that the HTTP verb mechanism is unnecessary or over specified. The semantics of HTTP MEH are application-defined, so it can be used to fetch, update, replace, query, delete, or whatever the application defines to be necessary. Services honoring HTTP MEH implicitly signal that interoperability is not supported, but that intermediate proxies 'should do the right thing' regardless.

Re: Why I’m not leaving Python for Go

#34
post #10

I suppose it's all a matter of taste. The error handling design decision is one thing I really like about Go. I write high reliability embedded software and "throw/catch" just doesn't cut it for me since it obscures possible error conditions thrown from subroutines. I want to have to explicitly deal with those errors whenever they might occur and error returns are a good way of doing that. For every language feature…

But throw/catch gives you the option to do it that way if you want. An if/else per statement is no different from a try/catch per statement.

The point of the post is that Go doesn't give you the option, whereas Python let's you decide when and how you'll deal with it.

Re: Why I’m not leaving Python for Go

#35

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 the stack sentinels or setjmp/longjmp that C++ has, which means the output is less architecture dependent.

Personally I don't think Go is quite ready for prime time, but it's definitely promising. I'm doing a couple of projects with it to see how it runs.

Re: Why I’m not leaving Python for Go

#36

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…

You are right that #2 is well served by exceptions when done right. It's also well served by checking locally and returning your own error status. Both ways can be done well. IME exceptions tend to pass the buck to the caller when they shouldn't, in the hands of mediocre programmers.

Re: Why I’m not leaving Python for Go

#37

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…

Just some more oil for the fire. Having worked primarily in Python for over 10 years (and generally been a huge enthusiast during that time), I'm pretty comfortable at this stage with the notion that exception handling languages contribute significantly in only one respect - they allow newbies to write code without ever properly understanding how errors should be managed without violating layering, where retries should be inserted, and so on.

The culture of writing code, and that code being fine once a unit test is passing seems to propagate the myth that it's fine for any code to throw any exception at any time – it doesn't matter as long as those errors expected to occur from testing are the only conditions that ever occur. As for the rest, well. Kaboom!

Starting off from C, it doesn't take you more than your first 100 lines before you discover pain due to missing a return value. In my experience, eventually 60% of your time is spent wondering how this particular return value propagates throughout the rest of the code you've written, and libraries in use.

The end result is my C code tends to be much more robust in the face of braindamage (say, network errors, IO errors) than my Python, simply as a result of a cultural mindset that basically encourages ignorance of error conditions.

You can also trace one of the biggest pains from Python 2 back to this culture: deferred error handling is at the very core of the Unicode/strings mess, probably the single most motivating factor for moving to Python 3.

[Extremely tired, aware this is poorly written and sways between points, but hope it makes some sense]

Re: Why I’m not leaving Python for Go

#38
post #28
post #7

It's not "tempting to ignore errors". You're the programmer, if you want to ignore it, do so. I don't know why you'd want to ignore the returned value and possible error on a GET request - given that 1) it can fail for so many reasons, and 2) the suggestion that you might be "GETTING" something. Ignoring the error of a print statement is more acceptable since it's unlikely to occur and there's rarely a lot you can do…

That's his whole point. He doesn't want to ignore errors but feels like Go is so verbose about it that it's a pain for programmers to deal with it. Example in case, print . Would you check its return value every time you call it? No. Contrast that to other languages, such as python, where you don't ignore the errors because you know that if something goes wrong, an exception will be raised. It lets you do stuff like:…

It's actually worse than that. The blog has error handling code like:

    if err := datastore.Get(c, key, record); err != nil {
        return &appError{err, "Record not found", 404}
    }
This is pretty typical Google Go error handling, where errors are only actually used as boolean flags. Errors are universally returned as type 'error' so to actually do anything with the error you have to first cast it to some specific type. But that type isn't part of the method signature so you have to dig around in the source or, if you are very lucky, it was documented someplace. You end up having actual error handling plus even more error handling for if you got the error type wrong.

For instance if datastore could return 'record not found' or 'io error' then they would usually be treated the same way by the code because to do otherwise would be even that more of a hassle.

Re: Why I’m not leaving Python for Go

#40
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 suddenly catching errors becomes much easier, and writing code is faster, but it's not like your program is any more robust. If you catch an error up at the top, your program or function is probably just going to quit. 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.

In the end, I just don't see much of a practical difference. In both cases, if you want to be a lazy or rapid programmer, errors will lead to your software just not working. And if you want to be conscientious about your errors, then you can do that in both cases.

Exception handling lets you handle errors "at a distance". It's convenient, but harder to keep track of. Returning errors keeps your code execution where you can see it, and you always know where it is. It's simpler, but more verbose.

Post reply on HN