Live data from Hacker News

When in Go, do as Gophers do

talks.golang.org

21–30 of 93 posts

Re: When in Go, do as Gophers do

#21
post #3

Earlier quoted context omitted.

this is especially true for everything related to error handling. I've never had to deal with a java codebase where exception were causing problems, but golang made me feel worrying about it from day 1. I really think they made the language a little bit too small.

If you have only worked in languages with exceptions, it's not surprising that you would struggle with Go's C-style error handling. I've grown to prefer it, as exception handling typically boils down to "not my problem" in most code bases. Go forces you to think through each error condition, which is an unusual amount of effort for people who may not be accustomed to it.

Go's error handling works well in small programs but there's a couple of issues.

One is that it quickly becomes hard to find out where errors really came from. Consider this idiomatic code:

    func MyFunc(input int) (output int, err error) {
      if output, err = someOtherFuncA(input); err != nil {
        return
      }
      if output, err = someOtherFuncB(output); err != nil {
        return
      }
      // ...
    }
If MyFunc returns an error it's not possible to know where it came from unless you know all about someOtherFuncA and someOtherFuncB and they return different kind of errors. What's missing from the stdlib is a utility that wraps errors to reproduce what's essentially a backtrace. `return wrapError("someOtherFuncA", err)`

The other issue is that (error) doesn't tell you what kind of errors are going to be returned. It's often useful to be able to classify errors as to respond to them accordingly. IO errors might be retryable but data-structure errors might be not. In the stdlib they use value comparison as a trick to classify errors combined with documentation of what exactly will be returned.

Re: When in Go, do as Gophers do

#22
post #3

Earlier quoted context omitted.

this is especially true for everything related to error handling. I've never had to deal with a java codebase where exception were causing problems, but golang made me feel worrying about it from day 1. I really think they made the language a little bit too small.

If you have only worked in languages with exceptions, it's not surprising that you would struggle with Go's C-style error handling. I've grown to prefer it, as exception handling typically boils down to "not my problem" in most code bases. Go forces you to think through each error condition, which is an unusual amount of effort for people who may not be accustomed to it.

That's a question i've often asked myself, whether having me think about error handling at almost every line of code was actually a good thing, or just plain overkill since most of time killing the top-most function ( and maybe retry it) is the only thing to do.

I don't really have an answer to that. But what i know is that i find the practice of having typed exception in java plus catching the one you want to deal with per block of code much more readable than the serie of if / else that go forces you to do.

Ps : i do write in many different languages, including C and python. But with C you know that you're writing in an prehistoric language so nothing cumbersome really surprises you, and python also has try / catch logic.

Re: When in Go, do as Gophers do

#23
post #7

Sad that this is still the way to test for interface implementations. http://talks.golang.org/2014/readability.slide#17

It is a perfectly reasonable way to test for interfaces. A single struct may satisfy a hundred interfaces which it doesn't even know about, this is actually one of the best traits of go.

Re: When in Go, do as Gophers do

#24
post #21

Earlier quoted context omitted.

If you have only worked in languages with exceptions, it's not surprising that you would struggle with Go's C-style error handling. I've grown to prefer it, as exception handling typically boils down to "not my problem" in most code bases. Go forces you to think through each error condition, which is an unusual amount of effort for people who may not be accustomed to it.

