16 ms·
> Do I particularly like managing errors that way? No, but I do think that it improves the transparency and quality of a lot of Go projects. So long as we can
by KirinDave 7y ago
> Do I particularly like managing errors that way? No, but I do think that it improves the transparency and quality of a lot of Go projects.
So long as we can all agree that it feels super bad, I guess this is fine. But it does sort of mean that Golang approaches the Java world back with checked exceptions where principle trumped ergonomics.
That lead to a world where folks felt "forced" to use Java, and that's a sticky label that's difficult to remove. I think the Golang community is going to find itself growing more slowly as folks increasingly realize other options offer similar benefits without the bad ergonomics.
- wybiral 7y ago> I think the Golang community is going to find itself growing more slowly as folks increasingly realize other options offer similar benefits without the bad ergonomics. Personally I enjoy writing Go code similar to the way that I enjoy writing Python code. So they did something right because I wouldn't ever say the same about Java or PHP. Edit: As a fun tangent... Python experienced the same kind of fracturing that adding generics or other dramatic features to a language can cause with the 2to3 move. There are still projects based on 2.7. It was hard to get people all on the same page once the community was split. What's also interesting is to watch the same thing happen with asyncio, which is practically an all-or-nothing thing to use in your Python project, so much so that most Python code still doesn't use it. Just an observation, but breaking changes to a language can really do a number on the community.
- KirinDave 7y agoI don't think folks are on 2.7 because they love it. I think they're there because it's difficult and expensive to migrate Python code.
- wybiral 7y agoThere were multiple reasons based on my experience. New people were still using 2.7 tutorials because there was way more information out there than for 3. And package managers in Linux systems took a long time to change. But the asyncio example is probably a better example of a fundamental program design change that's causing weird fracturing and incompatible library designs. Trying to use non-async from an async framework is a mess, trying to use async from a non-async is hard to integrate, etc.
- viraptor 7y agoI don't believe that python 2/3 change has much to do with sync/async issues. In python 2 we had twisted which was its own async universe. The sync and async worlds are disconnected in pretty much every language, but it's mostly a non-issue. You just don't mix them and it doesn't become a mess.
- wybiral 7y agoThat's not what I said, they were two times that the community fractured. There is fracturing with asyncio. Look at popular libraries. The "requests" library comes to mind, but there are others. It's hard to use different 3rd party components between the two paradigms which causes fragmentation in the libraries. You end up with aiohttp-requests and stuff. PS: it does make a huge difference. If someone posts "how do I make a web server?" on a forum you'll get two different frameworks and approaches as answers. The community basically goes in two directions and much of the work becomes incompatible. The multithreaded sync vs event loop async just don't play well with each other. There still aren't many 3rd party libraries that really focus on asyncio because much of the community is still in the "threaded" design.
- a1369209993 7y agoI don't know about love, but it's significantly better than python3. I'm on 2.7 because the authors refuse to continue development of python in favor of a different, inferior language. Difficulty and expense of migration have nothing to do with it.
- meruru 7y agopg wrote a bunch of really good essays about Java vs Python vs Lisp and how those were perceived by programmers. I always remember them when I see Go being compared to Java while still being liked by Hackers. I wonder what he would write about this phenomenon.
- parasubvert 7y agopg has a blind spot wrt Java. Lots of hackers liked (and still like) Java ecosystem (see Kotlin for more recent fun). like lisp hackers, they hung out on their own and didn't mingle.
- meddlepal 7y agoThis, but also I suspect a lot of people that claim to dislike Java are tainted by it's framework heavy ecosystem especially early-mid 2000s. The language itself is fairly clean and very pragmatic.
- meruru 7y agoFWIW the essays I mentioned are from the early 2000s. Java's Cover is from 2001: http://www.paulgraham.com/javacover.html http://www.paulgraham.com/javacover.html
- parasubvert 7y agoThat essay has proven to be astonishingly wrong. It’s 18 years later and I suspect he’d say the same things about Golang.
- parasubvert 7y agoPossibly, though Java these days is largely “Spring”.
- meruru 7y agoThose essays were written a long time ago and reflected the situation at the time. I can't really say how accurate they were, but you're using the present tense and mentioning present technology, so I thought it would be worth to emphasize that.
- tempsolution 7y agoYou can't compare it to Java checked exceptions. Java checked exceptions are one of those billion dollar "mistakes". It is the single worst thing in Java for me. Checked exceptions add nothing and break almost everything around clean design & code. For that comparison to work, java would have needed to only have checked exceptions, with some added language features to deal with them cleanly, and then it might actually have been a viable design. Littering your code with try-catch is what makes exceptions infeasible for error handling.
- KirinDave 7y ago> It is the single worst thing in Java for me. Checked exceptions add nothing and break almost everything around clean design & code. Should I compare it to "Golang Dependency Hell Claimed My Project?" > For that comparison to work, java would have needed to only have checked exceptions, with some added language features to deal with them cleanly, and then it might actually have been a viable design. Why? That's not what happened with Golang's error handling?
- ghostpepper 7y ago> Should I compare it to "Golang Dependency Hell Claimed My Project?" As someone just learning Go, what is Golang Dependency Hell?
- KirinDave 7y agoIt's not a problem you have to deal with but those of us from the world before bundled vendoring list projects because of Go's creators not having sympathy with people not living in a single global monorepo universe and most of its audience not having the discipline to vendor stuff by hand.
- jacques_chester 7y agogoogle: it's a community project, we swear also google: we don't have that problem at google, so it's not a problem
- jchw 7y ago>So long as we can all agree that it feels super bad, I guess this is fine. Actually, I don't think everyone agrees it feels super bad. I personally like having all of my error handling be explicit, painfully explicit even. >approaches the Java world back with checked exceptions where principle trumped ergonomics. I also have to disagree here. To me, checked exceptions are the worst of both worlds. Here you have additional language features, but nearly the same verbosity. Your 'happy path' must be surrounded by try blocks. Worse, everything that happens in a try block is 'flattened.' Not only does this mean you may need many try blocks, sometimes it can even be difficult to take individual statements and put them in one try block. For example: try { doThing(doOtherThing()); } catch(...) { // What happens if doThing and doOtherThing throw the same exception? Do I have to use a temporary variable? } Also, exceptions have been overloaded to handle everything, including runtime errors. I think this is more subjective but I strongly dislike it. I do think runtime errors should be possible to handle, just ideally through a separate, more explicit paradigm. try { doThing(blah[0]); } catch(...) { ... } catch(IndexOutOfRange) { // Handling runtime errors at the same level as application-level errors!! } Go doesn't even really force you to check your errors, it just makes it harder to accidentally not check them. Like: result, err := doThing(); // Error return result result, _ := doThing(); // NOT an error return result I think this is excellent. It may lead to complaints about an annoying compiler, but most importantly it leads to fewer mistakes. You can still explicitly tell the compiler to shut up, but it is obvious. Language ergonomics are complicated, but the benefits of Go's approach are hard to deny. Unfortunately, nothing comes without downsides, and it seems like solving the error handling ergonomics issue is a tough one. I think repetitiveness aside, the Go error handling ergonomics are great, and that's exactly why they attempted to reduce repetitiveness. But, in reflection, a lot of that repetitiveness can also be reduced by refactoring your code, so it may not even be quite as bad as it seems.
- pcwalton 7y ago> Worse, everything that happens in a try block is 'flattened.' Not only does this mean you may need many try blocks, sometimes it can even be difficult to take individual statements and put them in one try block. Go has exactly the same issue. But with exceptions at least you can group multiple statements together and handle them with one catch block. With Go you have to use multiple if blocks to get the same semantics. > Go doesn't even really force you to check your errors, it just makes it harder to accidentally not check them. Go doesn't make it harder to accidentally not check errors. If you call a function that only returns an error, such as os.Mkdir(), then the compiler will not warn you when you forget to handle the error. > Language ergonomics are complicated, but the benefits of Go's approach are hard to deny. I don't really see any benefit to Go's approach over exceptions or result types. If making it obvious that errors are handled is important, there's a solution for that that's much more elegant than if-err-nil blocks everywhere. It's precisely the solution that the Go community just rejected.
- baby 7y agoThe bad ergonomics? Golang is an excellent language.
- stcredzero 7y agoSo long as we can all agree that it feels super bad, I guess this is fine Exceptions feel super good, even as you're taking too many shortcuts and glossing over things. Proper handling of the unhappy paths is often going to feel like a slog, because it often is complicated, and it's often a slog. Glossing over error handling in golang can feel bad exactly when it should.
- KirinDave 7y ago> Exceptions feel super good, even as you're taking too many shortcuts and glossing over things. I'm not sure I follow this talk about "short cuts.". Exceptions provide stronger guarantees by default than multiple-value-bind and manual if statements. Your code fails closed as opposed to open. > Proper handling of the unhappy paths is often going to feel like a slog, because it often is complicated, and it's often a slog. I'm used to languages where this generally isn't the case, but sure. Why twist the knife in the wound though? > Glossing over error handling in golang can feel bad exactly when it should. When you capture but fail to check an errval and an untraceable default value starts rattling around inside your code causing unexpected behavior? It's like an NPE but worse because it won't immediately trap. It's more like a double free.
- schrodinger 7y agogo vet catches that scenario and won’t pass CI. You have to explicitly decide to ignore it by using an underscore for the err value and then you get just what you asked for.
- KirinDave 7y agoSure, but it doesn't catch the case where you have multiple error variables in scope and you refer to the wrong one in one place but not the other or if you reuse an error. I've seen that happen more than a few times. Some of it in new production code.
- apta 7y agofmt.Println says otherwise. That and it's possible to overwrite previous error variables, something that is not possible with exceptions.
- natefinch 7y agoLiterally the first non-trivial code I wrote in go (running a bunch of goroutines to download a ton of files from a website in parallel)... I knew exactly where and how things could fail and where things were failing just by looking at the code. Coming from C++ and C# and Python, there was no comparison. I had never been so confident in the code I'd written, even though I was a newbie at Go and a veteran of the other languages.
- kazinator 7y agoDid you know where every page fault would happen, and manually check every memory access and fix the situation? You didn't have to because there is an precise, robust non-checked exception handling system which takes care of that: the hardware catches the situation, dispatches a handler in the operating system which fixes it and re-starts your program at the original machine instruction to try the memory access again.
- mikeschinkel 7y agoYou do not have to be precise in Go either, and you don't have to know all the faults. All you have to know if where a return value that implements the interface `error` is not nil.
- KirinDave 7y agoI guess then I have to ask, why would try() make that worse? Because I can't stand Golang error handling. It's repetitive, it's error prone, and other language features interact with it so that when you make a mistake it can be as hard as a double free to track down where the erroneous default value was introduced. On the other hand, using Rust, Ocaml, F# or Haskell I understand how my code composed and I can be confident I can just use an error handling strategy. The only complexities appear, as with everyone else, when we have asynchronous code. So I don't mean to disagree with your feelings, but they're sure not mine and they're part of why I don't use Golang. I was excited about try() because it at least addressed the most tedious part.
- 7y ago
- weberc2 7y agoI understand what you mean by “bad ergonomics”, but I think of those things as “ergonomics in the small”. You end up writing for loops and error checks. It’s verbose but not complex, and it’s all very localized. Further, people get really hung up on these small language issues and miss go’s killer features: simplicity and consistency. Go is a small, simple language with few surprises. No guesswork about which feature subsets to use. But simplicity and consistency are themes that runs throughout the developer experience. Everyone uses gofmt so everyone’s style is the same. The standard library comes with a testing library and everyone uses it. Also, there is only one test runner, it comes with the toolchain, and you can run it on any project without special project knowledge. There is only one build system and it doesn’t make you learn a new project configuration DSL to use it, nor does it require anyone to have a working knowledge of compilers or linkers. You just run “go build” and you get a binary, and it works on almost every project (some larger projects have FFI or code generation steps). Static linking is the default. You don’t have to configure a CI job to package your libraries and push to a package registry. Nor do you have to make documentation packages or operate a webserver to serve your docs (or push to a hosted server). And the documentation tooling doesn’t require you to learn a custom documentation markup language—it’s just comments. The GC has only a couple of tuning knobs. There is no dichotomy between sync libraries and async libraries (e.g., flask vs aiohttp) nor are there questions about which coroutine / thread / async frameworks to use. I could go on and on and on, but I think I’ve made my point. I think these are the features that people like about Go and are going to continue to drive its growth until other languages wise up.
- apta 7y agogolang's "simplicity" (i.e. unexpressivity and weak modeling ability) translate into complexity in real world code bases. There's no way around it.
- weberc2 7y agoThose things do translate into some complexity in some real world code bases, but other features save much more complexity. On balance, Go comes out ahead IMO.
- 7y ago
- eikenberry 7y ago> I think the Golang community is going to find itself growing more slowly as folks increasingly realize other options offer similar benefits without the bad ergonomics. I'm curious about what you think these other options are? There are of course tons of languages and you can find just about any set of features you want, but the combination Go has along with the momentum, community, etc. it has means that there are not many that can compare in its niche. Ignoring the language/semantics (ie. the bad ergonomics) and just focusing on the external aspects. Which languages targets the same niche that have the "similar benefits" of fast compile times, static builds, great tooling, good/improving libraries, easy deployment, and mainstream backing/acceptance?
- apta 7y ago> it has means that there are not many that can compare in its niche Which is? "devops"? Otherwise, offerings on the JVM and .NET are strictly superior. And now with native compilation being available for both platforms, they will also be a better fit at devops than golang. Other alternatives include Rust.
- eikenberry 7y agoI would say the niche is basically clouds systems programming and general server side apps. JVM based language can't compare due to the JVM. The last thing you want for that type of programming is a huge, complex virtual machine to worry about. That plus memory issues, slow compiles, complex deployments makes it not really in the running. The .net based languages are a bit more interesting, but they have a _lot_ of ground to make up for due to their roots. Not having their roots in the native OS/culture of the internet will make it tough road. Rust is nice but has its flaws as well. I think it will end up nailing a lot of use cases where C++ would have been picked before. Go really targets what JVM based languages or things like Python+C would have been used for... not C++. That is, I think it is really a different niche.
- repolfx 7y agoThe last think you want for general server side programming and cloud systems programming is Java? Because of the JVM? You should probably tell Google and Amazon that. Both very heavy users of Java on the server, despite Go. In fact the server space is where Java is most dominant! The JVM is not actually complicated to use, especially not in the latest versions. It has the same number of 'default knobs' (that you should probably tweak in production) as Go does, but they're simpler to understand, for instance, Go requires you to control GC overhead by specifying "heap overhead" whereas Java just lets you specify a pause time goal directly, which is what you actually care about. As for slow compiles, where did you get that idea? Java is extremely fast to compile. You can compile hundreds of thousands of lines of code and start executing them in seconds. I wonder to what extent you really used the ecosystem at all, with comments like that.
- diminoten 7y agoYeah but as a prospective Go user, the fact that the language is opting for pain turns me off. Enjoy your ecosystem, I'm going to continue to use languages that actually like me, and care how my experience is.
- meddlepal 7y agoIt is all fun and games until someone at your job introduces Go into your ecosystem unfortunately then you're sort of stuck.
- mikeschinkel 7y agoI would say you can't know if it will cause you pain until you try it. Using the metaphor, some people actually like certain types of pain, and pain is something that is very hard to understand simply by listening to the complaints of others.
- skywhopper 7y agoWe don't all agree that it feels super bad. I think you are completely wrong on the ergonomics. Go's error handling looks ugly to people used to languages that try to _hide_ error states, but it's so much easier to work when you are unfamiliar with the codebase or when it's been a few months since you last touched the code. Clarity of unfamiliar code is part of language ergonomics as well. I'm not sure I follow your argument about Go "approaching" checked-exceptions in Java. Nothing is being forced on you. Go has worked the same way for a decade now. There is a lot of hugely successful software written in Go. In all that time, errors have worked the same way. In terms of choosing principles over ergonomics, in fact the Go committee chose ergonomics over the mistaken principle that "explicit error checking is so ugly and onerous that it's worth adding magic behavior and removing clarity". In any case, no one is arguing we shouldn't or couldn't improve Go's ergonomics. Rather, the conclusion from people who work with Go every day and are happy with the tradeoffs for their particular projects was that this specific change would make more things worse than it made better.
- mikeschinkel 7y agoI think it is unfair to label Go with "bad ergonomics." It might be fair to say the ergonomics are suboptimal for the code _writer_, but I would say they are much closer to optimal for the code _reader_.