3 ms·
> You don't have compile time checks for errors. Doesn't the fact that errors are values, combined with the fact that you cannot ignore values (except explicit
by bheadmaster 4y ago
> You don't have compile time checks for errors.
Doesn't the fact that errors are values, combined with the fact that you cannot ignore values (except explicitly by assigning them to "_"), provide compile time check for errors?
- teraflop 4y agoNot really. It's idiomatic to use a single "err" variable for every error value in the same function body, and the compiler will only check whether that variable is used at least once; it doesn't perform a data flow analysis to ensure that every value that might be assigned is used. So if you assign 10 different error results to the same variable at various points, but only actually check it 9 times and forget the 10th, the compiler will not tell you that anything's wrong.
- bheadmaster 4y agoYou are right. I forgot about that case. Perhaps variable re-declarations (via := operator) would be a good addition to Go. Compiler could optimize the code to re-use the variables when possible, but the semantics of the language would force the programmer to handle each and every error.
- stouset 4y agoNot really. Go thinks this is fine (on mobile, forgive me if I get this wrong). foo, err := foo() if err != nil { return nil, err } bar, err := bar(foo) return bar, nil The problem occurs because go only cares if a variable is used once per definition. Not once per assignment.
- bheadmaster 4y agoYou are right, I have missed that, as I have written under the sibling comment. Though I'd like to ask - does that scenario really happen in practice? It is idiomatic to handle every error right after the function call that returns the error. To me, the lack of "if err != nil {" under the "bar(foo)" call really stings my eyes. I know, compile time checking is different from "it doesn't happen in practice". It's a tradeoff. I'm just wondering about the magnitude of the impact.
- stouset 4y agoYou're looking at a minimal test case, not an example of it happening in real production code. Of course it's obvious in the minimal test case, that's the point. I've personally written something akin to the following, which triggered no errors (at the time, maybe this is fixed): foo, err := foo() if err != nil { nil, err } return foo, nil The worst part is because all of the error-handling is copypasta boilerplate, your eyes don't look at it. So subtle bugs get through and make it to production. I've seen this one too: foo, err := foo() if err != nil { return foo, nil } return foo, nil Also note that now we've gone from "Doesn't [go] provide compile time check for errors?" to "Well I guess it doesn't check that errors are used, but that would never happen to me."
- bheadmaster 4y ago> Also note that now we've gone from "Doesn't [go] provide compile time check for errors?" to "Well I guess it doesn't check that errors are used, but that would never happen to me." True, but there was also a "you are right" in between :)
- seer-zig 4y ago> does that scenario really happen in practice It does happen, I've seen it several times, and even other insidious examples that linters did not catch. When you're dealing with a code base that is constantly changes, things like that end up happening.