Xeoncross 2 days ago

I know they say that your programming language isn't the bottleneck, but I remember sitting there being frustrated as a young dev that I couldn't parse faster in the languages I was using when I learned about Go.

It took a few more years before I actually got around to learning it and I have to say I've never picked up a language so quickly. (Which makes sense, it's got the smallest language spec of any of them)

I'm sure there are plenty of reasons this is wrong, but it feels like Go gets me 80% of the way to Rust with 20% of the effort.

  • roncesvalles 2 days ago

    The nice thing about Go is that you can learn "all of it" in a reasonable amount of time: gotchas, concurrency stuff, everything. There is something very comforting about knowing the entire spec of a language.

    I'm convinced no more than a handful of humans understand all of C# or C++, and inevitably you'll come across some obscure thing and have to context switch out of reading code to learn whatever the fuck a "partial method" or "generic delegate" means, and then keep reading that codebase if you still have momentum left.

    • asa400 2 days ago

      > The nice thing about Go is that you can learn "all of it" in a reasonable amount of time

      This always feels like one of those “taste” things that some programmers tend to like on a personal level but has almost no evidence that it leads to more real-world success vs any other language.

      Like, people get real work done every day at scale with C# and C++. And Java, and Ruby, and Rust, and JavaScript. And every other language that programmers castigate as being huge and bloated.

      I’m not saying it’s wrong to have a preference for smaller languages, I just haven’t seen anything in my career to indicate that smaller languages outperform when it comes to faster delivery or less bugs.

      As an aside, I’d even go so far as to say that the main problem with C++ is not that it has so many features in number, but that its features interact with each other in unpredictable ways. Said another way, it’s not the number of nodes in the graph, but the number of edges and the manner of those edges.

      • synthetic-echo 2 days ago

        Just an anecdote and not necessarily generalizable, but I can at least give one example:

        I'm in academia doing ML research where, for all intents and purposes, we work exclusively in Python. We had a massive CSV dataset which required sorting, filtering, and other data transformations. Without getting into details, we had to rerun the entire process when new data came in roughly every week. Even using every trick to speed up the Python code, it took around 3 days.

        I got so annoyed by it that I decided to rewrite it in a compiled language. Since it had been a few years since I've written any C/C++, which was only for a single class in undergrad and I remember very little of, I decided to give Go a try.

        I was able to learn enough of the language and write up a simple program to do the data processing in less than a few hours, which reduced the time it took from 3+ days to less than 2 hours.

        I unfortunately haven't had a chance or a need to write any more Go since then. I'm sure other compiled, GC languages (e.g., Nim) would've been just as productive or performant, but I know that C/C++ would've taken me much longer to figure out and would've been much harder to read/understand for the others that work with me who pretty much only know Python. I'm fairly certain that if any of them needed to add to the program, they'd be able to do so without wasting more than a day to do so.

        • Denzel 2 days ago

          Did you try scipy/numpy or any python library with a compiled implementation before picking up Go?

          • synthetic-echo 2 days ago

            Of course, but the dataset was mostly strings that needed to be cross-referenced with GIS data. Tried every library under the sun. The greatest speed up I got was using polars to process the mostly-string CSVs, but didn't help much. With that said, I think polars was also just released when we were working with that dataset and I'm sure there's been a lot of performance improvements since then.

          • rcxdude 14 hours ago

            These only help if you can move the hot loop into some compiled code in those libraries. There's a lot of cases where this isn't possible and at that point there's just no way to make python fast (basically, as soon as you have a for loop in python that runs over every point in your dataset, you've lost).

      • kalterdev 2 days ago

        > I’m not saying it’s wrong to have a preference for smaller languages, I just haven’t seen anything in my career to indicate that smaller languages outperform when it comes to faster delivery or less bugs.

        I can imagine myself grappling with a language feature unobvious to me and eventually getting distracted. Sure, there is a lot of things unobvious to me but Go is not one of them and it influenced the whole environment.

        Or, when choosing the right language feature, I could end up with weighing up excessively many choices and still failing to get it right, from the language correctness perspective (to make code scalable, look nice, uniform, play well with other features, etc).

        An example not related to Go: bash and rc [1]. Understanding 16 pages of Duff’s rc manual was enough for me to start writing scripts faster than I did in bash. It did push me to ease my concerns about program correctness, though, which I welcomed. The whole process became more enjoyable without bashisms getting in the way.

        Maybe it’s hard to measure the exact benefit but it should exist.

        1: https://9p.io/sys/doc/rc.html

      • HumblyTossed 12 hours ago

        > Like, people get real work done every day at scale with C# and C++.

        That would be me. I _like_ C#, but there are elements to that language that I _never_ work with on a daily basis, it's just way too large of a language.

        Go is refreshing in it's simplicity.

      • 8organicbits 2 days ago

        I think Go is a great language when hiring. If you're hiring for C++, you'll be wary of someone who only knows JavaScript as they have a steep learning curve ahead. But learning Go is very quick when you already know another programming language.

      • throwaway894345 2 days ago

        I agree that empirical data in programming is difficult, but i’ve used many of those languages personally, so I can say for myself at least that I’m far more productive in Go than any of those other languages.

        > As an aside, I’d even go so far as to say that the main problem with C++ is not that it has so many features in number, but that its features interact with each other in unpredictable ways. Said another way, it’s not the number of nodes in the graph, but the number of edges and the manner of those edges.

        I think those problems are related. The more features you have, the more difficult it becomes to avoid strange, surprising interactions. It’s like a pharmacist working with a patient who is taking a whole cocktail of prescriptions; it becomes a combinatorial problem to avoid harmful reactions.

    • egl2020 2 days ago

      I've been writing go professionally for about ten years, and with go I regularly find myself saying "this is pretty boring", followed by "but that's a good thing" because I'm pretty sure that I won't do anything in a go program that would cause the other team members much trouble if I were to get run over by a bus or die of boredom.

      In contrast writing C++ feels like solving an endless series of puzzles, and there is a constant temptation to do Something Really Clever.

      • zimpenfish 2 days ago

        > I'm pretty sure that I won't do anything in a go program that would cause the other team members much trouble

        Alas there are plenty of people who do[0] - for some reason Go takes architecture astronaut brain and wacks it up to 11 and god help you if you have one or more of those on your team.

        [0] flashbacks to the interface calling an interface calling an interface calling an interface I dealt with last year - NONE OF WHICH WERE NEEDED because it was a bloody hardcoded value in the end.

        • roncesvalles a day ago

          My cardinal rule in Go is just don't use interfaces unless you really, really need to and there's no other way. If you're using interfaces you're probably up to no good and writing Java-ish code in Go. (usually the right reason to use interfaces is exportability)

          Yes, not even for testing. Use monkey-patching instead.

          • zimpenfish 12 hours ago

            > My cardinal rule in Go is just don't use interfaces unless you really, really need to and there's no other way.

            They do make some sense for swappable doodahs - like buffers / strings / filehandles you can write to - but those tend to be in the lower levels (libraries) rather than application code.

      • stackghost 2 days ago

        Go is okay. I don't hate it but I certainly don't love it.

        The packaging story is better than c++ or python but that's not saying much, the way it handles private repos is a colossal pain, and the fact that originally you had to have everything under one particular blessed directory and modules were an afterthought sure speaks volumes about the critical thinking (or lack thereof) that went into the design.

        Also I miss being able to use exceptions.

        • throwaway894345 2 days ago

          When Go was new, having better package management than Python and C++ was saying a lot. I’m sure Go wasn’t the first, but there weren’t many mainstream languages that didn’t make you learn some imperative DSL just to add dependencies.

          • stackghost 2 days ago

            Sure, but all those languages didn't have the psychotic design that mandated all your code lives under $GOPATH for the first several versions.

            I'm not saying it's awful, it's just a pretty mid language, is all.

            • tptacek 2 days ago

              That was a Plan9ism, I think. Java had something like it with CLASSPATH too, didn't it?

            • klooney 2 days ago

              I never understood the GOPATH freakout, coming from Python it seemed really natural- it's a mandatory virtualenv.

              • stackghost a day ago

                The fact that virtualenv exists at all should be viewed by the python community as a source of profound shame.

                The idea that it's natural and accepted that we just have python v3.11, 3.12, 3.13 etc all coexisting, each with their own incompatible package ecosystems, and in use on an ad-hoc, per-directory basis just seems fundamentally insane to me.

            • throwaway894345 2 days ago

              I picked up Go precisely in 2012 because $GOPATH (as bad as it was) was infinitely better than CMake, Gradle, Autotools, pip, etc. It was dead simple to do basic dependency management and get an executable binary out. In any other mainstream language on offer at the time, you had to learn an entire programming language just to script your meta build system before you could even begin writing code, and that build system programming language was often more complex than Go.

            • gp 2 days ago

              The language has changed a lot since then. Give it a fresh look sometime.

              • treis 2 days ago

                It's still pretty mid and still missing basic things like sets.

                But mid is not all that bad and Go has a compelling developer experience that's hard to beat. They just made some unfortunate choices at the beginning that will always hold it back.

    • treis 2 days ago

      The tradeoff with that language simplicity is that there's a whole lot of gotchas that come with Go. It makes things look simpler than they actually are.

    • kermatt 2 days ago

      > I'm convinced no more than a handful of humans understand all of C# or C++

      How would the proportion of humans that understand all of Rust compare?

      • Measter 2 days ago

        For Rust vs C++, I'd say it'll be much easier to have a complete understanding of Rust. C++ is an immensely complex language, with a lot of feature interactions.

        C# is actually fairly complex. I'm not sure if it's quite at the same level as Rust, but I wouldn't say it's that far behind in difficulty for complete understanding.

      • gf000 a day ago

        Rust managed to learn a lot from C++ and other languages' mistakes.

        So while it has quite a bit of essential complexity (inherent in the design space it operates: zero overhead low-level language with memory safety), I believe it fares overall better.

        Like no matter the design, a language wouldn't need 10 different kinds of initializer syntaxes, yet C++ has at least that many.

      • Santosh83 2 days ago

        For Rust I'd expect the implementation to be the real beast, versus the language itself. But not sure how it compares to C++ implementation complexity.

      • metaltyphoon 2 days ago

        Rust isn’t that complicated if you have some background in non GC languages.

        • j16sdiz 2 days ago

          Parent say _all_ of it, not a subset for everyday use.

          • estebank 2 days ago

            There's a different question too, that I think is more important (for any language): how much of the language do you need to know in order to use it effectively. As another poster mentioned, the issue with C++ might not be the breath of features, but rather how they interact in non-obvious ways.

    • morshu9001 2 days ago

      This is also what I like about JS, except it's even easier than Go. Meanwhile Python has a surprising number of random features.

      • alexjplant 2 days ago

        ECMAScript is an order of magnitude more complicated than Go by virtually every measure - length of language spec, ease of parsing, number of context-sensitive keywords and operators, etc.

        • ttoinou 2 days ago

          Yeah I’m pretty sure people who say JS is easy don’t know about its Prototype based OOP

          • morshu9001 2 days ago

            You don't have to know about it, but if you do, it's actually simpler than how other languages do OOP.

            • gf000 a day ago

              Not convinced. Especially with property flags.

      • legends2k 2 days ago

        Sorry, hard disagree. Try to understand what `this` means in JS in its entirety and you'll agree it's by no stretch of the imagination a simple language. It's more mind-bending and hence _The Good Parts_.

      • woodruffw 2 days ago

        I think JS is notoriously complicated: the phrase “the good parts” has broad recognition among programmers.

      • jchw 2 days ago

        Just so we're on the same page, this is the current JS spec:

        https://262.ecma-international.org/16.0/index.html

        I don't agree. (And frankly don't like using JS without at least TypeScript.)

        • goranmoomin 2 days ago

          While I might not think that JS is a good language (for some definition of a good language), to me the provided spec does feel pretty small, considering that it's a language that has to be specified to the dot and that the spec contains the standard library as well.

          It has some strange or weirdly specified features (ASI? HTML-like Comments?) and unusual features (prototype-based inheritance? a dynamically-bounded this?), but IMO it's a small language.

          • jchw a day ago

            Shrugging it off as just being large because it contains the "standard library" ignores that many JS language features necessarily use native objects like symbols or promises, which can't be entirely implemented in just JavaScript alone, so they are intrinsic rather than being standard library components, akin to Go builtins rather than the standard library. In fact, in actual environments, the browser and/or Node.JS provide the actual standard library, including things like fetch, sockets, compression codecs, etc. Even ignoring almost all of those bits though, the spec is absolutely enormous, because JavaScript has:

            - Regular expressions - not just in the "standard library" but in the syntax.

            - An entire module system with granular imports and exports

            - Three different ways to declare variables, two of which create temporal dead zones

            - Classes with inheritance, including private properties

            - Dynamic properties (getters and setters)

            - Exception handling

            - Two different types of closures/first class functions, with different binding rules

            - Async/await

            - Variable length "bigint" integers

            - Template strings

            - Tagged template literals

            - Sparse arrays

            - for in/for of/iterators

            - for await/async iterators

            - The with statement

            - Runtime reflection

            - Labeled statements

            - A lot of operators, including bitwise operators and two sets of equality operators with different semantics

            - Runtime code evaluation with eval/Function constructor

            And honestly it's only scratching the surface, especially of modern ECMAScript.

            A language spec is necessarily long. The JS language spec, though, is so catastrophically long that it is a bit hard to load on a low end machine or a mobile web browser. It's on another planet.

      • ajross 2 days ago

        The Javascript world hides its complexity outside the core language, though. JS itself isn't so weird (though as always see the "Wat?" video), but the incantations required to type and read the actual code are pretty wild.

        By the time you understand all of typescript, your templating environment of choice, and especially the increasingly arcane build complexity of the npm world, you've put in hours comparable to what you'd have spent learning C# or Java for sure (probably more). Still easier than C++ or Rust though.

        • xigoi 2 days ago

          …do you know you can just write JavaScript and run it in the browser? You don’t need TypeScript, NPM or build tools.

          • throwaway894345 2 days ago

            You do if you want more than one file, or if you want to use features that a user’s target browser may not support.

            • xigoi 2 days ago

              > You do if you want more than one file

              Modules were added in, like, 2016.

        • morshu9001 a day ago

          nodejs and npm are easy for beginners, especially compared to the Python packaging situation

    • jbreckmckye a day ago

      I learned Go this year, and this assertion just... isn't true? There are a bunch of subtleties and footguns, especially with concurrency.

      C++ is a basket case, it's not really a fair comparison.

      • nasretdinov a day ago

        As they (I) say, writing a concurrent Go program is easy, writing a correct one is a different story :)

    • throwaway894345 2 days ago

      I’ve been using Python since 2008, and I don’t feel like I understand very much of it at all, but after just a couple of years of using Go in a hobby capacity I felt I knew it very well.

  • throw1111221 2 days ago

    Well that's good, since Go was specifically designed for juniors.

    From Rob Pike himself: "It must be familiar, roughly C-like. Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical."

    However, the main design goal was to reduce build times at Google. This is why unused dependencies are a compile time error.

    https://go.dev/talks/2012/splash.article#TOC_6.

    • the_gipsy 2 days ago

      > This is why unused dependencies are a compile time error.

      https://go.dev/doc/faq?utm_source=chatgpt.com#unused_variabl...

      > There are two reasons for having no warnings. First, if it’s worth complaining about, it’s worth fixing in the code. (Conversely, if it’s not worth fixing, it’s not worth mentioning.) Second, having the compiler generate warnings encourages the implementation to warn about weak cases that can make compilation noisy, masking real errors that should be fixed.

      I believe this was a mistake (one that sadly Zig also follows). In practice there are too many things that wouldn't make sense being compiler errors, so you need to run a linter. When you need to comment out or remove some code temporarily, it won't even build, and then you have to remove a chain of unused vars/imports until it let's you, it's just annoying.

      Meanwhile, unlinted go programs are full of little bugs, e.g. unchecked errors or bugs in err-var misuse. If there only were warnings...

      • Mawr 2 days ago

        Yeah, but just going back to warnings would be a regression.

        I believe the correct approach is to offer two build modes: release and debug.

        Debug compiles super fast and allows unused variables etc, but the resulting binary runs super slowly, maybe with extra safety checks too, like the race detector.

        Release is the default, is strict and runs fast.

        That way you can mess about in development all you want, but need to clean up before releasing. It would also take the pressure off having release builds compile fast, allowing for more optimisation passes.

        • the_gipsy 2 days ago

          That doesn't make any sense, you'd still need to run the linters on release. Why bail out on "unused var" and not on actually harmful stuff.

        • dmoy 2 days ago

          > Debug compiles super fast and allows unused variables etc, but the resulting binary runs super slowly, maybe with extra safety checks too, like the race detector.

          At least in the golang / unused-vars at Google case, allowing unused vars is explicitly one of the things that makes compilation slower.

          In that case it's not "faster compilation as in less optimization". It's "faster compilation as in don't have to chase down and potentially compile more parts of a 5,000,000,000 line codebase because an unused var isn't bringing in a dependency that gets immediately dropped on the floor".

          So it's kinda an orthogonal concern.

          • Too 2 days ago

            Accidentally pulling in a unused dependency during development is, if not a purely hypothetical scenario, at least an extreme edge case. During debug, most of the times you already built those 5000000000 lines while trying to reproduce a problem on the original version of the code. Since that didn’t help, you now want to try commenting out one function call. Beep! Unused var.

          • Mawr a day ago

            Right, I meant that the binary should run slowly on purpose, so that people don't end up defaulting to just using the debug build. A nice way of doing so without just putting `sleep()`s everywhere would be to enable extra safety checks.

    • pa7ch 2 days ago

      I feel like people always take the designed for juniors thing the wrong way by implying that beneficial (to general software engineering) features or ideas were left out as a trade off to make the language easier to learn at the cost of what the language could be to a senior. I don't think the go designers see these as opposing trade offs.

      Whats good for the junior can be good for the senior. I think PL values have leaned a little too hard towards valuing complexity and abstract 'purity' while go was a break away from that that has proved successful but controversial.

    • ErroneousBosh a day ago

      > This is why unused dependencies are a compile time error.

      I think my favourite bit of Go opinionatedness is the code formatting.

      K&R or GTFO.

      Oh you don't like your opening bracket on the same line? Tough shit, syntax error.

      • benjiro a day ago

        But it also has a advantages that you can literally read a lot of code from other devs without twisting your eyes sideways because everybody has their own style.

        • ErroneousBosh 12 hours ago

          Exactly.

          "This is Go. You write it this way. Not that way. Write it this way and everyone can understand it."

          I wish I was better at writing Go, because I'm in the middle of writing a massive and complex project in Go with a lot of difficult network stuff. But you know what they say, if you want to eat a whole cow, you just have to pick and end and start eating.

          • benjiro 5 hours ago

            Yep ... its like people never read some of the main dev's motivations. The ability for people to be able to read each others code was a main point.

            I don't know but for me a lot of attacks on Go, often come from non-go developers, VERY often Rust devs. When i started Go, it was always Rust devs in /r/programming pushing their agenda as Rust being the next best thing, the whole "rewrite everything in Rust"...

            About 10 years ago, learned Rust and these days, i can barely read the code anymore with the tons of new syntax that got added. Its like they forgot the lessons from C++...

    • pkaye 2 days ago

      Doesn't Google use mostly C++?

      • throw1111221 2 days ago

        Just because it was a design goal doesn't mean it succeeded ;)

        From Russ Cox this time: "Q. What language do you think Go is trying to displace? ... One of the surprises for me has been the variety of languages that new Go programmers used to use. When we launched, we were trying to explain Go to C++ programmers, but many of the programmers Go has attracted have come from more dynamic languages like Python or Ruby."

        https://research.swtch.com/gotour

        • Measter 2 days ago

          It's interesting that I've also heard the same from people involved in Rust. Expecting more interest from C++ programmers and being surprised by the numbers of Ruby/Python programmers interested.

          I wonder if it's that Ruby/Python programmers were interested in using these kinds of languages but were being pushed away by C/C++.

          • estebank 2 days ago

            The people writing C++ either don't need much convincing to switch because they see the value or are unlikely to give it up anytime soon because they don't see anything Rust does as being useful to them, very little middle ground. People from higher level languages on the other hand see in Rust a way to break into a space that they would otherwise not attempt because it would take too long a time to reach proficiency. The hard part of Rust is trying to simultaneously have hard to misuse APIs and no additional performance penalty (however small). If you relax either of those goals (is it really a problem if you call that method through a v-table?), then Rust becomes much easier to write. I think GC Rust would already be a nice language to use that I'd love, like a less convoluted Scala, it just wouldn't have fit in a free square that ensured a niche for it to exist and grow, and would likely have died in the vine.

          • rcxdude 14 hours ago

            I think on average C++ programmers are more interested in Rust than in Go. But C programmers are on average probably not interested in either. I do agree that the accessible nature of the two languages (or at least perception thereof) compared to C and C++ is probably why there's more people coming from higher-level languages interested in the benefits of static typing and better performance.

      • dpe82 2 days ago

        It really depends on product area.

  • Someone 2 days ago

    > Which makes sense, it's got the smallest language spec of any of them

    I think go is fairly small, too, but “size of spec” is not always a good measure for that. Some specs are very tight, others fairly loose, and tightness makes specs larger (example: Swift’s language reference doesn’t even claim to define the full language. https://docs.swift.org/swift-book/documentation/the-swift-pr...: “The grammar described here is intended to help you understand the language in more detail, rather than to allow you to directly implement a parser or compiler.”)

    (Also, browsing golang’s spec, I think I spotted an error in https://go.dev/ref/spec#Integer_literals. The grammar says:

      decimal_lit    = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] . 
    
    Given that, how can 0600 and 0_600 be valid integer literals in the examples?)
    • mseepgood 2 days ago

      You're looking at the wrong production. They are octal literals:

          octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .
      • Someone a day ago

        Thanks! Never considered that a 21st century language designed for “power of two bits per word” hardware would keep that feature from the 1970s, so I never looked at that production.

        Are there other modern languages that still have that?

    • neild 2 days ago

      0600 and 0_600 are octal literals:

          octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .
      • j-scott 2 days ago

        Never mind, I was wrong. Here’s a playground showing how go parses each one: https://go.dev/play/p/hyWPkL_9C5W

        • mseepgood 2 days ago

          > Octals must start with zero and then o/O literals.

          No, the o/O is optional (hence in square brackets), only the leading zero is required. All of these are valid octal literals in Go:

          0600 (zero six zero zero)

          0_600 (zero underscore six zero zero)

          0o600 (zero lower-case-letter-o six zero zero)

          0O600 (zero upper-case-letter-o six zero zero)

          • j-scott 2 days ago

            My bad! I was wrong; added a playground demonstration the parsing behavior above.

  • zer00eyz 2 days ago

    I write a lot of Go, a bit of Rust, and Zig is slowly creeping in.

    To add to the above comment, a lot of what Go does encourages readability... Yes it feels pedantic at moments (error handling), but those cultural, and stylistic elements that seem painful to write make reading better.

    Portable binaries are a blessing, fast compile times, and the choices made around 3rd party libraries and vendoring are all just icing on the cake.

    That 80 percent feeling is more than just the language, as written, its all the things that come along with it...

    • gf000 a day ago

      Error handling is objectively terrible in Go and the explicitness of the always repeating pattern just makes humans pay less attention to potentially problematic lines and otherwise increases the noise to signal ratio.

    • cwbriscoe 2 days ago

      Error handling isn't even a pain to write any more with AI autocomplete which gets it right 95%+ of the time in my experience.

      • zer00eyz 2 days ago

        You're not wrong but... there is a large contingent of the Go community that has a rather strong reaction to AI/ML/LLM generated code at any level.

        I keep using the analogy, that the tools are just nail guns for office workers but some people remain sticks in the mud.

        • bccdee 2 days ago

          Nail guns are great because they're instant and consistent. You point, you shoot, and you've unimpeachably bonded two bits of wood.

          For non-trivial tasks, AI is neither of those. Anything you do with AI needs to be carefully reviewed to correct hallucinations and incorporate it into your mental model of the codebase. You point, you shoot, and that's just the first 10-20% of the effort you need to move past this piece of code. Some people like this tradeoff, and fair enough, but that's nothing like a nailgun.

          For trivial tasks, AI is barely worth the effort of prompting. If I really hated typing `if err != nil { return nil, fmt.Errorf("doing x: %w", err) }` so much, I'd make it an editor snippet or macro.

          • zer00eyz 2 days ago

            > Nail guns are great because they're instant and consistent. You point, you shoot, and you've unimpeachably bonded two bits of wood.

            You missed it.

            If I give a random person off the street a nail gun, circular saw and a stack of wood are they going to do a better job building something than a carpenter with a hammer and hand saw?

            > Anything you do with AI needs to be carefully reviewed

            Yes, and so does a JR engineer, so do your peers, so do you. Are you not doing code reviews?

            • bccdee a day ago

              > If I give a random person off the street a nail gun, circular saw and a stack of wood

              If this is meant to be an analogy for AI, it doesn't make sense. We've seen what happens when random people off the street try to vibe-code applications. They consistently get hacked.

              > Yes, and so does a JR engineer

              Any junior dev who consistently wrote code like an AI model and did not improve with feedback would get fired.

            • kgwxd a day ago

              You are responsible for the AI code you check in. It's your reputation on the line. If people felt the need to assume that much responsibility for all code they review, they'd insist on writing it themselves instead.

        • 9rx 2 days ago

          > there is a large contingent of the Go community that has a rather strong reaction to AI/ML/LLM generated code at any level.

          This Go community that you speak of isn't bothered by writing the boilerplate themselves in the first place, though. For everyone else the LLMs provide.

  • tptacek 2 days ago

    I don't understand the framing you have here, of Rust being an asymptote of language capability. It isn't. It's its own set of tradeoffs. In 2025, it would not make much sense to write a browser in Go. But there are a lot of network services it doesn't really make sense to write in Rust: you give up a lot (colored functions, the borrow checker) to avoid GC and goroutines.

    Rust is great. One of the stupidest things in modern programming practice is the slapfight between these two language communities.

  • throw-the-towel 2 days ago

    Unfortunately, it's the remaining 20% of Rust features that provide 80% of its usefulness.

  • morshu9001 2 days ago

    Language can be bottleneck if there's something huge missing from it that you need, like how many of them didn't have first class support for cooperative multitasking, or maybe you need it to be compiled, or not compiled, or GC vs no GC. Go started out with solid greenthreading, while afaik no major lang/runtime had something comparable at the time (Java now does supposedly).

    The thing people tend to overvalue is the little syntax differences, like how Scala wanted to be a nicer Java, or even ObjC vs Swift before the latter got async/await.

    • ezst 2 days ago

      I'll be the one to nickpick, but Scala never intended to be a nicer Java. It was and still is an academic exercise in compiler and language theory. Also, judging by Kotlin's decent strides, "little Syntex differences" get you a long way on a competent VM/Runtime/stdlib.

      • morshu9001 2 days ago

        Kotlin's important feature is the cooperative multitasking. Java code has been mangled all these years to work around not having that. I don't think many would justify the switch to Kotlin otherwise.

        • ezst 21 hours ago

          It's probably an important feature now, but it's a recent one in this context.

          • morshu9001 6 hours ago

            Oh true, I thought it was older

  • throwaway894345 2 days ago

    Similar story for me. I was looking for a language that just got out of the way. That didn’t require me to learn a full imparable DSL just to add a few dependencies and which could easily produce some artifact that I could share around without needing to make sure the target machine had all the right dependencies installed.

  • baby 2 days ago

    It really is a lovely language and ecosystem of tools, I think it does show its limitations fairly quickly when you want to build something a bit complex though. Really wish they would have added sumtypes

  • Thorrez 2 days ago

    Go is getting more complex over time though. E.g. generics.

  • osigurdson 2 days ago

    >> I'm sure there are plenty of reasons this is wrong, but it feels like Go gets me 80% of the way to Rust with 20% of the effort.

    By 20% of the effort, do you mean learning curve or productivity?

  • benjiro a day ago

    Funny thing is that also makes it easier on LLM / AI... Tried a project a while ago both creating the same thing in Rust and Go. Go's worked from the start, while Rust's version needed a lot of LLM interventions and fixes to get it to compile.

    We shall not talk about compile time / resource usage differences ;)

    I mean, Rust is nice, but compared to when i learned it like 10 years ago, it really looks a lot more these days, like it took too much of a que from C++.

    While Go syntax is still the same as it was 10 years ago with barely anything new. What may anger people but even so...

    The only thing i love to see is reduce executable sizes because pushing large executables on a dinky upload line, to remove testing is not fun.

  • tialaramex 2 days ago

    > I'm sure there are plenty of reasons this is wrong, but it feels like Go gets me 80% of the way to Rust with 20% of the effort.

    I don't see it. Can you say what 80% you feel like you're getting?

    The type system doesn't feel anything alike, I guess the syntax is alike in the sense that Go is a semi-colon language and Rust though actually basically an ML deliberately dresses as a semi-colon language but otherwise not really. They're both relatively modern, so you get decent tooling out of the box.

    But this feels a bit like if somebody told me that this new pizza restaurant does a cheese pizza that's 80% similar to the Duck Ho Fun from that little place near the extremely tacky student bar. Duck Ho Fun doesn't have nothing in common with cheese pizza, they're both best (in my opinion) if cooked very quickly with high heat - but there's not a lot of commonality.

    • klodolph 2 days ago

      > I don't see it. Can you say what 80% you feel like you're getting?

      I read it as “80% of the way to Rust levels of reliability and performance.” That doesn’t mean that the type system or syntax is at all similar, but that you get some of the same benefits.

      I might say that, “C gets you 80% of the way to assembly with 20% of the effort.” From context, you could make a reasonable guess that I’m talking about performance.

      • Xeoncross 2 days ago

        Yes, for me I've always pushed the limits of what kinds of memory and cpu usage I can get out of languages. NLP, text conversion, video encoding, image rendering, etc...

        Rust beats Go in performance.. but nothing like how far behind Java, C#, or scripting languages (python, ruby, typescript, etc..) are from all the work I've done with them. I get most of the performance of Rust with very little effort a fully contained stdlib/test suite/package manger/formatter/etc.. with Go.

        • echelon 2 days ago

          Rust is the most defect free language I have ever had the pleasure of working with. It's a language where you can almost be certain that if it compiles and if you wrote tests, you'll have no runtime bugs.

          I can only think of two production bugs I've written in Rust this year. Minor bugs. And I write a lot of Rust.

          The language has very intentional design around error handling: Result<T,E>, Option<T>, match, if let, functional predicates, mapping, `?`, etc.

          Go, on the other hand, has nil and extremely exhausting boilerplate error checking.

          Honestly, Go has been one of my worst languages outside of Python, Ruby, and JavaScript for error introduction. It's a total pain in the ass to handle errors and exceptional behavior. And this leads to making mistakes and stupid gotchas.

          I'm so glad newer languages are picking up on and copying Rust's design choices from day one. It's a godsend to be done with null and exceptions.

          I really want a fast, memory managed, statically typed scripting language somewhere between Rust and Go that's fast to compile like Go, but designed in a safe way like Rust. I need it for my smaller tasks and scripting. Swift is kind of nice, but it's too Apple centric and hard to use outside of Apple platforms.

          I'm honestly totally content to keep using Rust in a wife variety of problem domains. It's an S-tier language.

          • gf000 a day ago

            > I really want a fast, memory managed, statically typed scripting language somewhere between Rust and Go that's fast to compile like Go, but designed in a safe way like Rust

            OCaml is pretty much that, with a very direct relationship with Rust, so it will even feel familiar.

          • Xeoncross 2 days ago

            I agree with a lot of what you said. I'm hoping Rust will warm on me as I improve in it. I hate nil/null.

            > Go... extremely exhausting boilerplate error checking

            This actually isn't correct. That's because Go is the only language that makes you think about errors at every step. If you just ignored them and passed them up like exceptions or maybe you're basically just exchanging handling errors for assuming the whole thing pass/fail.

            If you you write actual error checking like Go in Rust (or Java, or any other language) then Go is often less noisy.

            It's just two very different approaches to error handling that the dev community is split on. Here's a pretty good explanation from a rust dev: https://www.youtube.com/watch?v=YZhwOWvoR3I

            • dontlaugh 2 days ago

              It’s very common in Go to just pass the error on since there’s no way to handle it in that layer.

              Rust forces you to think about errors exactly as much, but in the common case of passing it on it’s more ergonomic.

        • vips7L 2 days ago

          Go is in the same performance profile as Java and C#. There are tons of benchmarks that support this.

          • Xeoncross 2 days ago

            1) for one-off scripts and 2) If you ignore memory.

            You can make about anything faster if you provide more memory to store data in more optimized formats. That doesn't make them faster.

            Part of the problem is that Java in the real world requires an unreasonable number of classes and 3rd party libraries. Even for basic stuff like JSON marshaling. The Java stdlib is just not very useful.

            Between these two points, all my production Java systems easily use 8x more memory and still barely match the performance of my Go systems.

            • vips7L a day ago

              I genuinely can’t think of anything the Java standard library is missing, apart from a json parser which is being added.

              It’s your preference to prefer one over the other, I prefer Java’s standard library because atleast it has a generic Set data structure in it and C#’s standard library does have a JSON parser.

              I don’t think discussions about what is in the standard library really refutes anything about Go being within the same performance profile though.

            • deagle50 18 hours ago

              ZGC? It should be on par or better than Go.

              • vips7L 5 hours ago

                Java’s collectors vastly outperform Go’s. Look at the Debian binary tree benchmarks [0]. Go just uses less memory because it’s AOT compiled from the start and Java’s strategy up until recently is to never return memory to the OS. Java programs are typically on servers where it’s the only application running.

                [0] https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

            • gf000 a day ago

              Memory is the most common tradeoff engineers make for better performance. You can trivially do so yourself with java, feel free to cut down the heap size and Java's GC will happily chug along 10-100 times as often without a second thought, they are beasts. The important metric is that Java's GC will be able to keep up with most workloads, and it won't needlessly block user threads from doing their work. Also, not running the GC as often makes Java use surprisingly small amounts of energy.

              As for the stdlib, Go's is certainly impressive but come on, I wouldn't even say that in general case Java's standard library is smaller. It just so happens that Go was developed with the web in mind almost exclusively, while Java has a wider scope. Nonetheless, the Java standard library is certainly among the bests in richness.

    • NoboruWataya 2 days ago

      I guess the 80% would be a reasonably performant compiled binary with easily managed dependencies? And the extra 20% would be the additional performance and peace of mind provided by the strictness of the Rust compiler.

    • password4321 2 days ago

      Single binary deployment was a big deal when Go was young; that might be worth a few percent. Also: automatically avoiding entire categories of potential vulnerabilities due to language-level design choices and features. Not compile times though ;)

    • kace91 2 days ago

      Wild guess but, with the current JS/python dominance, maybe it’s just the benefits of a (modern) compiled language.

