top | item 28822752

Go is a terrible language (2020)

51 points| nassimsoftware | 4 years ago |debugged.it | reply

64 comments

order
[+] bedobi|4 years ago|reply
The worst problem with almost all popular programming languages are null and shitty error handling, such that, when you call foo() where foo is String foo(){ blabla } you can get a String, null OR an exception/hidden error response, but most compilers happily let you treat it as if it only ever returns a String. (What!!!?)

I hope some day null is no longer a thing, and that Functional Programming types like Option, Either, Try etc in the native libraries is the new default. (BTW, there's really nothing "Functional Programming" about them, they're just objects like any other in "Object Oriented" languages)

[+] angelzen|4 years ago|reply
Not top 5 languages, but Scala & Rust fit the bill.
[+] mftb|4 years ago|reply
This article is a poor choice for submission. He did a companion article that is the exact opposite, and a follow-up article a year later. The follow-up would be a much better choice. It gives links to both prior articles and his thoughts after a year of reflection - https://debugged.it/blog/20000-lines-under-the-go-cean/ .
[+] eyelidlessness|4 years ago|reply
I’ve never written a line of Go, though I’ve read a fair bit. I was expecting to object to the criticism of its error handling but I ultimately agree. If you can return and ignore an error, that’s another way of saying throw/raise. If error isn’t typed it’s no different from “anything can throw anything anywhere in the stack”. I had thought, not paying much attention to Go in particular, it must deal with this with something like an Either type. Even some language facilities to automatically unwrap Either and rewrap for callers if unhandled would be a great answer to the checked exceptions debate. But what I take away from this is errors in Go are just as amorphous as in JS but harder to find. That’s quite a feat!
[+] klodolph|4 years ago|reply
I write both Go and JavaScript.

> If error isn’t typed it’s no different from “anything can throw anything anywhere in the stack”.

Errors aren't untyped. It's an interface type. Not everything returns errors anyway, they definitely can't be returned from anywhere in the stack.

Errors in Go are definitely nowhere near as amorphous as those in JS. In JS, you can take an Error object and stick additional properties on it, and then throw that. In fact, Node does that, and by extension, thousands of JS libraries generate exceptions like that.

With Go, you use errors.As(), or errors.Is(), or a little bit of dynamic casting. The type of error which a function returns may not be part of its type signature, but decent libraries usually have only one or two error types they return. Yes, I hit F12 to see the library's source to see what errors it returns... but that's just because the IDE experience with Go is so fast and nice to use.

[+] bigdict|4 years ago|reply
It's just an improvement on error handling in C without introducing heavyweight exceptions.
[+] klodolph|4 years ago|reply
> ...functions don't declare what kind of errors they return.

We've gone down this route with Java and my conclusion is that declaring the kind of errors a function returns is, for most users, just a pain.

https://www.artima.com/articles/the-trouble-with-checked-exc...

My experience with Go is that decent libraries only have a small number of error return types, and then forward or wrap errors from libraries that they use. You can use errors.Is(), errors.As(), errors.Unwrap() to figure things out as necessary.

[+] hota_mazi|4 years ago|reply
It's a pain because it forces users to consider and code against error paths.

Just like putting on a seat belt is a pain.

Both are pains that are worth having because they help you create robust software.

The ways in which a function can fail should absolutely be part of its signature, and if these are recoverable, the compiler should refuse to build until you either handle these errors or pass them on to the caller.

[+] systemvoltage|4 years ago|reply
This post should not have been flagged. It is a completely valid criticism of Go. Author's tone could have been better but I'd rather hear straightforward opinions and not polished speech to offend those that cannot defend Go. Personally, I am a huge fan of Go but these are some valid points.

Anyone supporting such flagging behavior is completely against the spirit of what made this place great. Please reconsider your actions and what flagging does on HN.

[+] nassimsoftware|4 years ago|reply
[+] kvnhn|4 years ago|reply
Thanks for sharing this. It's very hard to lend credence to this series after reading this follow-up. Quoting from the link:

"There are certainly many reasons to hate Go, from the unusual syntax to the half-arsed way they decided to implement the programming model. On the other hand you can go all fanboy over how cool Go is because it makes it so simple to write microservices. (No, it doesn’t. It really, really doesn’t if you want to do it properly.)

If you jumped on either of these bandwagons, I would recommend getting off as soon as possible. Neither of these approaches are very professional and are telling signs of inexperience in software development."

There is an upsetting level of hypocrisy in patronizing your readers for consuming the clickbait-titled articles _you authored_.

[+] jgrant27|4 years ago|reply

    Most applications I tend to see don’t even use concurrency because they are so small and simple that they don’t need it.
Sorry but I just can't take your opinion of any language seriously or that you have much practical experience at all because of statements like this.
[+] teeray|4 years ago|reply
> However, the larger problem is that functions don’t declare what kinds of errors they return.

They don’t need to. Static analysis (guru) can answer the question “what kinds of error can this error be?” There’s no need to go source diving as the author suggests.

[+] lokar|4 years ago|reply
IMO this is a common failure in discussions about programming languages today. You really must consider the capabilities of "external" language tools (linters, static analysis, etc).

Not having all that in the core language can be a reasonable design choice.

[+] ed_elliott_asc|4 years ago|reply
So the general complaints of the article is that go isn’t Java?
[+] aranchelk|4 years ago|reply
Seems a little more thoughtful and extensive than that, e.g. the Nullability section. AFAIK that’s not properly solved in Java either.

Also I’m guessing the section on immutability isn’t referencing something special in Java, dunno.

[+] deepsun|4 years ago|reply
More like Kotlin, as nil problem exists in Java, but not in Kotlin.
[+] animex|4 years ago|reply
@dang will HN ever support code blocks in comments? pls.
[+] bfung|4 years ago|reply
You can get fixed formatting by newline + indenting 2 spaces, similar to non-GitHub markdown

  # Like this
  y = mx + b
