
Why I'm not leaving Python for Go (2012) - jshen
https://uberpython.wordpress.com/2012/09/23/why-im-not-leaving-python-for-go/
======
atrudeau
This is my biggest gripe with Go as well.

Though initially the diligent programmer will check each and every call with
if err != nil {}, there comes a time when laziness kicks in. When that time
comes, you'll get hit with unexpected behavior (aka: tracking down nil
references).

You might argue the same would happen with exceptions. Yes, they will blow up
in your face as well if you fail to catch them. But when they do, you'll
hopefully have a well specified restriction that enables to you pinpoint the
issue almost immediately.

Basically, with exceptions you know the guy who shot you in the gut because
you were being lazy, whereas with Go's error system he's hiding behind the
bushes with a dozen or so of his conspirators.

~~~
Matthias247
You can argument around that in both directions: Yes, exceptions will blow
your program up and you will see it later on and can debug the exception - no
silent errors.

But on the other hand what you really want is correct error handling from the
beginning (and no blowing up in release builds or SW delivered to customers).
Here error return values have the advantage in my opinion that you directly
see development that a function can error and that you need to handle that
error. While you can't see that a function might throw.

What Go is probably missing is forcing you to look at the returned error
values while you can currently accidentally miss them by only assigning the
first return value of a function.

~~~
atrudeau
Yes, that would be nice, but as lazy programmers we skip some error checks for
a reason: sometimes the error is highly unlikely. As such, it might not be
worth the cost of writing a bunch of error checking code which costs
keystrokes and litters the code with ifs.

If an uncaught exeception does happen, it moves from unlikely to likely, and
so gets plugged up in the code. Rinse and repeat. Again, the obvious advantage
being errors that are easy to track.

In go this approach would result in a possibly nightmarish debugging session.

~~~
Matthias247
Lazy programmers that skip error checks or count keystrokes as a something
major are probably at the wrong job.

Either an error can happen then it must be handled - no matter how likely it
is. Or it can't happen, then there's no need to handle it. The rare exceptions
are functions where errors are indicated in the type signature but in reality
won't occur, e.g. because the error return value will only be used in other
implementations of an interface or because a precondition that guarantees that
there will be no error was checked before. And for this cases you could still
do something like: _ = functionThatReturnsError()

This is the approach that you e.g. have to follow in F#.

------
kazinator
Apples and oranges. Python is a dynamic language, whereas Go is a systems
programming language that tries to offer an alternative to C.

You {would/would not} switch to Go from Python for about the same reasons why
you {would/would not} switch to C, Ada, Modula 2, and so on.

A more useful blog would be, "Why I'm not leaving C (or C++, Rust, ...) for
Go".

