[HN Gopher] Go runtime: 4 years later
       ___________________________________________________________________
        
       Go runtime: 4 years later
        
       Author : spacey
       Score  : 132 points
       Date   : 2022-09-26 19:25 UTC (3 hours ago)
        
 (HTM) web link (go.dev)
 (TXT) w3m dump (go.dev)
        
       | nhoughto wrote:
       | I always thought go needed more GC knobs, good that they added
       | this one and the strong reasoning behind it makes sense.
       | Impressive go has got this far with just one knob!
        
       | tbrock wrote:
       | I am not a fan of new knobs like this. It reminds me of Java
       | where you actually have to think about -xMx blah blah and setting
       | it is a dark art. I would really prefer if we could somehow
       | confer the memory limit from the container environment to go so
       | this could be set intuitively at the container level without
       | mucking about in the go GC internals.
        
         | mort96 wrote:
         | I'm sure the goal will always be to be as good as humanly
         | possible out of the box. 99.999% of users will probably never
         | have to think about it. But if your mission-critical
         | application just happens to hit a case which the default
         | behavior handles poorly, would you rather: 1) redesign your
         | system and hope that a different design just happens to not hit
         | the same bad case, or 2) tweak a knob until the GC fits your
         | use case?
         | 
         | I think I'd prefer 2. But 1 will always remain an option I
         | suppose.
        
       | synergy20 wrote:
       | It is probably a bit misleading when so many say: 'golang is
       | easy', it is not, it is as difficult as Java or other language,
       | probably easier than c++ and rust, but definitely not an easy
       | language.
       | 
       | it makes great sense for network with concurrency, not so with
       | real time or low resource devices to me.
        
         | mort96 wrote:
         | I always found languages which require you to always remember
         | to manually call destructors to be quite hard, be they C or Go
         | or JavaScript, when the system has lots of moving parts and
         | performance is a concern. A single mistake and you're leaking.
        
       | throwamon wrote:
       | Still yearning for an Ocaml-like language that uses the Go
       | runtime.
        
         | cheriot wrote:
         | I'd settle for the CoffeeScript of Go. Keep most of it, add sum
         | types, expand generics, and replace nil with options. If you're
         | feeling spicy, make whitespace significant.
        
         | pjmlp wrote:
         | I don't see the point, just use OCaml.
        
           | kevinmgranger wrote:
           | I don't understand how this is a response to every "I wish I
           | had blank but like ocaml". Threads exist.
        
             | pjmlp wrote:
             | As does OCaml since 1996, no need for sugar substitute
             | instead of using the real deal.
             | 
             | Compiles to native code, has a repl, version 5 is multicore
             | for those not happy with Lwt or multiprocessing in the UNIX
             | classical style of each tool does one thing, and a GC only
             | second to GHC in handling immutable types.
        
         | eeue56 wrote:
         | I've been toying with adding a new generator to Derw (currently
         | targets JS, TS, Elm, English and Derw itself for formatting)
         | that would support Go-based output. It will probably be an
         | experimental branch later this year. Go's performance and
         | distribution makes it an appealing target to hopefully get a
         | faster runtime (particularly interested in making the compiler
         | faster once self-bootstrapping is finished)
        
         | kornish wrote:
         | RIP Oden! https://oden-lang.github.io/
        
         | cmrdporcupine wrote:
         | I don't like Go, but I think I would use that.
         | 
         | But I'm ignorant: is the Go runtime built in any way to
         | accomodate third party languages? Apart from writing an
         | interepreter in Go, is there a good way to target it?
        
           | didibus wrote:
           | No it's not. That's why you haven't seen many alternate
           | languages.
           | 
           | Something else is that the semantics of the Go language
           | itself are purposely limited in ways that help build an
           | efficient runtime easily. So even if you could target the Go
           | runtime easily, it would impose limits to what the language
           | can do as I understand.
        
           | ck45 wrote:
           | This is just an assumption, but it might be possible to
           | translate to Go assembly and then use the Go toolchain.
           | 
           | Edit: https://github.com/minio/c2goasm seems to slightly go
           | in that direction.
        
         | eatonphil wrote:
         | F# on Go, yeah would be killer! Some time when I have enough
         | free time, if it doesn't exist already, I'd love to build.
        
           | jjtheblunt wrote:
           | what would it give that evolution of the .NET runtime and
           | tooling isn't likely to offer?
        
             | eatonphil wrote:
             | Go has nice libraries for networking on Linux.
        
       | philosopher1234 wrote:
       | Some very impressive wins here. Makes one wonder how much better
       | things are going to get in the next few years. All without
       | needing to change my programs!
        
       | nu11ptr wrote:
       | I really like the engineering principles in general that the Go
       | team uses, however, I just don't like Go. That isn't meant as a
       | slight or anything other than simply my opinion. That said, I
       | really like the idea of a simple language based on the sort of
       | principles demonstrated here. The runtime seems really nice, I
       | just wish I liked the language better (IMO: not expressive
       | enough, needs better error handling, needs much better enums,
       | needs pattern matching, has error prone C-style 'for', almost
       | everything is statements not expressions, special comments are
       | error prone, has nil pointers, etc.). In the end I think if
       | someone were to write a slightly simpler version of Rust with the
       | Go runtime it might be pretty neat. That said, I don't know what
       | I'd want to drop from Rust so maybe I'm just fantasizing.
        
         | User23 wrote:
         | This is pretty much exactly how I feel. I have great respect
         | for the Go team. I broadly agree with their design philosophy.
         | I think CSP is a great theory for concurrency. And I just don't
         | really like writing Go. I don't hate it, but I feel like I have
         | to either fight the language or just repeat myself an awful
         | lot.
         | 
         | Honestly, I suspect the deficiency is on my end. Perhaps I've
         | just spent too much time with Lisp and have experienced some
         | professional deformation.
        
           | mort96 wrote:
           | I sorely wish CSP was enforced in any way by Go, but it's
           | not. The only thing which arguably makes Go more "CSP-y"
           | than, say, C++ is that it comes with a decent built-in
           | concurrent queue and some syntax sugar. Goroutines have full
           | mutable access to all the variables in their scope, and lots
           | of Go code ends up being your good old mutex hell -- just
           | more of it, since threads are so easy to create.
           | 
           | I think something way more radical than "C++ threads but with
           | a built-in concurrent queue" is needed. If the default was to
           | share nothing, and any shared memory had to be explicitly
           | shared somehow, that would be a great step in the right
           | direction. Maybe the compiler could even check that
           | explicitly-shared variables are protected by a mutex;
           | something like how Rust mutexes "own" the things they're
           | protecting and you can't access the underlying object without
           | having the lock.
        
           | KerrAvon wrote:
           | It's OK to have ergonomic opinions about languages! In
           | scriptingland, I find Python abhorrent. Ruby fits my brain
           | like a glove (the core language, not Rails). Doesn't indicate
           | anything about the quality of the languages or their
           | respective partisans.
        
         | JustSomeNobody wrote:
         | > That isn't meant as a slight or anything other than simply my
         | opinion.
         | 
         | That's fine, we all have our preferences. I love Python, but I
         | can't stand Ruby. I love Go, but hate C++. I make my living
         | with C#, but won't touch Java.
         | 
         | It's okay. We're not wrong. We're just different.
        
         | Zababa wrote:
         | > In the end I think if someone were to write a slightly
         | simpler version of Rust with the Go runtime it might be pretty
         | neat.
         | 
         | OCaml kind of gives you that, but the dev experience isn't as
         | good as Rust or Go in my opinion. Still, I enjoy it a lot, more
         | than Go or Rust.
        
           | nu11ptr wrote:
           | Agreed - I really like OCaml. Unfortunately it isn't popular
           | enough to get tons of ecosystem love, so I could never find
           | the libraries I need. I'd be pretty happy if it got more
           | popular. Maybe the new multicore work will help.
        
         | akira2501 wrote:
         | I haven't found any issues with expression, so far. I wouldn't
         | use it to write a UI, but for writing networking code or
         | automated tasks I find it perfectly suited to the task.
         | 
         | I appreciate it's error handling. It's burdensome, sure, but it
         | presents almost no additional cognitive load when attempting to
         | reason about control flow.
         | 
         | It essentially has no enums. However, it has a comfortable type
         | system that can wrap primitive types, and you can define
         | methods on those wrapped types. It's serviceable, but not
         | elegant.
         | 
         | I have never been a fan of pattern matching outside of
         | functional languages. The phenomenon I notice in languages that
         | do have it, is the majority of uses cases seem to be a pattern
         | match with two outcomes, one a Some() and the other a None().
         | It really seems like a more annoying way to write if {} else
         | {}.
         | 
         | It has for, but it also has 'range.' It makes up for a lot.
         | 
         | It has nil pointers, which are just a "zero value." It's not
         | uncommon to make it useful and safer in certain contexts. You
         | can request a lookup in a map that is nil. You can ask for the
         | length of a slice that is nil. You get sensible answers still.
         | There are still footguns, but they're all single barrel.. which
         | is _nicer_.
         | 
         | I don't need a perfect language. Good enough with low cognitive
         | load and amazing cross-compile facilities I'll take any day of
         | the week.
        
           | nu11ptr wrote:
           | I will agree Rust has a higher "cognitive load", but not if
           | you write it every day. I think Rust might be tough to leave
           | and come back say a year later, but Go admittedly would be
           | easy. That said, having written 50K+ code in both languages,
           | I never want to write Go again. Rust on the other hand is all
           | I want to write now. I do wonder how many people who
           | understand Go's limitations (and work around them as you
           | point out above) have truly given Rust a try (takes a few
           | months - can't be done faster). I can't imagine anyone would
           | want to go back tbh, but maybe I'm wrong.
           | 
           | EDIT: In fairness, there is one thing and exactly one thing I
           | miss about Go: compile times. Rust is simply no competition
           | here, but in trade, it is doing a ton of extra work. Trade
           | offs.
        
             | stouset wrote:
             | Anecdote:
             | 
             | I have had year+ long breaks between writing Rust
             | applications. I have been able to get back into it without
             | issue very quickly. At least one of those times I
             | successfully completed a large, sweeping refactoring of a
             | code base that was untouched for three years that I can
             | confidently say would have been extremely difficult in
             | other languages I'm very proficient in and use daily.
        
             | vlunkr wrote:
             | > I do wonder how many people who understand Go's
             | limitations (and work around them as you point out above)
             | have truly given Rust a try (takes a few months - can't be
             | done faster)
             | 
             | This is basically the "Anyone who doesn't love my favorite
             | movie hasn't watched it enough times" argument. Programming
             | language design is a complex space, there are no "correct"
             | opinions.
        
             | ikiris wrote:
             | The problem with rust is explicitly that cognitive load in
             | large codebases. It is _much_ easier to read go code than
             | rust when working on many things. Rust fits great if you
             | don 't scale though.
        
       | tomalaci wrote:
       | I have been developing in Go for several years and feel like I
       | have seen most it can offer which is quite a lot for
       | backend/networking systems.
       | 
       | Besides its GC implementation that works very well most of the
       | time, it also has simple but strong debugging tools to
       | investigate how well you are handling memory allocation and CPU
       | usage. Enforcing consistent coding style also makes it very easy
       | to read other people's code and quickly contribute.
       | 
       | My suggestion to others is to avoid prematurely optimizing memory
       | usage (e.g. trying to do zero-copy implementations) and always
       | investigate performance via these profiling tools Go offers (e.g.
       | pprof). Very often Golang's compiler or runtime will
       | automatically optimize code that may not seem to allocate
       | optimally.
       | 
       | There are still downsides but some of them are actively worked
       | on:
       | 
       | 1. Generics are still lack-luster (... but good enough to start
       | replacing a lot of boilerplate code and will improve later on)
       | 
       | 2. Error handling is still tedious (fortunately it seems to be
       | their next big focus), it should take less code-space and have an
       | option of stack-trace
       | 
       | 3. Stdlib logging is too simple, lacks levels and structured-
       | logging-style (currently actively discussed:
       | https://github.com/golang/go/discussions/54763)
       | 
       | 4. Low-level UDP networking is weak (soon to be fixed as they
       | accepted this proposal: https://github.com/golang/go/issues/45886
       | ), this will become more important as we transition to QUIC
       | protocol
       | 
       | 5. CGo (C interop / C FFI) is pretty bad performance-wise
       | compared to other languages, it's OK if it is an I/O operation
       | but anything C interop that requires low latency won't be running
       | great
       | 
       | 6. Similar to other languages, nowadays there are growing
       | external dependency trees (e.g. I always wanted to use
       | testcontainers-go to make integration tests easier but man, have
       | you seen the dependency tree you will pull in with that
       | pacakge?), solution in my eyes is flattening and standardizing
       | most commonly used packages but Go in particular is very
       | opinionated regarding what is included in stdlib
       | 
       | The above downsides mostly come from the background of creating
       | distributed data pipelines and certain data collectors/parsers.
       | For building API servers, I keep hearing it is a godsend in its
       | simplicity, so your mileage may vary depending on the business
       | domain you work in.
       | 
       | I would be interested to hear other people's experience with Go,
       | however!
        
         | Fire-Dragon-DoL wrote:
         | And don't forget, the plugin API has some super strong
         | limitations. I wish that was fixed, otherwise platforms
         | "similar to wordpress" can never become a thing on Go
        
           | Xeoncross wrote:
           | Plugins for a compiled binary are just plain hard. Changing
           | the code works better with an interpreted language. Usually
           | you see the software implement it's own interpreter or a
           | scripting language on top to handle this.
        
             | Fire-Dragon-DoL wrote:
             | I know, I was thinking C# does something like that though,
             | so I was hoping it would be achievable.
             | 
             | The annoying part about the scripting language is that if
             | something is written in Go, you want developers to also
             | work in Go, otherwise the people writing plugins for your
             | software, knowing better the API and use-cases, have a
             | disconnection with the language actually used for the
             | software, losing potential opportunities for contributions.
        
             | wahern wrote:
             | Plugins for ELF- and Mach-O-based systems aren't any
             | different than regular shared libraries, modulo slightly
             | different symbol precedence. AFAIU, while a quite different
             | architecture, Windows PE linking treats them quite
             | similarly, too.
             | 
             | Perhaps you meant statically compiled binaries? Even then
             | I'm not so sure about that. Right now I'm working on a
             | project that statically compiles a plugin so its various
             | libraries can't leak or be overridden by the loading
             | application, yet which itself can load other plugins. OTOH,
             | this is in C, C++, and Lua (basically C from the
             | perspective of binary linking), all of which have mature
             | linking semantics.
             | 
             | When you use languages or toolchains that don't invest in
             | an ABI, or which make linking automagic (with no or little
             | recourse for exposing various linking features a platform
             | may offer), then runtime linking is likely to become a
             | major limitation in some areas.
        
           | cube2222 wrote:
           | Actually, folks usually just use gRPC or Yaegi in Go. You can
           | write an SDK for your software that abstracts all of that
           | away for the plugin developer.
           | 
           | See Terraform[0], Traefik[1], or OctoSQL[2].
           | 
           | Though I agree plugins would be welcome, especially for
           | performance reasons, though also to be able to compile and
           | load go code into a running go process (JIT-ish).
           | 
           | [0]: https://github.com/hashicorp/terraform
           | 
           | [1]: https://github.com/traefik/traefik
           | 
           | [2]: https://github.com/cube2222/octosql
           | 
           | Disclaimer: author of OctoSQL
        
           | morelisp wrote:
           | If I was going to try to make something "similar to
           | Wordpress" with Go I would replace plugins with optional
           | packages triggered by build flags (or possibly a light
           | codegen step), not an actual dynamic plugin system.
           | 
           | If you have a language that compiles fast and generates a
           | single binary, take advantage of that; don't try to
           | reimplement fragile dynamic linking.
        
           | Philip-J-Fry wrote:
           | I've written plugins in Go. You don't really need to use the
           | plugin package, and you probably shouldn't anyway.
           | 
           | One way I've done it in the past is via sub processes talking
           | via stdin/stdout. Another way I've done it is just via a
           | regular REST API.
           | 
           | You'll never get enough performance for a lot of tasks if you
           | need to pass a lot of data between applications. But
           | depending on your needs it's more than serviceable. The
           | benefit of this is that plugins don't need to be written in
           | Go, as you have a simple interface.
           | 
           | A good example of this is something like LSP. LSP plugins are
           | abundant and each one is written in a different language.
           | VSCode is Typescript, the Go language server is written in
           | Go. Both can speak to eachother fast enough.
        
       | nwmcsween wrote:
       | Not trying to be inflammatory but has the pclntab taking ~30% for
       | binary size been fixed yet? IMO it's a pretty severe design
       | choice.
        
         | Thaxll wrote:
         | No one really care about binary size increase , especially
         | because you can run a Go binary in a docker image with 0
         | dependencies ( scratch image ) which has a very small size.
        
           | nick__m wrote:
           | do you know how things like tzdata and locale are handled in
           | a single Go executable docker image ?
        
             | twp wrote:
             | tzdata, at least, can be embedded in your binary:
             | https://pkg.go.dev/time/tzdata
        
         | digitaLandscape wrote:
        
         | dewey wrote:
         | > IMO it's a pretty severe design choice.
         | 
         | I don't think that's true, otherwise it would've been fixed
         | already. For the main use case of Go
         | (https://go.dev/blog/survey2022-q2-results), APIs and web
         | services it just doesn't matter if the binary is 1MB or 30MB.
         | Unless you are working on some embedded systems where space is
         | scarce I don't see it as a big issue.
        
         | geodel wrote:
         | where is that issue listed?
        
           | LukeShu wrote:
           | https://github.com/golang/go/issues/36313
        
             | geodel wrote:
             | Ah that seems to be the issue some CockroachDB guy
             | complained about. I don't think its high priority for Go
             | team.
        
               | twp wrote:
               | The CockroachDB guy didn't understand what he was doing.
               | There's a refute from Russ Cox here:
               | https://news.ycombinator.com/item?id=26834128
        
       ___________________________________________________________________
       (page generated 2022-09-26 23:00 UTC)