liampulles 2 days ago

I love Go. One thing I haven't seen noted here is how great it is for use in monorepos. Adding a new application is just a matter of making a folder and putting a main packaged go file with a main() func. Running go install at the root ./.. takes care of compiling everything quickly and easily.

This combined with the ease of building CLI programs has been an absolute godsend in the past when I've had to quickly spin up CLI tools which use business logic code to fix things.

  • liveoneggs 2 days ago

    I don't understand how this isn't also true for practically every other language?

    • dlisboa a day ago

      It just isn't. There's nothing stopping other languages from being that easy but very few even try.

      Go sees itself more as a total dev environment than just a language. There's integrated build tooling, package management, toolchain management, mono repo tools, testing, fuzzing, coverage, documentation, formatting, code analysis tools, performance tools...everything integrated in a single binary and it doesn't feel bloated at all.

      You see a lot of modern runtimes and languages have learned from Go. Deno, Bun and even Rust took a lot of their cues from Go. It's understood now that you need a lot more than just a compiler/runtime to be useful. In languages that don't have that kind of tooling the community is trying to make them more Go-like, for example `uv` for Python.

      Getting started in a Go project is ridiculously easy because of that integrated approach.

      • liveoneggs a day ago

        I personally like Go and appreciate its simplicity and tooling and everything but the example given is "making a folder" and "putting a ... main() func" in it. But, like, this is exactly as easy with every single other language that I can think of.

        The second part "Running go install at the root ./.." is actually terrible and risky but, still, trivial with make (a - literally - 50 year old program) or shell or just whatever.

        I get that the feelz are nice and all (just go $subcmd) but.. come on.

        • sacado2 12 hours ago

          > "making a folder" and "putting a ... main() func" in it

          You can't do that with python for instance. First, you need a python interpreter on the target machine, and on top of that you need the correct version of the interpreter. If yours is too old or not old enough, things might break. And then, you need to install all the dependencies. The correct version of each, as well. And they might not exist on your system, or conflict with some other lib you have on your target machine.

          Same problem with any other interpreted language, including Java and C# obviously.

          C/C++ dependency management is a nightmare too.

          Rust is slightly better, but there was no production-ready rust 16 years ago (or even 10 years ago).

        • Merovius a day ago

          > But, like, this is exactly as easy with every single other language that I can think of.

          I mean, not exactly. Rust (or rather Cargo) requires you to declare binaries in your Cargo.toml, for example. It also, AIUI, requires a specific source layout - binaries need to be named `main.rs` or be in `src/bin`. It's a lot more ceremony and it has actively annoyed me whenever I tried out Rust.

          > The second part "Running go install at the root ./.." is actually terrible and risky but, still, trivial with make (a - literally - 50 year old program) or shell or just whatever.

          Again, no, it is not trivial. Using make requires you to write a Makefile. Using shell requires you to write a shell script.

          I'm not saying any of this is prohibitive - or even that they should convince anyone to use Go - but it is just not true to say that other languages make this just as easy as Go.

          • steveklabnik 16 hours ago

            > declare binaries in your Cargo.toml, for example. It also, AIUI, requires a specific source layout - binaries need to be named `main.rs` or be in `src/bin`.

            It does not. Those are the defaults. You can configure something else if you wish. Most people just don’t bother, because there’s not really advantages to breaking with default locations 99% of the time.

          • nasretdinov a day ago

            I think one other major part is that, compared to e.g. make the build process is more-or-less the same for all Go projects. There is some variation, and some (newcomers I want to think) still like to wrap go commands into Makefile, but it's still generally very easy to understand and very uniform across different Go projects

    • wredcoll a day ago

      The distinction, I believe, is between "possible" and "easy". Go makes a lot of very specific things easy via some of its design choices with language and tooling.

      As a counter example, it seems like e.g. c++ is mostly concerned about making things possible and rarely about easy.

    • vlovich123 2 days ago

      It’s not true of C/C++ which need changes to the build system. Also true for rust workspaces which is how I’d recommend structuring monorepos although it is generally easy (you just need to add a small cargo.toml file) or you can not use a workspace but you still need to declare the binary if I recall correctly.

      • o11c a day ago

        It's true for any C/C++ project which bothers to write 10 lines of GNU `make` code.

        The problem is that many projects still pander to inferior 1980s-era `make` implementations, and as such rely heavily on the abominations that are autotools and cmake.

        • LexiMax a day ago

          Autotools is far too pessimistic, but there are still considerable differences between different compiling environments. Tooling like CMake will always be necessary unless you are only targeting unix and your dependency graph isn't terribly deep.

          Even in that specific niche I find using a programmatically generated ninja file to be a far superior experience to GNU make.

        • bborud a day ago

          This is the theory, yes. And then reality comes bursting through the door and you are confronted with the awfulness that is the C/++ toolchain. Starting with multi-OS, multi-architecture builds, and then plunging into the cesspit that is managing third party dependencies.

          Let’s be real. C/++ has nothing even approaching a sane way to do builds. It is just degrees from slightly annoying to full on dumpster fire.

        • duskwuff a day ago

          C/C++ library dependencies are a thing, and there's no universal solution to acquiring and installing them.

          • bayindirh a day ago

            The most universal thing in C/C++ is vendoring, IMHO.

            If you are distributing source, you distribute everything. Then, it only needs a compiler and libc. That vendored package is tested, and it works on your platform, so there's no guesswork.

            • duskwuff 10 hours ago

              That might work for small, self-contained dependencies in projects which aren't themselves libraries. But good luck vendoring your deps when one of those deps is something really large like Qt or WebKit, or if you're building a library that other applications need to be able to link against.

            • allovertheworld 21 hours ago

              Not really since those vendored libraries would have their own dependencies as well

      • super_flanker a day ago

        No, you don't. All you need is to create a folder `bin` and any file with `main` fn in it will create a binary.

    • malkia a day ago

      With bazel/buck/pants/etc won't be problem for other major languages.

      • ricardobeat a day ago

        Have you worked with those before? "Quickly and easily" are not exactly what comes to mind.

        • malkia 5 hours ago

          Yes, at Google, roughtly 10 years ago - great experience. Recently with my own small projects, and on Windows (where it lacks the same charm... yet - but eventually!)

          But yes, I worked - mainly Java (back then) with GWT, some Python, Sawzall, R, some other internal langs.

  • linhns 2 days ago

    Agreed. This use case is not mentioned enough.

