The sad thing is that many people make language decisions on the beginner topics like syntax , literals, hello world or trivial samples.
Sure a 20 line python app will be 40 lines in Golang, but that doesn’t mean 10k lines of python are 20k lines in golang. And there are way more serious considerations than LOC.
Golang concurrency is amazing. You can reproduce an entire multi-core application stack with concurrent IO and CPU in a single binary.
When you realize how much code is wasted on config, RPC, encode-decode, code-generation, concurrency & locking – you want a language that reduces the need for those things (or makes them really easy).
My experience translating a codebase from Python to Golang (chat application), is that 20k of Python really does translate to around 40k of Golang to get the same functionality.
And it’s not just due to language but also expressiveness of the library ecosystem.
"The man barrier to translation was that, while at 14KLOC of Python
reposurgeon was not especially large, the code is very dense. It’s
a DSL that’s a structure editor for attributed DAGs — algorithmically
complex, bristling with graph theory, FSMs, parsing, tricky data
structures, two robot harnesses driving other tools, and three
different operator-composition algebras. It became 21KLOC of Go." [1]
It’s not a subjective opinion: I’m saying that I’ve actually migrated a Python application to Golang (real time chat application with a lot of business logic) and it was 2x the line count.
I expect the Golang line count ‘overhead’ gets bigger for typical LoB software that has to address any sort of enterprise mess.
I don't have any concrete measurements, but I think this is about right, ± a bit depending on the type of application.
I don't think this is necessarily a bad thing though; Go is a bit more explicit on a number of things and there's less opportunity to make code 'dense'. Both have their own up- and downsides.
I really think go goes too far to the point of hurting productivity and expressiveness. For example, go is missing any way to write parametric enums (sum types). Sum types make code much simpler and more expressive. The equivalent go code (using interfaces) is uglier, more verbose and more error prone. There’s a lot of features like that which go leaves out - like iterators, optional (nullable) types and so on.
The only tradeoff I see is that go is faster to learn, because it has less syntax. But at the end of the day I don’t mind spending a bit more time learning a language if the result is I can write more expressive and clear code. I love go’s concurrency model. It’s clever and simple to learn. I wish they applied the same pragmatism when designing other parts of the language.
All these things are a trade-off; unqualified statements that "sum types make everything simpler" are just wrong, because they don't. Whether it's worth the trade-off is a subjective judgement call and a completely different thing.
If all things are a trade-off, what would the trade-off of adding sum types be?
> All these things are a trade-off;
In some cases the trade-off is so one sided that its hardly worth the conversation. If everything is a trade-off, do you feel the same way about indenting your code? Or structured programming - aka using if/while blocks instead of gotos?
I think I'd confidently say that indented code makes everything simpler. And if I were given the choice, I think I'd choose structured programming every single time. I also don't often find myself questioning my daily choice to use high level languages rather than writing assembly directly. What else? Mmm... functions? I like those.
I feel the same way about sum types. They feel like an obviously good idea. Try as I might I can't think of any reason not to have them in a language like Go - except, as I already said - that they are another thing to learn when getting started. Having sum types and generics also makes it much easier for the type system to support optional types. And that makes it easier for a language to do away with Hoare's "billion dollar mistake".
If you disagree, I'd love to hear what you think the downsides are.
> If all things are a trade-off, what would the trade-off of adding sum types be?
Harder to write tooling for the language, bit harder to reason about code, possibly slower compiles (hard to claim this one for sure without a working implementation that has wide-spread use), harder to add features or change the language in the future, harder to work on (or implement a new) compiler.
None of these are insurmountable problems of course, and "Harder" means "harder relative to" rather than "hard". It's not clear to me anyway that sum times are a "slam dunk" type of feature. For example I've written a bunch of Go tooling over the years, and I really like that Go makes this fairly easy, partly due to the simple syntax. This is perhaps not something the "average developer does" or even a niche concern, but on the other hand: good tooling makes all the difference.
I'm not necessarily adding sum types to Go; details matter and it would partly depend on those.
Almost every single feature that has ever been added to any programming language was useful to add. I find many of Ruby's features useful, even some of the more esoteric ones, but that doesn't mean it was a good trade-off to add them.
> It's not clear to me anyway that sum times are a "slam dunk" type of feature.
They certainly are for me. I use them constantly in my two main languages - typescript and rust. Expressing similar ideas in go using iota and go's interfaces is far more awkward, inefficient and error prone.
I never said there aren't features in Go I would rather see removed, or that there aren't features I would like to see added, or that Go is perfect in general.
Only for some uses of iota. And iota is "simpler" from some perspectives, because you never have to deal with it anywhere except in const (..) blocks (that is, it's a very "localized" feature that barely interacts with anything else).
What’s also sad is people choosing between two very limited languages, Go and Python. Ultimately they both lead to the same place-orientated programming soup.
Sure a 20 line python app will be 40 lines in Golang, but that doesn’t mean 10k lines of python are 20k lines in golang. And there are way more serious considerations than LOC.
Golang concurrency is amazing. You can reproduce an entire multi-core application stack with concurrent IO and CPU in a single binary.
When you realize how much code is wasted on config, RPC, encode-decode, code-generation, concurrency & locking – you want a language that reduces the need for those things (or makes them really easy).