The lack of exceptions just seems like a total bear to me. I wrote C for 10 years and did tons of stuff like:

    Open file "foobar.dat". If that fails, abort with this error.
    Read the first 4 bytes into x.
      If that fails, abort with a different error.
    Seek to byte x. If that fails, abort with yet another error.
and so on, and so on, over and over again. Python's exceptions are a huge improvement over this pattern of timidly asking permission to do anything. The fact is there are so, so many occasions where you want to abort a computation if one of the many steps along the way goes wrong. Something like Haskell's Maybe monad is a good way of attacking the problem too.

But Go has neither. It seems to just offer the bad old clumsy C way and say, "Deal with it." To those who have written real Go programs, I'm honestly wondering: how is this not a pain in the ass?

Unlike C, Go isn't overloading what is returned, it has an extra param, and the language has been baked to handle doing like initialization and checks in single line if statements. It does force the developer who might actually have a clue what the exception is and how to fix it to handle it, but IMHO this is a good thing. Go forces lots of things like this (not using an import, won't compile; not using a variable, won't compile).

Honestly, compared to the exception hellscapes I have had to deal with in Java and C++ --- it seems like the path of least surprise. Which incidentally has been my favorite things about Go, the low number of surprises.

A lot of using Go in real work has gone against my expectations. There are a lot of things I initially saw as huge warts (lack of exceptions, generics and import versions), but I liked channels enough (Erlang background) to give it a shot. So far, I have been delighted by using it as a stack (build cycle, deploy method, terse C'ish syntax).

The problem with this "forcing" that go does is that it ALSO includes _, which means it's inevitable that lazy developers will get tired of handling error and just shunt it into _.

You can't stop people from being lazy. Look at all the Java and Python code that forcefully ignores exceptions.

It is something that can be caught with static analysis, however. Someone recently put together an appropriate tool[1] for Go, in fact. It seems to work very well.

[1]https://github.com/kisielk/errcheck