If I were using Go (which I almost certainly won't be, ever), I think would
try to use its panic/recover mechanism as much as possible to avoid the
tedious multi-level error handling.

~~~
nicerobot
> I think would try to use its panic/recover mechanism as much as possible

And that's exactly the reason you should avoid Go. Every error is not
exceptional. Most errors are not exception. Hence, most errors should not
panic.

> to avoid the tedious multi-level error handling.

It only looks tedious to the uninitiated based on code snippets you've
probably seen. Or if you're stuck in an imperative paradigm, i can imagine Go
will feel tedious. But since Go has first class functions, it's quite easy to
write high-order functions that work better than try/catch and make error
handling flow quite nicely. It also provides better error handling than
cumbersome, coarse-grained, and verbose try-catch clauses where the catch
clause is not directly related to the call that produced the exception (which
probably isn't really an exceptional case but rather just a simple error.)

[https://gist.github.com/nicerobot/263869942dd5344d9cd6943af5...](https://gist.github.com/nicerobot/263869942dd5344d9cd6943af5b5ddf2)

Yea, Python can do the same but because Exceptions exist, everyone considers
simple errors to be exceptional. Go allows errors to just be errors and error
handling becomes related directly to the call that caused the error.

~~~
kazinator
Users of languages that have excellent support for first-class functions _and_
exception handling will probably not agree with you, sorry.

Lower-level code often doesn't "know" how to handle a situation when it is not
able to complete its job. The executive decision about how to proceed is
somewhere higher up.

Returning an error code that has to be propagated through several levels to
the appropriate place is blub programming that belongs to the 1960's.

Higher order functions are useful for error handling, but only when coupled
with a dynamic control transfer. The low-level routine invokes a callback,
which is some closure belonging to a higher level. For this architecture to be
useful to its full potential, that closure must be able to make a jump (for
example, a jump to the surrounding code in the function where that closure was
created, to effectively abort all the frames between that function and the low
level where the error occurred).

~~~
nicerobot
I was _only_ pointing out, through _one_ _simple_ example, the flaw in your
conclusion of Go errors being tedious. I was not discussing other languages
nor how to incorporate extensive and fluid error handling in Go to be as
capable as any in other language. And since you've raised several points that
weren't pertinent, it seems you simply want to disagree with me, so i'll end
my side of this discussion. Have fun.

~~~
kazinator
What is the magic pixie dust in Go which makes returned error values not
tedious?

(Besides, of course, what I mentioned in the original posting: panic and
recover.)

------
Mithaldu
I know i'm being a smartass, but:

"Why I'm not leaving Apples for Bananas (uberapplepie.wordpress.com)"

------
akubera
I'm not very familiar with Go, so please correct me if I'm wrong, but this
looks like this pattern was chosen due to the async-focused nature of the
language; similar to many callback-laden javascript error handling strategies.
Is this true?

Also, I see that the error must implement the 'error' interface, and this
interface specifies a single "Error" method. Is the typical error-checking
practice to do type assertions on the err object, ensuring you know what went
really went wrong?

I agree with the article that python's handling is better, if not for the fact
that ignored errors within 3rd party libraries _could_ go unnoticed and be
hard to debug. Python3's try/except blocks even work in asynchronous
coroutines.

Also, this article was written in 2012; this should be mentioned. (previous
discussion:
[https://news.ycombinator.com/item?id=4562211](https://news.ycombinator.com/item?id=4562211))

~~~
ElKrist
I can't tell you why this pattern of error handling was chosen but this is
different from the callback pattern in nodejs. In Go, errors are typically
returned directly by the called function. Even if such function makes
"asynchronous" calls (there is a great article shared on HN that explained why
this term is not the best)

------
dpc_pw
Part of the reason I avoid Python software like a plague.

The flaw of Go is not reporting unhandled errors at compile time (solved by
3rd party checkers), and no convenient mechanism to escalate errors upwards.
Both somewhat fixed in Rust by compiler and `try!`. But I don't see how Python
is making it any better. It actually makes it much worse.

Errors are not exceptional. They need to be handled with care. Exceptions make
people throw them on every error condition, and then __maybe __sometimes, wrap
the whole sections of code into try...catch blocks and not do anything useful
about it.

Overall (IMO, from my experience) open source Go projects are light-years
ahead of Python projects in terms of stability, usability and reliability.

------
luckydude
How is this showing python better than go?

~~~
d23
And how does this add anything to the discussion that hasn't been said 9000
times?

~~~
strunz
This article is also from 2012

~~~
kinkdr
And is the 3rd time submitted to HN by the same user.

------
sargas
"Beginner programmers have a favorite language. Seasoned programmers have a
language they hate the least." \- Unknown Author

\---

It is about the right tool for the job guys. All languages have something to
hate on. Of course it is important to work with technology you like. Nothing
wrong with this article, the guy is voicing his opinion. But this isn't a
verdict on Go. People like Go for precisely the way it handles errors.

------
m_mueller
> I’m still waiting for that open source, concurrent, bottom left language to
> come along. Any suggestions are more than welcome.

Could that language be Swift? I haven't been following that too closely, but
from my experience with Obj-C (and GCD), Apple has been doing a relatively
good job with concurrency. Any thoughts on that?

