Live data from Hacker News

Why I’m not leaving Python for Go

uberpython.wordpress.com

51–60 of 245 posts

Re: Why I’m not leaving Python for Go

#51
I see both pros and cons in the Go approach.

I find Python's exceptions model to be something that does occasionally frustrate me. For example, I'm used to using NSIS for some things (the PortableApps.com Launcher being one thing); its model is that a command may set the global error flag. This means that some sorts of things will fail silently - occasionally bad, but generally good. Some styles of Python scripts (generally automation scripts rather than full-blown programs) would do much better ignoring most errors. When you have a script merrily chugging along and all of a sudden due to some obscure corner case (perhaps not even documented) in a small, incidental part of the script the whole thing quits, it can be rather annoying.

The Go approach lets you catch errors if you want, or drop them, much more easily than Python approach. My inclination at present is that the Go approach is more likely to end up with error-resilient code, as it encourages dealing with errors each time, while Python typically encourages you to let the caller deal with an exception if you can't - but often I think the caller doesn't realise that he should. Or after a couple of levels of indirection, it's not even documented that that exception can occur. (This sort of thing, I believe, is something that Java's checked exceptions were supposed to help with - either deal with the exception or declare it.)

For myself, I've had lots of experience with Python and am now dabbling with Go, using it for two smaller projects to decide which to use for my next major project. At the very least, I think the approach is worthwhile trying in a serious project that its merits and those of the Python approach may be more completely analysed.

Re: Why I’m not leaving Python for Go

#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, the example lacks error handling. Its almost like people avoid doing error checking in C code because of the cumbersome amount needed to be done in order to check each and every time. If an example code would include error checking, the number of lines can easy increase 3-4 times the original size.

Re: Why I’m not leaving Python for Go

#54
post #28

Earlier quoted context omitted.

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 t…

> 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 [...]

This is quite correct and what's really broken with Go's approach to error handling and documentation.

Re: Why I’m not leaving Python for Go

#56
post #50

Earlier quoted context omitted.

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 t…

I guess you are super lucky: https://developers.google.com/appengine/docs/go/datastore/re... or even https://developers.google.com/appengine/docs/go/datastore/re... err := datastore.Get(c, key, record) if err == ErrNoSuchEntity { // entity not found return } else if err != nil { // some other error return } Don't really see the hassle you are referring to.

I think this is exactly the point. You have to read the comment to get the error types (isn't compiler accessible), it doesn't list what all the possible error types are (doesn't say the ones documented are exhaustive), and the code returns a singleton error (no state) presumably so the caller doesn't have to do a bunch of casts..

Re: Why I’m not leaving Python for Go

#57

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…

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…

What am I missing here? This appears to be fully in-band and contains a redundant code path (constituting a NaN bug in languages with incomparable NaN—no idea if that applies to Go) for no apparent reason.

Re: Why I’m not leaving Python for Go

#58
post #32

Earlier quoted context omitted.

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.

Easier to maintain how? I don't think I see it. Return values, at least as a mechanism, are strictly simpler; they do not introduce new control flow. They just use "return." Control always reverts to the caller.

For an exception, you don't know whether it's the caller, the caller's caller, some generic exception handler, or what. It's no fun trying to track down all of the callers of A, some subset of which might not catch exception X, then track down the subset of those callers which catch X.

Otherwise adding or removing error codes seems equivalent to adding or removing exceptions. Same with trying to decide which exceptions/errors to handle or bubble up.

Re: Why I’m not leaving Python for Go

#59
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,…

To be fair, most sample code I've seen, regardless of language, usually does not include error handling. Why not? Probably because it would detract from the main point being illustrated.

Re: Why I’m not leaving Python for Go

#60
post #31

Earlier quoted context omitted.

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.

That depends, though, doesn't it? Just about anything network-related is subject to flakiness, disconnection, and timeouts. That means HTTP, database connections, sockets, etc.
Post reply on HN