5 ms·
I've come to accept that Golang, as bad as it is, is probably the best that we're going to get in the near future. It takes so long for a language to rise to p
by preommr 3y ago
I've come to accept that Golang, as bad as it is, is probably the best that we're going to get in the near future.
It takes so long for a language to rise to prominence that newer languages like nim or zig are probably a decade away from even gaining a threshold.
I really wish there was a better alternative to golang because it comes so close to greatness: fast compile times, small binaries, GC, great concurrency ergnomics, great for networking (My God! you can just use net/http for so much - it's insane), an attempt at simple code (yea checking err is boilerplate, but it makes error handling clear), a community focused on having few dependencies where it's possible to build something and have it work for years.
But then there's complete bullshit like the nil handling, a lot of the interface design, the horrible enum equivalent, using casing to indicate accessibility, how tacked on generics are, how long it took to get decent package management when there was so much existing knowledge to learn from, etc. There's also some features like sum types that would be really nice to have.
- troupo 3y ago> great concurrency ergnomics Erlang/Elixir would like to have a word ;)
- zapnuk 3y ago...to congratulate Go as another language where concurrency ergonomics is baked into the language. While Go has another philosophy in mind, it works for many people. Together they opened the door to make concurrency a more important language feature and undoubtedly influenced other popular languages like java.
- zozbot234 3y agoI wouldn't describe Golang as "concurrency ergonomics" You can inadvertently share mutable data across Goroutines (Golang's term for userspace threads or fibers) in a memory unsafe way.
- SEMW 3y agoI'm a reasonably new go programmer, I've only been doing it full-time for a few months. But "great concurrency ergonomics" has.. not been my experience. What I've been finding is that primitives it gives you are easy to use, but extremely hard to use _correctly_. My first major PR in go had a week of back and forths as more experienced go programmers on my team pointed out the many, many places where my concurrent code was buggy -- places where I was receiving without selecting over the context being cancelled or some close-channel, places where I was sending from a goroutine that had to have a nonblocking basic loop without guarding with a default clause, places where I was using an unbuffered channel where pathological goroutine scheduling could result in a deadlock, places where I was using non-thread-safe data structures in places that could theoretically be mutated by multiple goroutines and without spamming mutexes everywhere, etc. etc. And sure, I'm relatively new to go. I'll learn these things and get better. But the contrast to some previous work I'd done in Elixir was striking. In Erlang/elixir, _the obvious first thing you try is generally actually correct_. And it gives you standard ways of working built on top of the primitives (genserver calls etc.), so you don't have to buggily reinvent the wheel every time you want to send a message from one goroutine to another with a reply, or need to tear down a bunch of goroutines simultaneously. I have a highly-concurrent elixir service I wrote several years ago, by myself (early stage company, no code review), still in production. It pretty much never has problems and basically just worked from the start. If I'd tried that with go, without a bunch of experienced go programmers to point out all the subtle race conditions, I'd probably still be dealing with a long tail of data races and deadlocks years later.
- t8sr 3y agoI think your criticism of Go as it is right now is basically: 1) nil handling is bad 2) Missing enum/variant/sum type 3) Non-specific dislike of interfaces and generics (care to expand?) 4) Some style decisions, like case-sensitivity Honestly, that's not a bad score for a language like this. If I were to list off things I dislike about virtually any other programming language, it'd be a lot longer. It's even more ok, because some type of enum type can still be added without breaking the language. I do agree about nils, though, that design is just bad and we're probably stuck with it.
- deleted 3y ago[deleted]
- baq 3y agoYeah it got so much right. I understand why generics were not part of 1.0 release. But I just can’t figure out how nil is better than option/result especially if you already have a generic map and an array as builtins…
- t8sr 3y agoI think nil is in the language because it keeps the compiler simpler than if it had to support an extra construct that exhausts the variants of option and result. In principle, you could implement a check, e.g. in govet, that tries to prove a value can't be nil and, if it can't, requires a runtime check. This is how things work, e.g., in eBPF, and it's fine. What really irks me about nil is that it's typed, and the (runtime!) type is part of the comparison. So checking "err == nil" can return false in case of "nil == nil" if you ever return a concrete error type rather than the interface. Now that is some crazy nonsense, and probably unfixable at this point.
- jen20 3y agoIt defers a tiny piece of complexity in the language to every program written in the language (at least, ones that care about correctness).
- t8sr 3y agoWell, actually I think once you decide that any nilable type has to be so annotated (e.g. as an option type), that changes the language quite a bit. I’m not so sure there is any evidence that programs written in such languages are simpler. In my experience, e.g. Rust and C# programs tend to be more complex than Go programs. Of course you might say the opposite, my point is that there’s no real evidence in either direction. And dealing with such type annotation is much more than a tiny bit complex. Constructs usually used for this tend to be some of the most complicated things in any language that has them. (Rust’s match alone might even have more grammar to it than all of Go). Finally correctness gets thrown around a lot, but what does it mean? Disallowing nils isn’t a magic bullet, in fact in most practical programs I’ve seen, values where the option wrapper is empty panic anyway. And even if you could eliminate all null pointer errors, how big a win is that really for correctness? I haven’t seen a null dereference error in Go code in a while.
- jillesvangurp 3y agoI have good hopes for Kotlin native to start being an alternative to things like Rust and Go. The compiler is already there. The ecosystem is just a bit lacking with libraries and Kotlin just is not used a lot for things like command line tools and other things where Go tends to be popular. Mostly the focus with Kotlin native is on IOS right now. But you can build windows/linux/mac binaries just as easily. Things like ktor actually support kotlin native as well. And of course there are a growing number of multiplatform libraries and things like the wasm compiler for kotlin getting closer to being ready.
- the_gipsy 3y agoKotlin will forever be a language built on top of java by a company that sells IDEs.
- jillesvangurp 3y agoA better Java; and with Kotlin native no jdk dependencies. And yes, they do know what they are doing when it comes to IDEs and languages.
- the_gipsy 3y agoFair enough.
- junon 3y ago... Rust?
- kaba0 3y ago> I really wish there was a better alternative to golang because it comes so close to greatness: fast compile times, small binaries, GC, great concurrency ergnomics, great for networking (My God! you can just use net/http for so much - it's insane), an attempt at simple code (yea checking err is boilerplate, but it makes error handling clear), a community focused on having few dependencies where it's possible to build something and have it work for years It’s called Java