Hacker News new | past | comments | ask | show | jobs | submit login

> Go is a tool if you actually want to solve the problem and make sure people after can quickly understand how and why you solved it. Rather than stand in awe of your creation.

I disagree with that.

The problem in those cases is not expressivity. It's complex features that are very easy to misuse and have no alternatives within the language.

And Go is littered with those. It allows for lots of "cleverness" around Reflection and Empty Interfaces, which effectively turn it into a poorly-specified ad-hoc dynamic language. Same for templates. This is the same problem of Meta-programming in Ruby, and the same problem with complex OOP architecture that plagues some Java projects. It's all avoidable, of course.

Those features are not "expressive", quite the contrary, but they lead to the same problem of "pile of crap nobody want's to touch because some of the developers were so creative and wanted to express themselves".

It takes as much discipline within a team to avoid this in Golang (or any other "non-expressive language") than in more expressive languages.

On the other hand, lots of new ES6 features give it more expressivity without necessarily adding complexity and in fact making the code easier to read and more reliable.




>And Go is littered with those. It allows for lots of "cleverness" around Reflection and Empty Interfaces, which effectively turn it into a poorly-specified ad-hoc dynamic language.

I strongly disagree with that. You can do it, you can do clever code through reflection. But it is actively discouraged unless it's something required to solve the problem, e.g automatic JSON marshalling/unmarshalling.

No professional Go dev is going to immediately reach for empty interfaces or reflection without seeing what the solution looks like with verbose type safe code.


Maybe in your experience this doesn't happen, or maybe we have different thresholds for what we consider abuse, but it's definitely a thing for a lot of people.

Also, overuse of reflection doesn't happen overnight, or only because of inexperienced programmers.

In most complex projects it happens because someone wants to add more complex abstractions that exist in other languages to help with the work and to reduce programmer error and the only way to do it is via Reflection and Empty Interfaces, or maybe via templates.


All of the Go projects where I work have a very strong "empty interfaces are bad" culture (noobs who don't know better will get called out in code review), and the only reflection I've ever run across is for marshaling/unmarshaling. I really don't see these things being overused at all. When I first started using Go, I did perpetrate some empty interface crimes, but it really only takes one experience getting bitten by thwarting the static typing before you learn to avoid that.


I'm glad you are having a good experience, but people work on different projects with different requirements and different constraints.

In Go, empty interfaces and reflection, or templates, are for some cases the only possible way to solve a large class of complex problems. If you don't encounter those problems then it's all good, but some people do.

You haven't also taken into account the possibility of people having to maintain pieces of Go code acquired or forked from somewhere else. Maybe my team was the one who inherited the code from someone who "perpetrated some empty interface crimes".

Not all Go development is greenfield development.

This is one of the things I dislike the most about the Go community. Every single criticism or suggestion to the language is dismissed as being user error, without even taking into consideration the use case or the different experiences one might have, or if the codebase was gotten from somewhere else, or even acknowledging that there are other programming styles. It is a giant echo chamber with people constantly saying "works on my computer".


I dunno, that seems a little unfair. I’m not saying empty interfaces aren’t a problem just because I’ve managed to avoid them, I’m just saying it is quite possible to write reasonable Go by knowing what language features are misfeatures. Obviously if you’re often running across and having to deal with code laden with empty interfaces, that’s a major problem and put in that situation, I’d probably have the impression that the language encourages bad behavior. I’m just saying that so far, I haven’t encountered it all that much so I don’t really perceive it as a problem. If you want to paraphrase this as “works for me,” so be it, but it seems like a particularly uncharitable interpretation.

I do think it’s a crime that the standard library contains some empty interfaces in critical packages that seem egregious. The fact that you can accidentally pass an rsa.PublicKey (instead of a pointer to an rsa.PublicKey) to a function that takes a crypto.PublicKey interface and not find out until runtime is hard to forgive.

Anyway, I’m not just saying “works for me” but I am saying that I’m not going to let what dumb things someone else might do with the language change my enjoyment of it. This view is likely influenced by the fact that my particular projects aren’t allowed to pull in 3rd party dependencies without a thorough review, so the problem of dependency fan-out that may pull in some unfortunate code is reduced significantly.


And TypeScript and Flow these days allow to properly type the wast majority of JavaScript “dynamic typing” patterns making reflection usage in Go and Java to look ridiculous for a supposedly statically typed languages.


>It takes as much discipline within a team to avoid this in Golang (or any other "non-expressive language") than in more expressive languages.

I think this will differ from team to team. I've been working within two different companies as a Go dev so far and haven't seen any Reflection misuse issues.

The difference I see here: while Go does indeed have those features-about-to-turn problems you will be called on not use them too much or use them at all from around every corner. They are there as a necessarily evil.

At the same time meta-programming and every thing that comes with ruby's dynamic expressiveness usually is the one of the selling points.

Go has its flaws and tradeoffs, and simply things that can and will be misused but you don't see articles that promote them as something that should win you over some other language.


> Go has its flaws and tradeoffs, and simply things that can and will be misused but you don't see articles that promote them as something that should win you over some other language.

I disagree there. I can think of two examples of things I consider very easy to misuse in Go, but are promoted by the community as being the superior solution to problems in articles and posts all the time: Go Error Handling and Go Code Generation.


>Go Code Generation.

Agree

>Go Error Handling

Go error handling has its downsides but how can you misuse it? If your code may generate an error = return an error to handle elsewhere. If the code you are calling returns an error = handle it.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: