Live data from Hacker News

Ten years of “Go: The good, the bad, and the meh”

blog.carlmjohnson.net

211–220 of 305 posts

Re: Ten years of “Go: The good, the bad, and the meh”

#211
post #131

Earlier quoted context omitted.

I am not aware of an option that "catches everything", in any langauge.

Any language with exceptions, checked or unchecked, will not allow errors to unintentionally get swallowed unless you write explicit code to do so. Rust and Zig's error handling also has the same property. This comes from experience working on large golang code bases, with error linters, and seeing errors silently and unintentionally ignored.

Explicit code to do so in Java involves wrapping two error throwing methods in one try catch, which wither have the same error class or downcasting the exception. Its been a long while since Ice used Java but i ran into that in other peoples code in production constantly.

For me it really stood out because thats when i first tried go, and while i found the error handling annoying, i found it rather directly addressed that issue.

Re: Ten years of “Go: The good, the bad, and the meh”

#212
post #187

Earlier quoted context omitted.

Can you point to something Go has spent this hypothetical marketing budget on?

Docker, Kubernetes and key CNCF projects.

What was the marketing investment here..?

Re: Ten years of “Go: The good, the bad, and the meh”

#213
post #42

Go didn't try to be overly clever and abstract. That rubs quite a few people the wrong way, but it also means you are less likely to have to work with people who try to be clever. My first reaction when seeing Go is that it smelled of "old fart". It looked straightforward and unexciting. I'm an old fart. I like straightforward and unexciting. It tends to lead to code that I can still read 6 months from now. I want to…

I still don't know what people mean by "obvious" code. Yes, there are people who create a mess with abstraction. This happens in every language, in Java people create FactoryFactories, in Haskell people play type tetris, in Ruby, people abuse metaprogramming and in Go, I assume some people go overboard with code-gen. But that said, I suspect many people, when they say, "obvious code", they mean "I can easily understa…

> Yes, there are people who create a mess with abstraction. This happens in every language, in Java people create FactoryFactories, in Haskell people play type tetris, in Ruby, people abuse metaprogramming and in Go, I assume some people go overboard with code-gen.

It's possible in any language and yet some languages' codebases are consistently worse than others ;)

If you create a culture of cleverness, implicitness and metaprogramming, that's what the programmers using your language will do. It's self-selection to an extent.

"I've suffered long from the Ruby ecosystem's mentality of 'look at what I can do!' of self-serving pointless DSL's and frameworks and solemnly swore to myself to stay away from cute languages that encourage bored devs to get 'creative'." [1]

"I worked at a Scala shop about 10 years ago. Everyone had their own preferred "dialect", kind of like C++, resulting in too much whining and complaining during code reviews. IMHO, the language is too complex." [2]

> And all the while, every one of these lines could be mutating some shared state

That's where the obvious code helps.

Let's circle back.

> I still don't know what people mean by "obvious" code.

The Zen of Python is a nice primer: [3]. A beautiful display of taste right there.

A few concrete examples:

- "Explicit is better than implicit."

Explicitly returning errors means we get to see every single point at which something could error out - explicit, as opposed to exceptions that could implicitly propagate from any line of code, with no way to tell.

Preferring pure functions - a pure function is a black box with a clearly drawn boundary line of input->output. Trivial to reason about in isolation.

No automatic type conversions.

No global state - any part of the code could change it.

No metaprogramming - you've learned Ruby but now some parts of the language have been changed to mean something completely different!

"The syntax has so many ways of doing things that it can be bewildering. As with Macro-based languages, you are always a little uncertain about what your code is really doing underneath." [4]

- "There should be one-- and preferably only one --obvious way to do it."

Uniform code. Iterating through an array always looks the same, so if the code you're looking at does it differently, you'll pay attention.

[1] https://news.ycombinator.com/item?id=13482459

[2] https://news.ycombinator.com/item?id=31219392

[3] https://peps.python.org/pep-0020/

[4] https://alarmingdevelopment.org/?p=562

Re: Ten years of “Go: The good, the bad, and the meh”

#214
post #166

Earlier quoted context omitted.

Well, let's be honest: it targets junior developers, or at least that was originally a major goal. It is backed by Google and is marketed. It actually targeted Google developers. It was a 20% project that was not backed by the company officially. Official backing only came *AFTER* others were convinced internally that it was worthy. Their marketing budget started at a grand total of $0. So it stated with NONE of the…

A programming language "starting" is usually a longer period of time, at least by my definition. Not the first year or so. Also, that go targeted junior developers were the authors words, not mine. Last: > Can you provide a reason why we should care about a language being "an advanced high-level language"? Because it makes a certain group of developers more productive. If you care about that or not is your decision.…

Because it makes a certain group of developers more productive. If you care about that or not is your decision. I'm not saying you should.

I would qualify that further.

It makes a certain group of developers more productive for certain kinds of problems. In particular they are more productive for rapidly creating relatively small prototypes. Particularly if performance is not a significant concern.

By the data that I've encountered (private and proprietary), using the features that make for high level languages, also make development in the large harder. And increase the cost of maintenance. You also get the issue that different parts of the code become likely to follow different styles. And the points where they meet are likely to become problematic.

If you care about that or not is your decision. I'm not saying you should. But these were the issues that the golang designers were attempting to address.

Re: Ten years of “Go: The good, the bad, and the meh”

#215
post #214

Earlier quoted context omitted.

A programming language "starting" is usually a longer period of time, at least by my definition. Not the first year or so. Also, that go targeted junior developers were the authors words, not mine. Last: > Can you provide a reason why we should care about a language being "an advanced high-level language"? Because it makes a certain group of developers more productive. If you care about that or not is your decision.…