ashishb 2 days ago

Contributing to a new Go codebase is easy.

The Go codebases look all alike. Not only the language has really few primitives but also the code conventions enforced by standard library, gofmt, and golangci-lint implies that the structure of code bases are very similar.

Many language communities can't even agree on the build tooling.

  • reppap a day ago

    I like that I can understand a Go file without deciphering 15 layers of macros.

  • trenchpilgrim 2 days ago

    I'm still trying to convince the scientists I work with that they should format their code or use linters. Making them mandatory in Go was a good decision.

    • ashishb 2 days ago

      > I'm still trying to convince the scientists I work with that they should format their code or use linters.

      Consider adding a pre-commit hook if you are allowed to.

      • trenchpilgrim 2 days ago

        My group's repos enforce strict rules, theirs does not.

        • millerm 2 days ago

          Yeah, I've been there. I would get passed down horribly formatted code from another repo and it showed the data scientists writing it barely knew what they were doing. It was their repo, we couldn't do anything about it. They wouldn't reformat the code, because they were afraid it would break. They also passed us a lot of Python, and you can see where they got this fear from.

  • stOneskull 2 days ago

    i've just started learning Go and i really like this aspect. one way to do things, one way to format.. the % operator is a bit confusing for a negative number - that took me down a little rabbit-hole, learning about how a remainder can be different to how i normally think about it.

