4 ms·
>I found it a chore to maintain Go-based systems My opinion is the opposite. Almost every go code base I've seen is extremely consistent compared to other lang
by 43224gg252 9y ago
>I found it a chore to maintain Go-based systems
My opinion is the opposite. Almost every go code base I've seen is extremely consistent compared to other languages. Going from one code base to another is almost always seamless because learning Go involves learning the Go tools which forces you to follow Go coding standards. I'd choose to work on a Go code base over Java or C++ any day of the week.
I don't have much experience with elixir, but that's because I like to stay employed.
>the entire error thing is absurd. Anders Hejlsberg got this right many years ago: 9 out of 10 errors are "handled" by a central error handler
This is almost always unacceptable in production, especially when it comes to mission critical hard/software. You need to be able to handle errors in production that you may not even be able to catch in testing and that means you need to catch all the errors and think critically about what should be done when that error is encountered. "Central error checkers" are almost never robust enough for mission critical systems.
Go basically forces people to write high-quality, resilient code bases, and I like it for that.
- thinbeige 9y ago> I don't have much experience with elixir, but that's because I like to stay employed. While the previous commenter gave an objective and rational overview why he think Go gives him a hard time you can't resist to get polemic.
- 43224gg252 9y agoI gave rational counter arguments and employment is pretty important too imo. It seems a lot of the anti-Go people tend to favor languages that no one gets paid to use.
- thinbeige 9y agoYes, but the discussion wasn't about the employment situation and if--your tone was slightly inappropriate. You could have also written: "I've no experience with Elixir but your words catch my interest. The inferior Elixir enployment situation (compared to Go) held me back from Elixir. But I should give it a try." Same message and nobody loses his face.
- deleted 9y ago[deleted]
- actsasbuffoon 9y agoI'm getting paid to write Elixir right now.
- jorgec 9y agoIn reality, Go is a language that practically no one gets paid to use. Go is niche and the few projects around here are short term.
- zimpenfish 9y agoI interviewed for two Go jobs in London last month that were specifically building up Go teams for long term projects. It's definitely getting less niche by the month.
- freeone3000 9y agoYou have the ability to choose Go - you could as easily have chosen Elixir.
- nine_k 9y agoYou should stick with Cobol. It paid the developers for 60 years, and has a very fair chance to continue commanding reasonably good salaries for another 20 or 30. Maintaining Cobol code is a chore, though, partly for the same reasons as Go code.
- di4na 9y agoPaid for Elixir full time, and there is definitely a market :)
- latch 9y agoI definitely agree with you that Go codebases has a high level of consistency. It's certainly one of the many good things Go offers and something I hope other languages look at to see if they can replicate. But, that doesn't really have anything to do with it being a chore. We can just agree to disagree on that. However, I think you misunderstood my point about errors (or maybe you're just working with very different types of systems). Empirically, looking at Java codebases, the C# team found that most errors weren't "handled" beyond an outer exception handler. Anecdotally, this has been my experience as well. I admit that this is a very 'web' point of view, where requests are isolated and most exceptional situations are best handled with logging + showing the user a friendly error message. At this point, they should adopt the Elixir approach and consistently provide a ! alternative across the stdlib (Must* is inconsistently available and verbose). They thought Go would be used by C++ programmers, instead it's being used by Ruby programmers (1). The language paradigm doesn't fit how people are using it as well as it could. I'm not sure what other languages you've been exposed to, but your last line is hard for me to believe. If you look at other languages, you'll find a lot of techniques aimed at quality and resilience that are nowhere in Go. Again, that doesn't make Go bad, but "resilient" ? Go has mutable, shared memory, nils, no thread isolation, no generics (so runtime casting), no pattern matching and so on. Even the error system which you like is reckless (??) compared to what you'll find in languages like Rust and Haskell (Result and Maybe). (1) https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html https://commandcenter.blogspot.com/2012/06/less-is-exponenti...
- dullgiulio 9y ago>> the entire error thing is absurd. Anders Hejlsberg got th is right many years ago: 9 out of 10 errors are "handled" by a central error handler > This is almost always unacceptable in production, especially when it comes to mission critical hard/software. You need to be able to handle errors in production that you may not even be able to catch in testing and that means you need to catch all the errors and think critically about what should be done when that error is encountered. Absolutely. My approach is usually that errors are always wrapped not just returned. The wrapping itself ends up looking almost like code documentation: "could not do X: <previous error>", "error while doing X: <previous error>". Every error string is then unique in the program, easy to grep. "Could not perform the operation", maybe together with a 500 lines stacktrace in your logs (which are maybe line-by-line bacause that's the default)... you are up to a nice middle of the night debugging session :)
- dvirsky 9y agoExactly, once you wrap errors with their context, or just at the lowest level wrap it with a stack trace, they become much more useful.
- jorgec 9y agoWhen you wrap the error then you are kicking it out. Sooner or later you must catch the error. So, in most case, its just delaying the inevitable.
- rufugee 9y agoThe problem I've found it that you might wrap errors this way, but the libraries you use don't, or approach it differently. So you're either chasing down strings that may or may not be grep'able or you're fighting with delve to track down what's happening. The whole error situation with Go is one of the main drawbacks of the language imho.
- barrkel 9y ago> This is almost always unacceptable in production, This is not true for almost all software outside of embedded domains. In fact responding to an error near where the error occurred is almost always a mistake. The rare exceptions to this are when "error" is unavoidable due to concurrency (e.g. I/O), and even then many errors shouldn't be handled (misconfiguration, incomplete system initialization, etc.) or should be wrapped and transformed for human consumption (e.g. user tried to access a resource that couldn't be found - we still bubble up). > you need to catch all the errors and think critically about what should be done when that error is encountered. If you support this position, you'd support checked exceptions like Java - something that's widely considered a mistake. There's lots of reasons why it's a mistake. A more important reason has to do with dynamic construction of control flow. If you use any monad design patterns in the construction of your application (easy to do because the monad design pattern is so powerful), you quickly create boundaries that errors need to cross unmolested because they're generic and cannot possibly encode policy. The same criticisms follow through into dependency injection and other forms of modular decomposition that use dynamic recomposition. Java style has you doing utterly pointless things, like wrapping all the implementation errors in a generic module-level error - obscuring the very thing that might theoretically let user code react to the error state! More philosophically, abstractions fail in implementation-dependent ways. When you encode policy about failure outside the abstraction boundary, you're encoding implementation-dependent behaviour; but you can't put the policy inside the abstraction boundary either, because then the abstraction isn't reusable - different applications have different policies. Error handling is inherently opposed to abstraction. That's why microscopic error-handling close to the cause of the error only flies in small closed systems, like kernels, databases, embedded.
- masklinn 9y ago> If you support this position, you'd support checked exceptions like Java - something that's widely considered a mistake. The primary problem of checked exceptions in java is not that they exist, it's that they are very badly integrated with the rest of the language e.g. it's impossible to be generic or transparent over checked exceptions, their hierarchy is messy and it's often unclear why specific exceptions are checked and others unchecked. Haskell's error handling (reified through Either error values) has similar effective semantics but nowhere near the dislike because it's well integrated in the language and you can be generic over the error, the value, and the result itself.
- vbezhenar 9y agoI tried Go and so far I'm feeling that Go forces me to abandon error checking and even if error is catched, I have no idea where this error comes from, because there's no stacktrace or anything like that. Best thing I've come to is using strings as errors (completely throwing out any error hierarchy) and returning new error string for every call with call information (doing poor job which Java would do for me automatically).
- Thetawaves 9y agoThis is not the right way to do things.
- coldtea 9y ago>I don't have much experience with elixir, but that's because I like to stay employed. Yeah, because Go is the epitome of employability... >"Central error checkers" are almost never robust enough for mission critical systems. Go is not used in mission critical (embedded, medical, aviation, communications, etc) systems anyway. Besides the notion is wrong: mission critical systems DO centralize error checking. The code local to the error wouldn't have enough context (and shouldn't have the reach) to call the right procedures for cleaning up and moving on.