The “help” link could be added to more places while authoring, as it only shows up on the “edit” post screen atm.

https://news.ycombinator.com/formatdoc

[+] eyelidlessness|4 years ago|reply
Indent 4 spaces, you’ll get monospace. Not syntax highlighted but I doubt you’ll ever see that here.
[+] BrandoElFollito|4 years ago|reply
I am an amateur dev (for 25 years), using mostly Python. I was blackmailed by a friend to try Go.

Boilerplate, no exceptions, slices, ... all felt terrible.

And then I started to appreciate the typing and the fact that I had to give some thought about where to actually handle errors.

I know kinda like Go, except for the weird way maps are handled, and the lack of types in errors (compared to Python where it is fantastic).

There are certainly pros and cons (I am not a good enough developer to have advanced thoughts on that) but the cross compilation makes a lot of things easier when deploying self-contained executables.

[+] nunez|4 years ago|reply
Make sure you read the OP's follow-up before cargo-culting on the "Golang bad" ship: https://debugged.it/blog/20000-lines-under-the-go-cean

(I actually quite like Go, despite it being more difficult to write tests for than other languages, and error messages usually being very cryptic.)

[+] NelsonMinar|4 years ago|reply
I don't love that Go doesn't have exceptions. But it was a choice made thoughtfully:

https://golang.org/doc/faq#exceptions https://go.dev/blog/errors-are-values

[+] vasilia|4 years ago|reply
There is one more reason. When you write something that works in a loop, e.g. web server, exceptions are a huge potential issue. I was working on a C++ project with a very complex state machine. One day our service started using all 128 CPU cores just for stack unwinding. It was an ordinary exception in 3thrd party library raised on every request in the loop. We have tried to make a lot of optimisations in different unwind libraries. But it was far away from the performance of a simple Optional-like errors container as a return value. Exceptions are really Zero-cost if they occur only once when application should be terminated.
[+] mixmastamyk|4 years ago|reply
The language is rough but the performance, tools, and deployment is top notch. That dichotomy was quite surprising to me.

If someone could write a "coffeescript" for it, perhaps a python+pascal love-child, while keeping the fantastic lower-level parts of go, I'd be all over it.

[+] ohCh6zos|4 years ago|reply
The last two companies I have been at switches from other languages to Go. At this point I don't see what people like about Go. This article touches on problems, but it is only the tip of the iceberg.
[+] nassimsoftware|4 years ago|reply
The thing with Go is that I find the syntax very ugly to look at however it is so convenient to install, run, deploy, make performant applications.
[+] rtoway|4 years ago|reply
I'm not a Go fan but the language to me looks very readable and clean. However in my opinion syntax is usually not that important, you can and will get used to anything
[+] ronnier|4 years ago|reply
The thing that gets me is how time is handled, enums, no sets, no way to make variables final, the "make" syntax, could probably go on
[+] nobody0|4 years ago|reply
Is there possibility that go adds algebraic datatype and pattern matching? error handling will be nicer that way generally.
[+] deltasixeight|4 years ago|reply
Go is an ugly language. Practical but ugly.
[+] didip|4 years ago|reply
No way, Go is beautiful based on this 1 metric: It always looked the same regardless who wrote it.

It makes PR review job so much easier, and to me, that's beautiful.

[+] jgrant27|4 years ago|reply

    Have you debugged.it ?
Debugging seems to be the author's coding philosophy which says it all.

    While I had over a decade of experience in other languages, such as Python, PHP, Java, etc. 
    I found it extremely difficult to wrap my head around Go.
This could be because the author's introduction to programming and most of their experience has been with some very problematic languages.

Maybe it's not Go that is a terrible language but just that the author is not a systems programmer who has worked with large code bases ?

[+] tgsovlerkhgsel|4 years ago|reply
No, it doesn't get any better when the codebase is bigger. The way to figure out WTF went wrong in a large code base written in Go is:

1. Take the line number where the error was logged, likely somewhere very close to e.g. the main event handling loop, and completely disconnected from the place where the error was initially thrown. There is no stack trace.

2. Try to figure out which parts of the error string are constant (i.e. searchable), and pray for the developer to have been familiar with the issue so that the string is globally unique (corollary: When writing Go, make sure your error strings are unique, introduce some form of variation if you're throwing similar errors, even if it's just punctuation or synonyms, to make sure the throw site is identifiable).

3. Try to guess what the flow between those two sites could have been.

The lack of proper stack traces (or even the line number where the error was thrown) on errors is one of the most insane effects of this error handling approach. (The other is hard to read code because the actual logic is hidden in 3x as much error handling boilerplate).

[+] systemvoltage|4 years ago|reply
I’m not sure if I buy that. Did you read the article? The author is expressing explicitly what’s wrong in many areas and why they’re useful. I don’t like rebuttals like this because it then becomes a self-fulfilling prophecy of Go-lovers avoiding criticism from outside because “They won’t get it due to their background”. Great, now we’ve just created an echo-chamber. It’s good to get outside perspective and debate. I’m sure many Go experts would like to understand where they could improve - without losing Go’s core minimalism.

Author’s tone could be better but they’re just being straightforward that they don’t like Go and specifically why. Totally ok in my view.

[+] ClumsyPilot|4 years ago|reply
I think this criticism is very unfair, if there is one thing java is (in)famous for, its large codebases. Kafka is written in it. I myself don't use it, but you need to substantiate your argument.

Is there any reason you believe python and java are 'very problematic"? Isnt every language promlematic in its own way? Are they more problematic than C, which breeds foodguns, or what are we comparing to?