tmoertel 2 days ago

The introduction of automatic code modernizers to keep legacy code up to date with modern Go idioms is interesting:

> With gopls v0.18.0, we began exploring automatic code modernizers. As Go evolves, every release brings new capabilities and new idioms; new and better ways to do things that Go programmers have been finding other ways to do. Go stands by its compatibility promise—the old way will continue to work in perpetuity—but nevertheless this creates a bifurcation between old idioms and new idioms. Modernizers are static analysis tools that recognize old idioms and suggest faster, more readable, more secure, more modern replacements, and do so with push-button reliability. What gofmt did for stylistic consistency, we hope modernizers can do for idiomatic consistency.

Modernizers seem like a way make Large-Scale Changes (LSCs) more available to the masses. Google has internal tooling to support them [1], but now Go users get a limited form of opt-in LSC support whenever modernizers make a suggestion.

[1] https://abseil.io/resources/swe-book/html/ch22.html

tschellenbach 2 days ago

10 week onboarding program we use here for go backend devs: https://www.reddit.com/r/golang/comments/1eiea6q/10_week_pla...

go is amazing. switches from python to go 7 years ago. It's the reason our startup did well

  • zerr 2 days ago

    One thing I don't like when it comes to Golang jobs - it is rare to see pure software engineering positions. For some reason, most Go jobs requirements include AWS, Kubernetes/Docker, CI/CD setup, etc... DevOps stuff, which is not the case for positions in other stacks.

    • millerm 2 days ago

      I haven't been able to find a job anywhere, using any language, that didn't require all that stuff these days. I wish I could go back to pure development, but now we all get this entire infra-crap thrown at us too. Which then means... you support the environments, the runtime, and the code. It's a 24/7 world and I don't care for it anymore.

      • arccy a day ago

        it's alignment of incentives.

        nowadays devs are less inclined to pump out crappy code that ends up with some ops guy having to wake up in the middle of the night