Go's error handling works well in small programs but there's a couple of issues. One is that it quickly becomes hard to find out where errors really came from. Consider this idiomatic code: func MyFunc(input int) (output int, err error) { if output, err = someOtherFuncA(input); err != nil { return } if output, err = someOtherFuncB(output); err != nil { return } // ... } If MyFunc returns an error it's not possible to…

Think the point i to handle errors wherever they're best handled. Sometimes that means returning it and sometimes it means handling it right away.

I've written code with this style of error-handling in Perl 5, and I think it works quite well. I like having "custom" error-handling that fits the style and the purpose of that particular program, instead of trying to to fit a general pattern onto all programs. It also means you can start out with something very crude, and improve it as you go along and learn more about the failure modes etc.

Re: When in Go, do as Gophers do

#25
post #22

Earlier quoted context omitted.

If you have only worked in languages with exceptions, it's not surprising that you would struggle with Go's C-style error handling. I've grown to prefer it, as exception handling typically boils down to "not my problem" in most code bases. Go forces you to think through each error condition, which is an unusual amount of effort for people who may not be accustomed to it.

That's a question i've often asked myself, whether having me think about error handling at almost every line of code was actually a good thing, or just plain overkill since most of time killing the top-most function ( and maybe retry it) is the only thing to do. I don't really have an answer to that. But what i know is that i find the practice of having typed exception in java plus catching the one you want to deal w…

I agree with that as well. I was just now writing a program to receive a command and perform an action, and sometimes it will receive invalid commands, or there will be some error performing the action. In these cases, I just want it to ignore the errors and resume its loop.

With Python, you just wrap it in a try/catch and forget about it. With Go, I already wrote five error checks and I'm sure I haven't caught some condition that will make it crash. I have to say I prefer the exception style, at least in this case.

Re: When in Go, do as Gophers do

#26
post #7

Sad that this is still the way to test for interface implementations. http://talks.golang.org/2014/readability.slide#17

It is a perfectly reasonable way to test for interfaces. A single struct may satisfy a hundred interfaces which it doesn't even know about, this is actually one of the best traits of go.

I looked at this slide for a while and couldn't understand it. Could you explain the detail a bit ? It seems like relying on dynamic type casting over a nil variable, is that correct ?

But then what would the following "if" look like ?

Re: When in Go, do as Gophers do

#27
post #2

I've never known a language with so much discussion on why what you are doing isn't idiomatic as Go. I'm enjoying using Go for the few small services I'm using it for but it seems that a language which has to constantly fight it's users to reinforce what it considers idiomatic has some core issues.

You must, truly, channel the minds from planet 9 to enjoy the experience of Go. (This statement is not considered 'polite' in certain circles, but darn it, I can't help myself ;)

That said, I've tried channeling Rob and it is an interesting and informative experience ..

Re: When in Go, do as Gophers do

#28

As I go from normal Go style to idiomatic Go style, I find more error checks. That is annoying when your code grows. http://talks.golang.org/2014/readability.slide#11 In this example, have to check error 3 times to write 4 lines of code.

In Java, I'd have to write 3 catch blocks. It's possible to write a blanket catch, toss it up to higher levels and make it someone else's problem. I vaguely recall this being against Pike's vision of what "exceptional" means and he wanted a language that forces developers to think of disk/network failure as a very common case.

Re: When in Go, do as Gophers do

#29
post #26

Earlier quoted context omitted.

It is a perfectly reasonable way to test for interfaces. A single struct may satisfy a hundred interfaces which it doesn't even know about, this is actually one of the best traits of go.

I looked at this slide for a while and couldn't understand it. Could you explain the detail a bit ? It seems like relying on dynamic type casting over a nil variable, is that correct ? But then what would the following "if" look like ?

This is how you can make sure that a struct implements an interface. The line 'var _ scan.Writer = (*ColumnWriter)(nil)' assigns a nil pointer of the struct to a scan.Writer interface reference which would fail if ColumnWriter doesn't implement the interface. And the casting always works.

Re: When in Go, do as Gophers do

#30
I've only been using Go for less than a week and my impressions are less than good. I'm still waiting and hoping to understand what it is that people like about Go, but I'm starting to suspect that won't happen.

The biggest problem I have had most so far is when reading other code, finding the meaning amongst all of the error nil checks and the sprawling if conditions that they bring.

Another thing that makes it difficult is the preference for scattering returns everywhere and avoiding `else if`s, I read code structurally so code like this from slide 29 (http://talks.golang.org/2014/readability.slide#29) is really difficult to parse.

    func finishStatus(r Result, complete bool) int {
        if !complete {
            return http.StatusAccepted
        }
        if stat, ok := r.Object.(*api.Status); ok && stat.Code != 0 {
            return stat.Code
        }
        if r.Created {
            return http.StatusCreated
        }
        return http.StatusOK
    }
Post reply on HN