Because it makes a certain group of developers more productive. If you care about that or not is your decision. I'm not saying you should. I would qualify that further. It makes a certain group of developers more productive for certain kinds of problems. In particular they are more productive for rapidly creating relatively small prototypes. Particularly if performance is not a significant concern. By the data that I…

I think you are quite mistaken. It is pretty much commonly agreed that powerful typesystems are not great for prototypes, rather the opposite, they allow easier maintenence of bigger codebases.

Re: Ten years of “Go: The good, the bad, and the meh”

#216

Worked with Go over 6 years; my biggest annoyance at the beginning, verbosity of error handling, has mostly gone away. In most cases the explicit error handling helped us hardening the code. What does still bother me is the lack of proper enum support. I remember when Java boosted their enum support and the way it impacted the quality of the code. Sure would love to see something similar in Go.

Java now has records, record patterns, pattern matching, and switch expressions. Things that the golang author still don't seem to understand the need for (quite ironic for a language that claims it makes concurrency easy).

Is that more or less ironic than Java copying Go's goroutines and still struggling to add value types?

Re: Ten years of “Go: The good, the bad, and the meh”

#217

I am immensely thankful for Go. The simplicity of the language and the stdlib is shockingly well thought out -- things like io.Reader are so obvious and yet not part of many other languages. The language has made me a better programmer. And the cross-compilation story is chefs kiss . Working on a cross-platform project where in Go, I write code and it just builds. In Java, I fight with Gradle. In Swift, I fight the t…

> I wish the protobuf library wasn't awful I’m curious what you don’t like about it? I haven’t used Go in anger, but I love protobufs, and it’s shocking that Go, of all languages, would have a substandard implementation.

My personal gripes are around the generated code not being idiomatic Go. It feels like code written by someone who doesn't really enjoy Go.

In particular, oneofs are *so* awful to work with that I'm often tempted to use an Any instead. For example:

    message Image {
      oneof kind {
        Bitmap bitmap = 1;
        Vector vector = 2;
      }
    }
Should, in my opinion, lead to code like this:

    img := &Image{Kind: &Bitmap{}}
But the reality looks more like this:

    img := &Image{Kind: &Image_Bitmap{Bitmap: &Bitmap{}}}

My other main gripe is that the generated structs embed a mutex, and so can't be copied, compared [ergonomically], or passed by value.

Sadly, both of these issues are explained away as on the issue tracker.

(My use-case is primarily to share data structures across languages, so perhaps it's not totally aligned with what protobufs is trying to do. I just wish there was a better alternative.)

Re: Ten years of “Go: The good, the bad, and the meh”

#218

Earlier quoted context omitted.

C# has way, way more market share than Go as well as a bigger ecosystem and it's not even close. I would hardly call a Java replacement a "niche" since that's everywhere. There are, of course, other benchmarks that rank c# above go, but benchmarks are flawed. I imagine people are comparing C# to go because it's got a pretty solid type system

I would beg to differ. On Github[0], Go currently sits at #3 for pull request volume (C# is at 10), #3 for stars (C# is at 8), #6 for pushes/commits (C# is at 10) and #6 for issues opened (C# is at 9). By each of those metrics, Go has a significantly more vibrant ecosystem than C#. [0]: https://madnight.github.io/githut/#/pull_requests/2023/2

https://redmonk.com/sogrady/2023/05/16/language-rankings-1-2...

This is one of the better rankings. But I would add that these will significantly underrepresent enterprise-type projects, where C# is often used. Some say that job listings give a more accurate picture, and while I didn’t look it up, I do believe that C# has more positions.

Re: Ten years of “Go: The good, the bad, and the meh”

#219
post #208
post #180

Earlier quoted context omitted.

Honestly, I'm incredibly frustrated with this issue; it's just pure idiocy. Commenting out a part of the code and observing the effects is such a simple and useful debugging technique, yet this "feature" of Go prevents you from doing so effectively. What's even more frustrating is that when you search for solutions, you come across two kinds of (pardon my language) completely brain-dead responses: First, there are th…

> I've never seen anyone argue that allowing unused variables is good for production. It's always been about facilitating the development process and debugging. Yes, I am aware now there are unused variables, but please just let me see what does removing this part of the code do. Yes, but once you allow that, you'll inevitably end up with unused variables in production code (warnings are useless). That's the core of…

Fully agree on both of these messages. This is the only thing I don't agree:

> warnings are useless

Warnings are useful, to (no surprise here) warn me about possibly problematic stuff. That's why my C++ builds are usually full of warnings during development, but the final build for production won't contain any, because it is performed with -Werror (i.e. "treat all warnings as if they were compilation errors"), thus any unsolved warning would break the build.

A common reply to this argument, which just in case I'd like to reply in advance, is: "but the end result will be that in order to save time, and to avoid having to fix all those pesky warnings, lazy devs will end up doing production/release builds without the -Werror flag (or equivalent for whatever compiler)". To which my response is: That's a social/political/behavioral problem, a poor project management, or any combination of them, and you cannot even start to pretend that those can be solved with technology.

Re: Ten years of “Go: The good, the bad, and the meh”

#220
post #90

Earlier quoted context omitted.

> you can learn in a day and keep in your head. I'm not sure that this successpoint is really that valuable. It sounds more valuable for those who want butts in seats than it does for long term satisfaction and survivability of your code base.

Being able to read your code you wrote 2 years ago does wonders for survivability, which is a gross simplification of course. It's a great language for some problems, horrible for others. The problem is people tend to talk as though everyone works in their domain.

If “each individual line is easy” would work, we would be reading-writing in assembly. I don’t accept the premise that Go would be any better in this region, if anything, it is worse by cluttering up the happy path by error “handling” noise, and much harder than they should be opewtions.
Post reply on HN