Why Go is not my favourite language

(blog.habets.se)

28 points | by behnamoh a day ago ago

19 comments

  • bccdee 18 hours ago ago

    Oddly this misses the two big things I hate about Go: Squishy types and no immutability.

    1. A nullable SQL string is idiomatically expressed as sql.NullString{String: "my string", Valid: true}. If you forget to initialize `Valid`, it silently sets itself to false and your string is null. I feel like the right solution for this is sum types, but Go says you only need interfaces (and then of course it doesn't use them for stuff like this). And Go doesn't have named arguments, so convention for big functions is to pass a big struct with fields for all the arguments. If you omit a field, it gets zero-intialized, which is nice if you want the default to be zero, but otherwise you can't really have a default value, because there's no way to tell if a given zero was explicit or implicit. And there's no way to ensure that every field gets filled in. I get what they're trying to do with zero values, but it makes the whole type system feel a little bit squishy.

    2. I want immutability semantics. Good immutability. Go doesn't even have bad immutability. If you're disciplined, whatever, but people aren't, and I've seen a lot of Go turn into big nasty mutable mudballs.

    • imiric 3 hours ago ago

      > otherwise you can't really have a default value, because there's no way to tell if a given zero was explicit or implicit

      You can use pointers, or nullable types. These are not ideal, admittedly, but it's not true that "there's no way".

      > there's no way to ensure that every field gets filled in

      This can also be done with an exhaustive linter. You might think this isn't great either, but then again, always being reminded that you left out some fields is a) annoying, and b) goes against the benefit of default values altogether.

      I agree with you on immutability, though.

      I also agree with some of the points in the article, and have my own opinions about things I would like Go to do differently. But if we can agree that all programming languages have warts and that language designers must make tradeoffs, I would say that Go manages to make the right tradeoffs to be an excellent choice for some tasks, a good choice for many tasks, and a bad choice for a few tasks. That makes it my favorite language by a wide margin, though that's also a matter of opinion.

  • N_Lens 21 hours ago ago

    Not to disagree with the author as I feel their passion for language semantics is probably valuable “somewhere”.

    However, as an engineer I find Go very easy and usable despite these nits.

  • tapirl 18 hours ago ago

    Go was my favorite language for a long time, and I have written many books and articles about it. However, since the release of Go 1.22 [1], that is no longer the case. Go 1.22 damaged Go's reputation for promoting explicitness and maintaining strong backward compatibility.

    [1]: https://go101.org/blog/2024-03-01-for-loop-semantic-changes-...

    • bccdee 18 hours ago ago

      for-loop variable capture was maybe the #1 worst decision in the language. It was never what you wanted. I appreciate Go's commitment to backwards-compatibility, but in this case breaking it was the right choice.

      • tapirl 12 hours ago ago

        It is only right for for-each loops.

        For 3-clause-for loops, if you have read https://go101.org/blog/2024-03-01-for-loop-semantic-changes-... carefully, it is hard to think it is right.

        • bccdee 5 hours ago ago

          All the examples in that article are very exotic.

            for i, p := 0, (*int)(nil); p == nil; fmt.Println(p == &i) {
              p = &i
            }
          
          Be honest, how many times have you actually seen code which depended on the address of a variable declared in a 3-clause for-loop remaining stable across loop iterations? Nobody does this. It's extremely weird and un-idiomaic. Heck, 3-clause for-loops are somewhat uncommon in and of themselves. Conversely, everyone who writes Go has experienced unintuitive capture issues with for-range loops.

          Are you actually aware of any breakages this change has caused?

    • nacozarina 11 hours ago ago

      this is a repeating pattern with languages; there's no commitment to design coherency, no governance, just a mad scamper to stuff features into the project until it becomes an absurd caricature of itself.

      C++ did it so egregiously & disastrously you'd think language maintainers would have been scared straight. No, like moths to a flame, it is the preferred hill to die on.

      This is how C99 keeps winning when it bleeping should not. It's settled science, however imperfect. It's not getting rearranged because someone read a blog post. It has stability in real-world clock-on-the-wall terms like nothing else.

      • tapirl 6 hours ago ago

        The change made in Go 1.22 for 3-clause-for loops is not a new feature. It simply broke backward compatibility and old Go principles. It is much worse than C++'s stuff features.

    • tommica 15 hours ago ago

      What is your language of choice now then?

      • tapirl 12 hours ago ago

        zig now.

  • leecommamichael 2 hours ago ago

    The author should try Odin.

  • DoctorOW 19 hours ago ago

    I'm going to be honest, I always felt like the verbosity was the point of Go. Iirc the whole reason it was invented was to let codebases be as readable as they are writable even for less experienced developers. Why are there Error types when exceptions exist? To force you to acknowledge the possibility for errors. You can easily let your frameworks and libraries handle recovering from panics, but err is unavoidable. You have to, at the very least, put the _.

    • cwillu 8 hours ago ago

      Which is great until you have to troubleshoot an error code surfaced by a nasty web of code with no idea where it came from because the simplest way to handle err is to re-return it, optionally (and more or less uselessly) wrapping it in a new err. I'll take a panic with a stack trace over that any day.

  • 3 hours ago ago
    [deleted]
  • electroglyph 21 hours ago ago

    damn this is old. how relevant is this today?

  • logicprog 20 hours ago ago

    [dead]