tail_exchange 2 days ago

I was very skeptical of Go when I started learning it, but it quickly became my favourite language. I like how simple but powerful it is.

If I had a magic wand, the only things I would add is better nulability checks, add stack traces by default for errors, and exhaustive checks for sum types. Other than that, it does everything I want.

weakfish 2 days ago

I like Go. Coming from Python, I appreciate having most things be explicit in nature vs. magical, and having concurrency not feel like a bolted on nightmare.

Writing microservices at $DAYJOB feels far easier and less guess-work, even if it requires more upfront code, because it’s clear what each piece does and why.

  • jsight 2 days ago

    I've finally gotten around to learning Go this year and I'm having a pretty similar experience.

    It really feels like a simpler language and ecosystem compared to Python. On top of that, it performs much better!

MichaelNolan 2 days ago

Go would probably be my favorite language if it just had a few more features around functional programming. Specifically around immutability and nullness, and maybe exhaustive switch statements. Then it just might be perfect.

At work we use Uber’s NillAway, so that helps bit. https://github.com/uber-go/nilaway Though actually having the type system handle it would be nicer.

  • kellpossible2 2 days ago

    Go with Sum types and no nil pointers would be fantastic! Is it too much to dream of? It feels like Gleam gets pretty close but it flies off in a bunch of other directions.

srameshc 2 days ago

Go is my favorite programming language. I remember when I first found Go and it was because I was using Java back then and learnign Akka framework for concurrent programming . I realized Go was so much less code compared to Java and I could understand it effortlessly. Since then I have been using it very regularly but still I don't feel I am good at this language. But it helps me get the work done. Cheers to the 16th anniversary of Go.

rollulus 2 days ago

I love Go. It makes that I get shit done. I picked up Go more than ten years ago, because it was HN’s darling and when I didn’t know about hype cycles. No regrets.

threemux 2 days ago

I use Go every day at work and it's still the first thing I reach for when completing personal projects. It gets better every year. Keep up the good work Go team!

bobjordan 2 days ago

I tried to use go in a project 6-7 years ago and was kind of shocked by needing to fetch packages directly from source control with a real absence of built in versioning. That turned me off and I went back to python. I gather that now there’s a new system with go modules. I should probably revisit it.

zmj 2 days ago

I'm glad Go exists. If nothing else, it cemented that tooling is at least as important as the language.

tapirl 2 days ago

> Go stands by its compatibility promise—the old way will continue to work in perpetuity ...

It is so weird that they still claim this after they have made the the semantic change for 3-clause for-loop in Go 1.22.

When a Go module is upgraded from 1.21- to 1.22+, there are some potential breaking cases which are hard to detect in time. https://go101.org/blog/2024-03-01-for-loop-semantic-changes-...

Go toolchain 1.22 broke compatibility for sure. Even the core team admit it. https://go101.org/bugs/go-build-directive-not-work.html

  • 0x696C6961 a day ago

    The new toolchain continues to compile old code using the old semantics. Only modules which specify Go 1.22 in go.mod have the new bahivour.

    • tapirl a day ago

      The problem is, when you modified the go version in go.mod, the behaviors of some code change, but the change is not easy to detect in time. Go team never plan to develop a tool to identify/detect code affected by such breaking changes, leaving developers without guarantees for safe migration.

      And when running go scripts without go.mod files, the v1.22 toolchain doesn't respect the "//go:build go1.xx" directives: https://go101.org/bugs/go-build-directive-not-work.html

      And consider that some people run go scripts even without the "//go:build go1.xx" directives ... (Please don't refute me. The Go toolchain allows this and never warns on this.)

  • gf000 a day ago

    It's especially funny considering that this issue has been known from lisps for 50+ years..

    • tapirl a day ago

      They can fix the issue by just changing the semantics of "for-range" loops, almost no negative effects. But they also applied the change to 3-clause-for loops, which causes many problems, some of which have been pointed out before the change was made. So the rookie mistake is totally caused by arrogance.

culebron21 2 days ago

To me, Go is like Rust oversimplified beyond reason. It edits your code when you don't ask, removing things you just started; it lacks iterators -- every time you must write a big cycle instead. It lacks simple things like check if a key exists in a map.

Proponents say it has nothing under the hood. I see under-the-hood-magic happen every time.

1) The arrays append is one example. Try removing an element from an array - you must rely on some magic and awkward syntax, and there's no clear explanation what actually happens under the hood (all docs just show you that a slice is a pointer to a piece of vector).

