4 ms·
I'm about 8 months in to using Go for a few largish projects and I'd say these are probably the two biggest things I still struggle a bit with. (not generics as
by nicpottier 9y ago
I'm about 8 months in to using Go for a few largish projects and I'd say these are probably the two biggest things I still struggle a bit with. (not generics as others seem to obsess about)
On errors, I'm really of two minds. In a way, it is a lot like how Java started with checked exceptions, it forced you to deal with the error. But at some point most people decided that was annoying and switched to runtime exceptions for everything, which while requiring a lot less code, still led to errors often bubbling up all the way to the user.
I think checked is the right thing, but it does require developers to be thoughtful and not just throw errors upwards. If you accept that checked is the route you want to go, I don't find Go's use of error values worse than exceptions.
On the package management front, I think the current best practice for projects that must not break is to vendor your dependencies. Go is working towards having better tools to allow you to specify SHA's for your dependencies easily but we aren't fully there yet.
While it took a bit to wrap my head around using `govend` to vendor my dependencies, in the end it really hasn't ended up being a big pain point in practice. I also never have to worry about a dependency either disappearing or pulling a trick of shipping the same version # with different code. (or having the repo/package manager be down, which anybody who has shipped a lot of code will tell you has happened)
So yes, I agree these are both, weird, but they aren't deal breakers. For our particular application, I really love Go, more so than I have any other language in recent memory.
- eweise 9y agoChecked exceptions suck. Every method has to explicitly throw them up to a higher level where they can be handled causing tons of useless boilerplate. Its much better to just let unchecked exception bubble to a higher level of the app. This is a best practice in java so letting the exception bubble all the way back to the user is just poor programming.
- erikb 9y agoI have to google what the "checked" actually means. But in Java you can throw parent classes, in Python you don't need to declare them at all. And honestly having a bad implementation is still better than no implementation. The main point here is to get correct, helpful error reporting so people understand what's going on. If I spend another 4 hours debugging an error message that was actually just a warning and not a biggy at all I'm going to throw up.
- alphaalpha101 9y agoThat's exactly what you have to do in Rust anyway though. Except instead of just writing `throws SomeError` in the declaration line of the function, you have to annotate virtually every line of your function with `?` and wrap the return line in `Ok(...)`.
- steveklabnik 9y agoThe ? RFC did include a "catch" construct, and there's been some discussion about doing something more like "throws SomeError." We'll see!
- alphaalpha101 9y agoIt's far too late for "we'll see".
- curun1r 9y ago> not generics as others seem to obsess about One reason people obsess about generics is specifically because of error handling. With generics, you could implement Result and Option types, which make error handling significantly more sane.
- leshow 9y agoYou'd need generics and algebraic types to implement Result/Option
- curun1r 9y agoFalse. That feature allows a more efficient implementation, but (T, error) (or an equivalent struct) can be reasoned about in much the same way as Result<T>. You don't need a tagged union when you can use the nil-ness of one of the two values in the tuple as the tag. Similarly, Option<T> is just a wrapper around a nullable T.
- KirinDave 9y agoThat would let people do this, and I hear people ask for it a lot. I dunno if it'd actually be better without the possiblity of not-wow-slow combinators. Golang has all these weird performance pitfalls that you only hit if you contort the language too hard. Naming combinatior functions sometimes trips those conditions. I'm of the opinion that even just pattern matching and the kind of nil type propagation checking that TypeScript does could help enourmously. Generics won't fix error handling without compiler help, and the best way to get that help is to introduce pattern matching as a forcing function.
- leshow 9y agoThe type you propose can inhabit both different variants at once, the entire point of Option is that it is either something or not.
- alphaalpha101 9y agoPersonally I loathe this style of programming. It's not that it's difficult, it just seems to obscure code a great deal. Writing this sort of thing in Rust: fun some_function(a: &A) -> Result<&B, SomeError> { let c = foo(a)?; let d = foobar(a, c)?; Ok(if xfoo(c) { let e = blah()?; bar(d, e)? } else { baz(d)? }) } where you have to write every function in this pseudo-do-notation where 'return' is just wrapping the return expression in 'Ok' and `a <- expr` becomes `let a = expr?;` is just horrible. I'd much rather write this: fun some_function(a: &A) -> &B throws SomeError { let c = foo(a); let d = foobar(a, c); if xfoo(c) { let e = blah(); bar(d, e) } else { baz(d) } } See how that's so much cleaner? It's not actually any different from exceptions anyway, you're basically using them like exceptions, and they're implemented in the same way. The difference is that in the latter the code is much simpler and easier to understand. That's all. In fact, that syntax could be added to Rust (after 6-12 months of bikeshedding as usual) and just have it automatically translated to the above anyway. The other issue with Result/Option is that people start doing really horrible things like adding Option::map. Sorry but it's not a container that has 0 or 1 things in it. It's an optional value. That they're mathematically equivalent doesn't mean that they're the same thing conceptually. It's as bad as pretending that Result<T, Err> is useless and everyone only needs Either<L, R> where by convention R is the error value. God please just no.