2) enums creation is just nonsense

3) To make matters worse, at work we have a linter that forbids merging a branch if you a) don't do if err != nil for every case b) have >20 for & if/else clauses. This makes you split functions in many pieces, turning your code into enterprise Java.

It feels like, to implement same things, Go is 2x slower than in Rust.

On the positive side,

* interfaces are simpler, without some stricter Rust's limitations; the only problem with them is that in the using code, you can't tell one from a struct

* it's really fast to pick up, I needed just couple of days to see examples and start coding stuff.

I think Go would have been great with

* proper enums (I'll be fine if they have no wrapped data)

* sensible arrays & slices, without any magic and awkward syntax

* iterators

* result unwrapping shorthands

  • jiehong a day ago

    One thing Go took from C that I dislike: overly short variable names (like in interface names when implementing function are usually 1 or 2 letters, but also chan!).

    Other random things I hate:

    - first element in a struct, if unnamed, acts like extending a struct;

    - private/public fields of method based on capitalisation (it makes json mapping to a struct have so much boilerplate);

    - default json lib being so inept with collections: an empty slice is serialised as null/absent (empty list is not absence of a list, WTF, but the new json lib promises to fix that json crap);

    - error type being special, and not working well with chanels;

    - lambda syntax is verbose;

    - panics (especially the ones in libs);

    - using internal proxy in companies for packages download is very fiddly, and sucks.

    But, the tooling is pretty good and fast, I won’t lie. The language won’t win beauty contests for sure, but it mostly does the job. Still weak at building http servers (limited http server libs with good default headers, very limited openapi spec support).

  • alain_gilbert 2 days ago

    I worked on a toy programming language (that compile down to golang), which is a fork of the go lexer/parser, but it changes how functions can only return one value allowing the use of Result[T]/Option[T] and error propagation operators `!` and `?`.

    It has enums (sum type), tuple, built-in Set[T], and good Iterator methods. It has very nice type inferred lambda function (heavily inspired by the swift syntax)... lots of good stuff!

    https://github.com/alaingilbert/agl

  • Mawr 2 days ago

    > it lacks iterators -- every time you must write a big cycle instead

    It has iterators - https://pkg.go.dev/iter.

    > It lacks simple things like check if a key exists in a map.

    What? `value, keyExists := myMap[someKey]`

    > Try removing an element from an array - you must rely on some magic and awkward syntax, and there's no clear explanation what actually happens under the hood (all docs just show you that a slice is a pointer to a piece of vector).

    First of all, if you're removing elements from the middle of an array, you're using the wrong data structure 99% of the time. If you're doing that in a loop, you're hitting degenerate performance.

    Second, https://pkg.go.dev/slices#Delete

    • culebron21 2 days ago

      > `value, keyExists := myMap[someKey]`

      If I don't need the value, I have to do awkward tricks with this construct. like `if _, key_exists := my_may[key]; key_exists { ... }`.

      Also, you can do `value := myMap[someKey]`, and it will just return a value or nil.

      Also, if the map has arrays as elements, it will magically create one, like Python's defaultdict.

      This construct (assigning from map subscript) is pure magic, despite all the claims, that there's none in Golang.

      ...And also: I guess the idea was to make the language minimal and easy to learn, hence primitives have no methods on them. But... after all OOP in limited form is there in Golang, exactly like in Rust. And I don't see the point why custom structs do have methods, and it's easier to use, but basic ones don't, and you have to go import packages.

      Not that it's wrong. But it's not easier at all, and learning curve just moves to another place.

      • lenkite 2 days ago

        > Also, if the map has arrays as elements, it will magically create one, like Python's defaultdict.

        Err, no Go doesn't do that. No insertion happens unless you explicitly assign to the key.

        • culebron21 2 days ago

          You're right. But it will return something: https://go.dev/play/p/Cz6aeGpURgo

            my_map := make(map[int32][]int64)
            val := my_map[123]
            val = append(val, 456)
            my_map[123] = val
            fmt.Println(my_map)
          
          prints `map[123:[456]]`

          I guess it's convenient compared to Rust's strict approach with entry API. But also, what I found is that golang's subscript returns nil in one case: if the value type is a nested map.

            my_map := make(map[int32]map[int32]int64)
            val := my_map[123]
            val[456] = 789
            my_map[123] = val
            fmt.Println(my_map)
          
          output:

            panic: assignment to entry in nil map
          • HL33tibCe7 2 days ago

            It returns the zero value for all types, including arrays (which is nil).

            nil is equivalent to the empty array, which is why the rest of the code works as it does.

      • ricardobeat a day ago

        _ is idiomatic and not an awkward trick. It keeps signatures consistent even when you don't need the value.

      • zimpenfish 2 days ago

        > Also, you can do `value := myMap[someKey]`, and it will just return a value or nil.

        It might if your map is a `map[typeA]*typeB` but it definitely won't return a `nil` if your map is anything like `map[typeA]typeC` (where `typeC` is non-nillable; i.e. int, float, string, bool, rune, byte, time.Time, etc.) - you'll get a compile error: "mismatched types typeC and untyped nil".

      • HL33tibCe7 2 days ago

        > But it's not easier at all, and learning curve just moves to another place.

        Hard disagree. Go has its sharp corners, but they don’t even approach the complexity of the borrow checker of Rust alone, let alone all of the other complexity of the Rust ecosystem.

  • jmaker 21 hours ago

    I used to do Go in production for several years, along with Java and TypeScript event-loop backends. It was a breeze of fresh air, especially for new projects, where the Java conventions could be put to rest. But in such an environment, with mostly Java legacy, people did tend to bend Go to the Java idioms rendering the PR reviews very cumbersome.

    From what I’ve experienced, if you need any fine-grained control over your data or allocations, precision on the type level, expressing nontrivial algorithms, Go is just too clumsy.

    The more I read about how people use Go today and what issues people still have, the more I’m happy I picked Rust for almost everything. I even find it much more productive to write scripts in Rust than in Python or shell script. You just get it right very quickly and you don’t need to care about the idiosyncrasies of ancient tech debt that would otherwise creep into your new projects. And of course the outcome is way more maintainable.

    Not saying that Rust hadn’t had its own warts, but most of them are made explicit. This is perhaps what I appreciate the most.

    Intuitively, however, I still notice myself creating a new Python or shell script file when I need something quick, but then something doesn’t really work well the moment the logic gets a bit more complex, and I need to backtrack and refactor. With Rust, this hasn’t been an issue in my experience.

    And intuitively, I still tend to think in Java terms when designing. It’s funny how it sticks for so long. And when writing some Java, I miss Go’s use-site interfaces and TypeScript’s structural typing, while I miss nominal typing in TypeScript. It’s just maybe that you get used to workarounds and idiosyncrasies in some system and then carry them over to another paradigms.

    I do like Go’s value propositions, and lots of its warts have been sorted out, but I’m just not as productive in it for my use cases as I am with Rust. It just checks way more boxes with me.

  • Zababa 2 days ago

    Go has iterators, had them for a while now. To delete an element from a slice you can use `slices.Delete`.

    >3) To make matters worse, at work we have a linter that forbids merging a branch if you a) don't do if err != nil for every case b) have >20 for & if/else clauses. This makes you split functions in many pieces, turning your code into enterprise Java.

    That is not a problem with Go.

  • lenkite 2 days ago

    > This makes you split functions in many pieces, turning your code into enterprise Java.

    Umm..in Java you won't have to split functions here. Maybe you should study some modern Java ?

    • culebron21 a day ago

      I didn't mean that in Java you must split functions. I meant that code becomes a lot of functions with seemingly English names, but it's obscure what is happening.

      p.s. upvoted, because some mob came and downvoted those who replied to me.

  • 9rx 2 days ago

    > proper enums

    It has proper enums. Granted, it lacks an enum keyword, which seems to trip up many.

    Perhaps what you are actually looking for is sum types? Given that you mentioned Rust, which weirdly[1] uses the enum keyword for sum types, this seems likely. Go does indeed lack that. Sum types are not enums, though.

    > sensible arrays & slices, without any magic and awkward syntax

    Its arrays and slices are exactly the same as how you would find it in C. So it is true that confuses many coming from languages that wrap them in incredible amounts of magic, but the issue you point to here is actually a lack of magic. Any improvements to help those who are accustomed to magic would require adding magic, not taking it away.

    > iterators

    Is there something about them that you find lacking? They don't seem really any different than iterators in other languages that I can see, although I'll grant you that the anonymous function pattern is a bit unconventional. It is fine, though.

    > result unwrapping shorthands

    Go wants to add this, and has been trying to for years, but nobody has explained how to do it sensibly. There are all kinds of surface solutions that get 50% of the way there, but nobody wants to tackle the other 50%. You can't force someone to roll up their sleeves, I guess.

    [1] Rust uses enums to generate the sum type tag as an implementation detail, so its not quite as weird as it originally seems, but still rather strange that it would name it based on an effectively hidden implementation detail instead of naming it by what the user is actually trying to accomplish. Most likely it started with proper enums and then realized that sum types would be better instead and never thought to change the keyword to go along with that change.

    But then again Swift did the same thing, so who knows? To be fair, its "enums" can degrade to proper enums in order to be compatible with Objective-C, so while not a very good reason, at least you can maybe find some kind of understanding in their thinking in that case. Rust, though...

    • culebron21 2 days ago

      > It has proper enums.

      Well, then they look awkward and have give a feel like it's a syntax abuse.

      > Its arrays and slices are exactly the same as how you would do it in C. So while it is true that trips up many coming from languages that wrap them in incredible amounts of magic, but the issue you point to here is actually a lack of magic.

      In Rust, I see exactly what I work with -- a proper vector, material thing, or a slice, which is a view into a vector. Also, a slice in Rust is always contiguous, it starts from element a and finishes at element b. I can remove an arbitrary element from a middle of a vector, but slice is read-only, and I simply can't. I can push (append) only to a vector. I can insert in the middle of a vector -- and the doc warns me that it'll need to shift every element after it forward. There's just zero magic.

      In Go instead, how do I insert an element in the middle of an array? I see suggestions like `myarray[:123] + []MyType{my_element} + myarray[123:]`. (Removing is like myarray[:123] + myarray[124:]`.)

      What do I deal in this code with, and what do I get afterwards? Is this a sophisticated slice that keeps 3 views, 2 to myarray and 1 to the anonymous one?

      The docs on the internet suggest that slices in go are exactly like in Rust, a contiguous sequence of array's elements. If so, in my example of inserting (as well as when deleting), there must be a lot happening under the hood.

      • pekim 2 days ago

        Inserting elements in to a slice can be done quite easily since the introduction of the slices package to the standard library.

        https://pkg.go.dev/slices#Insert

        • callc 2 days ago

          You shouldn’t need a library to do this simple operation.

          I’m guessing the go language design went too far into “simplicity” at the expense of reasonableness.

          For example, we can make a “simpler” language by not supporting multiplication, just use addition and write your own!

          • 9rx a day ago

            The operation is simple in concept, but can be costly from a compute standpoint when n is large. Multiplication has predicable performance. Insert does not. It being a function indicates that it is doing a lot of things and thus offers pause to make sure that the operation is acceptably within your operational bounds.

            It could have been a builtin function, I suppose, but why not place it in the standard library? It's not a foundational operation. If you look at the implementation, you'll notice it simply rolls up several foundation operations into one function. That is exactly the kind of thing you'd expect to find in a standard library.

      • 9rx 2 days ago

        > Well, then they look awkward and have give a feel like it's a syntax abuse.

        So nothing to worry about?

        > how do I insert an element in the middle of an array?

        Same as in C. If the array allocation is large enough, you can move the right hand side to the next memory location, and then replace the middle value.

        Something like:

            replaceWith := 3
            replaceAt := 2
            array := [5]int{1, 2, 4, 5}
            size := 4
            for i := size; i > replaceAt; i-- {
                array[i] = array[i-1]
            }
            array[replaceAt] = replaceWith
            fmt.Println(array) // Output: [1 2 3 4 5]
        
        If the array is not large enough, well, you are out of luck. Just like C, arrays must be allocated with a fixed size defined at compile time.

        > The docs on the internet suggest that slices in go are exactly like in Rust, a contiguous sequence of array's elements.

        They're exactly like how you'd implement a slice in C:

            struct slice {
                void *ptr;
                size_t len;
                size_t cap;
            };
        
        The only thing Go really adds, aside from making slice a built-in type, that you wouldn't find in C is the [:] syntax.

        Which isn't exactly the same as Rust. Technically, a Rust slice looks something like:

            struct slice {
                void *ptr;
                size_t len;
            };
        
        There is some obvious overlap, of course. It still has to run on the same computer at the end of the day. But there is enough magic in Rust to hide the details that I think that you lose the nuance in that description. Go, on the other hand, picks up the exact same patterns one uses in C. So if you understand how you'd do it in C, you understand how you'd do it in Go.

        Of course, that does mean operating a bit lower level than some developers are used to. Go favours making expensive operations obvious so that is a tradeoff it is willing to make, but regardless if it were to make it more familiar to developers coming from the land of magic it stands that it would require more magic, not less.

        • culebron21 2 days ago

          Ok, so mostly we agree. And I was right that you can't just concatenate different slices (e.g. to remove one item from the middle), hence Go has to do a lot of work under the hood to do that. I count this as magic.

          • 9rx a day ago

            > Ok, so mostly we agree.

            I don't follow. Information isn't agreeable or disagreeable, it just is.

            > And I was right that you can't just concatenate different slices

            That's right. You would have to physically move the capacitors in your RAM around (while remaining powered!) in order to do that. Given the limits of our current understanding of science, that's impossible.

            > hence Go has to do a lot of work under the hood to do that.

            Do what? You can't actually do that. It cannot be done at the hardware level. There is nothing a programming language can do to enable it.

            All a programming language can do is what we earlier demonstrated for arrays, or as slices allow dynamic allocation, if the original slice is not large enough you can also copy smaller slices into a new slice using a similar technique to the for loop above.

            Go does offer a copy function and an append function that do the same kind of thing as the for loop above so you do not have to write the loop yourself every time. I guess that's what you think is magic? If you are suggesting that calling a function is magic, well, uh... You're not going to like this whole modern programming thing. Even Rust has functions, I'm afraid.

            The Go standard library also provides a function for inserting into the middle of a slice, but, again, that's just a plain old boring function that adds some conditional logic around the use of the append and copy functions. It is really no different to how you'd write the code yourself. So, unless function are still deemed magic...

          • zimpenfish 2 days ago

            I may have misunderstood "you can't just concatenate different slices (e.g. to remove one item from the middle" but does [0] not do what you're talking about?

            (with the caveat that anything else sharing `a` will be mangled, obvs.)

            [0] https://go.dev/play/p/uQdoa3mUF00

    • tptacek 2 days ago

      I wish Go had sum types too. But I like being able to write a mutable tree structure without first having to read a whole book on the subject and inventing a new system of pointers. Every language is tradeoffs.

      • zerr 2 days ago

        As a C++ dev, such comments reinforce my hesitation to pick up either Go or Rust seriously :) It seems I already have the golden middle after all.

        • allovertheworld 21 hours ago

          If only C++ had a fully supported cargo system

      • ninetyninenine 14 hours ago

        Pointers are orthogonal to sum types. They are completely different things and there is literally no tradeoff for the two things you describe. So you’re not making any sense.

        • tptacek 12 hours ago

          No, you simply misread the comment.

      • EnergyAmy 2 days ago

        I like the language saying "it's not as easy as you think" when I'm about to do something ill-advised like roll my own mutable tree structure.

        • dilyevsky a day ago

          It is in fact not that hard when your memory is automatically managed

        • tptacek 2 days ago

          You understand that tree structures aren't just lookup tables, right? I wouldn't roll my own red-black tree (Jesus how tedious would that be). That's not what I'm talking about.

        • bobbylarrybobby 2 days ago

          I mean, it is as easy as you think in a GC language

    • culebron21 a day ago

      upvoted to compensate the mob that came about and downvoted those who replied to me.

jryio 2 days ago

Glad to see that the bowling development team is focusing on deterministic tooling like language server protocol in gopls and using static analysis for automatically restoring code with go fix.

Recently I made the same assertions as to Go's advantage for LLM/AI orchestration.

https://news.ycombinator.com/item?id=45895897

It would not surprise me that Google (being the massive services company that it is) would have sent an internal memo instructing teams not to use the Python tool chain to produce production agents or tooling and use Golang.

  • somekyle2 2 days ago

    Even 15 years ago or so when Guido was still there I recall being told "we aren't supposed to write any new services in Python. It starts easy, then things get messy and end up needing to be rewritten." I recall it mostly being perf and tooling support, but also lack of typing, which has changed since then, so maybe they've gotten more accepting.

disintegrator a day ago

When you turn on exhaustive, exhaustruct and wrapcheck linters in golangci-lint. You get such a massive safety boost and it makes you fly through writing Go.

p2detar 2 days ago

I recently finished my first ever side gig in Go - a web platform that organizes business processes between multiple actors. Got paid and more feature requests are coming in. Fronted with Caddy, the whole thing runs flawlessly on a $5 VPS. I love Go.

Pbhaskal 2 days ago

It has been my go to language since 2020. I was given a task to complete in a week and my lead told just go through Go playground and write the code (it was some snmp receiver/transmit stuff). To my surprise it was so easy to learn, write and more importantly test. Only recent thing i have not learned is generics, hopefully will get their sooner. Coming from java background the things Go did felt so clever and just too good to believe

adamddev1 2 days ago

I'm thankful for Go because it was an easy first introduction to static typing.

I remember making a little web app and seeing the type errors pop up magically in all he right places where I missed things in my structs. It was a life-changing experience.

iainctduncan 15 hours ago

Curious if anyone has real-world stories/data around Green Tea's pause times....

rishabhaiover 2 days ago

Love Go! It gently introduced me to the systems programming world.

mikewarot a day ago

And here I was anticipating a release of Go for the Apple ][ computer[16]

[16] https://en.wikipedia.org/wiki/SWEET16

  • duskwuff a day ago

    It might be possible. TinyGo exists, and can target some devices with even less memory than the Apple II, like the ATmega328 microcontroller.

kasperset 2 days ago

I am not really familiar with Go but I wonder where it would be without Google's support and maintenance. I have no doubt it is a solid language with some really smart people in programming language design behind it. It is so much easy to release programming language but so much difficult to maintain and curate it over time.

captainkrtek 2 days ago

Been happily working in Go since 2014. My career has spanned C, Python, C#, Ruby, and a smattering of other languages, but am always quite fond and preferential towards Go.

submeta a day ago

Been writing Python code for over twenty years, and using it for personal and work projects, not mainly, but to suppport my work. Recently I ported some of my code to Go and was blown away: Cross compiler, creating binaries, concurrency done right, super fast code. I come very late to the party, and writing software is not my main job, but Go is such a nice complement for my toolbelt. Python for prototyping or writing small services with fastapi, go for network realted stuff, serving lots of users. Super happy with this.

And I am wondering if Rust would be a good addition. Or rather go with Typescript to complement Python and Go.

insurancesucks a day ago

Every Go thread on this site is the same.

"Man I love Go, it's so simple, plenty fast, really easy to pick up, read, and write. I really love that it doesn't have dozens of esoteric features for my colleagues to big brain into the codebase"

"Oh yeah? Well Go sucks, it doesn't have dozens of esoteric features for me to big brain into the codebase"

Repeat

  • dlock17 a day ago

    Yep, and I personally feel like it's been the biggest stealth marketing of Go through the years.

Zardoz84 2 days ago

I tough that would be about SWEET16

MagicMoonlight 2 days ago

I just can’t get over the idiotic syntax.

Instead of “int x”

You have “var x int”

Which obscures the type, making it harder to read the code. The only justification is that 16 years ago, some guy thought he was being clever. For 99.99% of code, it’s a worse syntax. Nobody does eight levels of pointer redirection in typical everyday code.

  • bbkane 2 days ago

    I prefer this, especially for more complex types like functions- https://go.dev/blog/declaration-syntax gives an overview of their thought process

    • gf000 a day ago

      "x: int p: pointer to int a: array[3] of int These declarations are clear, if verbose - you just read them left to right. Go takes its cue from here, but in the interests of brevity it drops the colon and removes some of the keywords "

      And in the process makes it significantly harder for human eyes to find the boundary between identifier and type.

  • LexiMax 2 days ago

    16 years is a bit of an under-estimate. I think the first popular language with this form of declaration was Pascal.

        var
            foo: char;
    
    Go was developed by many of the minds behind C, and inertia would have led them to C-style declaration. I don't know if they've ever told anybody why they went with the Pascal style, but I would bet money on the fact that Pascal-style declarations are simply easier and faster for computers to parse. And it doesn't just help with compile speed, it also makes syntax highlighting far more reliable and speeds up tooling.

    Sure, it's initially kind of annoying if you're used to the C style of type before identifier, but it's something you can quickly get to grips with. And as time has gone on, it seems like a style that a lot of modern languages have adopted. Off the top of my head, I think this style is in TypeScript, Python type hints, Go, Rust, Nim, Zig, and Odin. I asked Claude for a few more examples and apparently it's also used by Kotlin, Swift, and various flavors of ML and Haskell.

    But hey, if you're still a fan of type before variable, PHP has your back.

        class User {
            public int $id;
            public ?string $name;
    
            public function __construct(int $id, ?string $name) {
                $this->id = $id;
                $this->name = $name;
            }
        }
    • gf000 a day ago

      I have no problem with ident: type. I have problem with dropping the colon between them for no good reason, even though there used to be 2 quite well-established patterns every language adhered to.

    • mxey 2 days ago

      > don't know if they've ever told anybody why they went with the Pascal style

      I don’t know if this is the reason but Robert Griesemer, one of the three original guys, comes from a Pascal/Modula background.

    • anal_reactor a day ago

      Golang exists in this weird place where it's similar enough to C so that intuition connects it with C, but at the same time different enough that you keep tripping over.

  • mxey 2 days ago

    how would that look with type inference?

    You can write

    var x = 5

    how would that work if the type had to be first? Languages that added inference later tend to have “auto” as the type which looks terrible.

pjmlp 2 days ago

And still so many programming language design history lessons to learn from.

Maybe by 18, or 21, the maturity finally settles in.

ModernMech 2 days ago

Oh wow, so it's already been 16 years since Google steamrolled the Go! language, which had existed a decade before Go and had every right to the name. This was when they were still pretending "do no evil" was their brand.

There may be no honor amongst thieves but there is honor amongst langdevs, and when they did Go! dirty, Google made clear which one they are.

Status changed to Unfortunate

https://github.com/golang/go/issues/9#issuecomment-66047478

  • MagicMoonlight 2 days ago

    Does anyone use that other language? No!

    • duskwuff a day ago

      Go! wasn't even published as its own project [1] until 2015, well after Go(lang) was available. It previously existed as an unpublished CVS repository in an obscure Sourceforge project [2]; I can't fault the Go developers for ignoring or overlooking it. You can find a circa-2002 version of Go! in the archived CVS repository of the Sourceforge project, but none of the project's release files appear to contain it.

      (Ignore the "Last Update: 2013-09-06" on the project page - that's the date that SourceForge performed an automatic migration. Any real activity on the project seems to have petered out around 2002, with one final file released in 2003.)

      [1]: https://github.com/fgmccabe/go

      [2]: https://sourceforge.net/projects/networkagent/

      • ModernMech 9 hours ago

        You are wrong, here is the first publication from 2004. https://link.springer.com/article/10.1023/B:AMAI.0000031195....

        Due diligence would have revealed the Go! project in a standard literature review.

        I can and will fault the developers because even if they had overlooked it, they were explicitly asked, and declined to do so because they determined (themselves) there would be no confusion. So it wasn't that they overlooked it, or ignored it, they decided they were asked directly and responded "we don't care".

        If the reasoning boils down to "We can do this because you are small and we are big" I cannot support that.

    • ModernMech 2 days ago

      That's not the point, no one uses 99% of languages, so if that's the standard then it's a free-for-all. The PL community is small, so norms are important.

      PL naming code is:

      1. Whoever uses the name first, has claim to the name. Using the name first is measured by: when was the spec published, or when is the first repo commit.

      2. A name can be reused IFF the author has abandoned the original project. Usually there's a grace period depending on how long the project was under development. But if a project is abandoned then there's nothing to stop someone from picking up the name.

      3. Under no circumstances should a PL dev step on the name of a currently active PL project. If that happens, it's up to the most recently named project to change their name, not the older project even if the newer project has money behind it.

      4. Language names with historical notoriety are essentially "retired" despite not being actively developed anymore.

      All of this is reasonable, because the PL namespace is still largely unsaturated*. There are plenty of one syllable English words that are out there for grabs. All sorts of animals, verbs, nouns, and human names that are common for PLs are there for the taking. There's no reason to step on someone else's work just because there's some tie in with your company's branding.

      So it's pretty bottom basement behavior for luminaries like Ken Thompson and Rob Pike to cosign Google throwing around their weight to step on another dev's work, and then say essentially "make me" when asked to stop.

      * This of course does not apply to the single-letter langs, but even still, that namespace doesn't really have 25 langs under active development.

      • arccy 2 days ago

        Like how C and C# are different languages, Go and Go! are different. There's not name reuse here.

        • ModernMech 2 days ago

          Go and Go! are pronounced the same way, so yes, they're the same.

          Moreover the author of Go! personally requested that Google not step on his life's work. The man had dedicated a decade and authored a book and several papers on the topic, so it wasn't a close call. Additionally C# built on C++ which built on C. Go had no relationship to Go! at all. Homage and extension are one thing, but Go was not that.

          A policy of "do no evil" required Google to acquiesce. Instead they told him to pound sand.

          • arccy 13 hours ago

            They are not pronounced the same, otherwise we wouldn't have the ! in the language.

            • ModernMech 10 hours ago

              ! changes emphasis, not pronunciation.

  • anal_reactor a day ago

    Go! was clearly a toy language created only for the purpose of writing papers. It has no applications outside academia. Meanwhile Google's golang exists mostly in the sphere of practical use.

    • ModernMech 10 hours ago

      Programming languages don't have to be for the purpose of industrial software construction to be considered useful. In fact, many ideas that industrial languages use come from academia. If we want new ideas and new languages to flourish, it cannot be the case that large corporations get a free pass to just smash researchers' academic efforts when they feel like it, especially when their motto at the time was "Do no evil".

      • anal_reactor 6 hours ago

        My point is more that these two occupy two distinct areas. For example, the word "cool" has two very common meanings depending on whether you're talking about temperature of an object or the value of something in social context. Yes, it would be very confusing if "cool" had multiple meanings from the same domain, but that's not the case. Similarly, golang and Go! are terms from different domains. One is domain of practical engineering, and the other is academia.

nicodjimenez 2 days ago

Golang to me is a great runtime and very poor language. I could maybe get used to the C pointer-like syntax and to half of my code checking if err != nil, but the lack of classes is a step too far. The Golang idiomatic approach is to have a sprawling set of microservices talking to each other over the network, to manage complexity instead of having classes. This makes sense for things like systems agents (eg K8) but doesn't make sense for most applications because it complicates the development experience unnecessarily and monoliths are also easier to debug.

I would not use Golang for a big codebase with lots of business logic. Golang has not made a dent in Java usage at big companies, no large company is going to try replacing their Java codebases with Golang because there's no benefit, Java is almost as fast as Golang and has classes and actually has a richer set of concurrency primitives.

  • grey-area a day ago

    Microservices are entirely unrelated to classes and in no way endemic to go.

    Go’s lack of inheritance is one of its bolder decisions and I think has been proven entirely correct in use.

    Instead of the incidental complexity encouraged by pointless inheritance hierarchies we go back to structure which bundle data and behaviour and can compose them instead.

    Favouring composition over inheritance is not a new idea nor did it come from the authors of Go.

    Also the author of Java (Gosling) disagrees with you.

    https://www.infoworld.com/article/2160788/why-extends-is-evi...

    • nicodjimenez a day ago

      Microservices in Golang are definitely related to classes due to the ergonomic aspects of a language. It takes a lot of discipline in Golang not to end up with huge flat functions. Golang services are easier to reason about when they are small due to the lack of abstractions, also Golang is very quick to compile, so its natural to just add services to extend functionality. Code re-use is just a lot of work in Golang. Golang is not monolith friendly IMO.

      • grey-area 12 hours ago

        It really doesn’t.

        Structs and interfaces replace classes just fine.

        Reuse is really very easy and I use it for several monoliths currently. Have you tried any of the things you’re talking about with go?

  • wanderlust123 2 days ago

    I think lack of classes is highly desirable. So much enterprise code is poorly put together abstractions.

    I think go needs some more functional aspects, like iterators and result type/pattern matching.

    • nicodjimenez 2 days ago

      The solution to bad abstractions it not to make it very difficult to create abstractions at all. For systems code I think it's fine but for application code you probably want some abstractions or else it's very hard to scale a codebase.