Go is my hammer, and everything is a nail(maragu.dev)
maragu.dev
Go is my hammer, and everything is a nail
https://www.maragu.dev/blog/go-is-my-hammer-and-everything-is-a-nail
798 comments
I used to work for a Go shop. We dealt with financial data. I found it so annoying that many of my colleagues would use Go for one-off tasks such as aggregating CSV files, updating the database with some data, or fetching data from the database, and then trying to make a plot. I saw my colleagues again and again implementing basic algorithms such as rolling median, or finding a maximum. Instead of loading data into Pandas and doing a group by, they would create some kind of loopy solution that would use maps.
I totally understand why some people prefer Go in production to Python, but I could never understand why people wouldn't just learn the standard data science tools instead of reinventing the wheel in Go, always debugging their own off-by-one errors. It was difficult for me to trust the results of such analyses, given that I knew how many of the basic functions were written on the fly and probably not even tested.
In the end, I didn't think it was a good use of the company's time. It felt more like an ego thing - thinking and showing that Go is sufficient. It reminds me of how people try to use iPads to code - only to show that they can do it.
I totally understand why some people prefer Go in production to Python, but I could never understand why people wouldn't just learn the standard data science tools instead of reinventing the wheel in Go, always debugging their own off-by-one errors. It was difficult for me to trust the results of such analyses, given that I knew how many of the basic functions were written on the fly and probably not even tested.
In the end, I didn't think it was a good use of the company's time. It felt more like an ego thing - thinking and showing that Go is sufficient. It reminds me of how people try to use iPads to code - only to show that they can do it.
The author lists multiple reasons for this, but for me the biggest one is the first one: Go is good for almost everything.
I have extremely good productivity when using Go. Once your project exceeds 100 lines it is usually even better than python. And yes, I am aware that Rustians did a survey where Rust was crowned as the most efficient language but in my reality (which may differ from yours) Go is simply the best tool for most tasks.
Why is that? Well, for me there are 3 reasosns:
1. The language is extremely simple. If you know 20% of C you are already a Go expert.
2. The core libraries are extremly well thought.
3. Batteries are included. The toolchain and the core libraries alone can do 90% of what most people will ever need.
When people argue about the validity of these claims, I simply point them to this talk https://go.dev/talks/2012/concurrency.slide#42
I have extremely good productivity when using Go. Once your project exceeds 100 lines it is usually even better than python. And yes, I am aware that Rustians did a survey where Rust was crowned as the most efficient language but in my reality (which may differ from yours) Go is simply the best tool for most tasks.
Why is that? Well, for me there are 3 reasosns:
1. The language is extremely simple. If you know 20% of C you are already a Go expert.
2. The core libraries are extremly well thought.
3. Batteries are included. The toolchain and the core libraries alone can do 90% of what most people will ever need.
When people argue about the validity of these claims, I simply point them to this talk https://go.dev/talks/2012/concurrency.slide#42
Go is everything I don’t want in a language for my personal projects. It’s verbose, every simple task feels like a lot to write. It’s not expressive, what would be a one-liner in Python makes you write three for loops in Go. I constantly need to find workarounds for the lack of proper enums, lack of sum types, no null safety etc.
I’m sure these are the exact reasons why Go is good for enterprise software, but for personal projects, I get no fun out of using it
I’m sure these are the exact reasons why Go is good for enterprise software, but for personal projects, I get no fun out of using it
That's why Typescript is my hammer, unless I need a jack hammer, which is Rust.
With Deno and Typescript I get an even more versatile toolbox than with Go. And what's even more important to me, Typescript is safer and more ergonomic than Go, but slightly slower. Rust is safer, more ergonomic and faster than Go, but much harder to learn.
Especially strict (which is a must) Typescript is underrated. Compared to Go, we get:
- null safety
- widely supported generics
- discriminated unions with either manually (some lines of code) or es-lint exhaustiveness checks
- much safer concurrency, as all Typescript code runs single-threaded. You need web workers, which are not as safe as Rust for concurrency, but much safer than Go.
- collection / iterator methods
So far, I see only few downside. I'd be happy if people could provide more. Currently I'm scratching my head why I didn't fall in love with Typescript (for backend and CLI) earlier. Maybe I haven't seen the dark sides yet. So, some points where Go is stronger than Typescript:
- Go is much more efficient in terms of size and memory usage
- Go's GC is better than V8s
- Go is faster on CPU bound tasks
- Go has a greater std lib, however, Deno's std lib is pretty nice as well.
- The ecosystem is smaller, but has not as much trash as NPM. The dependency trees with NPM are usually large. By the way, Rust has this problem as well, less than Typescript but more than Go. Still, many mainstream NPM packages are safe and rock solid.
What else could we say against Typescript (and preferably Deno or Bun)? I'm really eager to hear people having ditched it an why.
With Deno and Typescript I get an even more versatile toolbox than with Go. And what's even more important to me, Typescript is safer and more ergonomic than Go, but slightly slower. Rust is safer, more ergonomic and faster than Go, but much harder to learn.
Especially strict (which is a must) Typescript is underrated. Compared to Go, we get:
- null safety
- widely supported generics
- discriminated unions with either manually (some lines of code) or es-lint exhaustiveness checks
- much safer concurrency, as all Typescript code runs single-threaded. You need web workers, which are not as safe as Rust for concurrency, but much safer than Go.
- collection / iterator methods
So far, I see only few downside. I'd be happy if people could provide more. Currently I'm scratching my head why I didn't fall in love with Typescript (for backend and CLI) earlier. Maybe I haven't seen the dark sides yet. So, some points where Go is stronger than Typescript:
- Go is much more efficient in terms of size and memory usage
- Go's GC is better than V8s
- Go is faster on CPU bound tasks
- Go has a greater std lib, however, Deno's std lib is pretty nice as well.
- The ecosystem is smaller, but has not as much trash as NPM. The dependency trees with NPM are usually large. By the way, Rust has this problem as well, less than Typescript but more than Go. Still, many mainstream NPM packages are safe and rock solid.
What else could we say against Typescript (and preferably Deno or Bun)? I'm really eager to hear people having ditched it an why.
Go is my favorite general-purpose tool (combination of language + standard library + 3rd party libraries + tooling + documentation). Everything just works out of the box and is simple to use and understand. No collection of dozens of external tools with fiddly configuration, a simple command to compile and simple deployment via a single executable with no additional setup required. No other language gives me such a simple and hassle-free all-around experience.
I certainly think other languages (Java, C#, Rust, JS/TS) have a lot of advantages over Go in some areas, but everything I've worked with so far has some other aspects that I absolutely hate.
POV from a (mainly) B2B fullstack SE
I certainly think other languages (Java, C#, Rust, JS/TS) have a lot of advantages over Go in some areas, but everything I've worked with so far has some other aspects that I absolutely hate.
POV from a (mainly) B2B fullstack SE
I've been coding in Go for over five years. I like Go, but I don't love it. It's never my first choice, although I don't advocate for rewrites just to move away from it.
The tooling is a mess. Go modules still feel like a 'first pass' implementation that never got finished. There's no consistency in formatting or imports (even though Go claims there is). Generics are a good step but are still very primitive (no generics on interfaces, no types as a first-class object).
It still feels very unfinished as an ecosystem. I hope it'll get better as the Go team mature things, like iterating on generics. But I can't see Go modules continuing without a fundamental rewrite.
The tooling is a mess. Go modules still feel like a 'first pass' implementation that never got finished. There's no consistency in formatting or imports (even though Go claims there is). Generics are a good step but are still very primitive (no generics on interfaces, no types as a first-class object).
It still feels very unfinished as an ecosystem. I hope it'll get better as the Go team mature things, like iterating on generics. But I can't see Go modules continuing without a fundamental rewrite.
There are a lot of aspects of Go that I’m really not a fan of, but I’ve been writing an increasing amount of it over the last few months and on the whole I’m finding it really enjoyable—even though I’m not sure I could empirically explain why.
The tooling is heaven compared to other stuff we do a lot of at work (TS/JS of course being the main offender), and generally I find I spend less time thinking about things that aren’t directly related to the problem I’m trying to solve. Though, that might just be because I’m not an expert and simply don’t yet know about other things I could be thinking about!
The tooling is heaven compared to other stuff we do a lot of at work (TS/JS of course being the main offender), and generally I find I spend less time thinking about things that aren’t directly related to the problem I’m trying to solve. Though, that might just be because I’m not an expert and simply don’t yet know about other things I could be thinking about!
Life is barely long enough to get good at one thing so you should choose your thing wisely. That's wisdom I've held for quite some time.
Coincidentally, I chose Go as my language of choice as well. The factors that led me to that choice were many, but to highlight some:
- incredible standard library
- simple to read and write
- single static binary builds (assets included, like html/images, etc)
- don't need a container (my binary is the container)
- can be used anywhere (webdev, desktop apps, gamedev, embedded, etc)
Coincidentally, I chose Go as my language of choice as well. The factors that led me to that choice were many, but to highlight some:
- incredible standard library
- simple to read and write
- single static binary builds (assets included, like html/images, etc)
- don't need a container (my binary is the container)
- can be used anywhere (webdev, desktop apps, gamedev, embedded, etc)
I really like most aspects of Go, but as someone who writes a lot of numerical code, no operator overloading is a deal breaker. It's so hard to accept something like Add(Scale(s1, vec1), Scale(s2, vec2)) over s1 * vec1 + s2 * vec2. So I stick with Python and C++ for now.
Rust is really appealing as a C++ replacement, but it has too many rules to replace Python for one-off scripts. Still need to try Nim and Swift, I guess...
Rust is really appealing as a C++ replacement, but it has too many rules to replace Python for one-off scripts. Still need to try Nim and Swift, I guess...
At the peak of my honeymoon phase with Golang, I went down this path too, and oh boy does it feels great and liberating, like finding a magic bullet, but soon as you start to scratch beyond the surface and dig deeper, you will find yourself trying to screw screws with a hammer, or tie your shoes with a chainsaw and ungodly things like that.
No tool deserves more love or loyalty than the productivity it brings, anything more is infatuation and a game for naive and the fool.
No tool deserves more love or loyalty than the productivity it brings, anything more is infatuation and a game for naive and the fool.
"The world is laaaarge. The number of projects are basically infinite. Even if I carve out a tiny subset of infinite, that’s still infinite."
I liked the use of this wisdom in there.
This article is not so much about Go but about choosing to specialize in one language ecosystem instead of spreading one's attention across several.
The author feels happy and contented and you all are getting defensive. He’s a solo dev, just recognize that that scopes his projects and stop trying to shoot him down.
Use what you want.
Use what you want.
I can't really disagree with the points the article makes in favor of Go, and it's not selling it over some other language/framework/tool but just celebrating how great of an ecosystem Go has. And it's true -- Go's ecosystem has matured into something very pleasant to work with.
By the same token I know professors who still write their simulation scripts in QBASIC because that's what they are familiar with and they can solve their problems quickly. You can use all sorts of tools to drive a nail.
On Go, it's almost a footnote in the context of the post, but I think a seriously underrated feature is its C-interoperability. Here [0] is an example. It's not unique of course -- tons of languages have some FFI solution for C libraries -- but Go's is I believe one of the most straightforward to use if you're already familiar with the language. And while there are portability/stability sacrifices you make when you call a native library, it does also expand the available dependencies even beyond "basically infinite."
[0] https://go.dev/blog/cgo
By the same token I know professors who still write their simulation scripts in QBASIC because that's what they are familiar with and they can solve their problems quickly. You can use all sorts of tools to drive a nail.
On Go, it's almost a footnote in the context of the post, but I think a seriously underrated feature is its C-interoperability. Here [0] is an example. It's not unique of course -- tons of languages have some FFI solution for C libraries -- but Go's is I believe one of the most straightforward to use if you're already familiar with the language. And while there are portability/stability sacrifices you make when you call a native library, it does also expand the available dependencies even beyond "basically infinite."
[0] https://go.dev/blog/cgo
I understand the sentiment. My goto hammer is Kotlin, which I like a bit better than Go. But that's a highly subjective thing of course. And I use plenty of other languages as well (including very occasionally some Go).
It's not about what is better in general but about what is better for you. Better here means less time wasted with figuring out syntax, tools, APIs, frameworks, etc. Once you know how to do a certain thing in one language, having to relearn to do the same things in another is slightly annoying. Although, LLMs are actually hugely helpful for this these days.
IMHO we're about to see a minor renaissance in web development. I was playing with the Kotlin WASM compiler a few weeks ago just to verify that I could use existing web APIs. As it turns out, it's are all there. Using them might not be the fastest right now but I'm sure that will get improved over time. Garbage collection is already in (and coming soon to Safari as well). There are some inefficiencies with making calls into js that need some attention. But that's not really a show stopper unless you are doing this many times per second.
What that means is that you can just do web application in wasm; use all the stuff from the browser that you normally use but without any javascript (except for a tiny wrapper that loads the wasm). I actually use kotlin-js so it's not a big leap for me. But wasm loads a bit faster and probably compiles a bit faster too. No more webpack uglification needed (which is actually slower than the kotlin compiler). So that's 2x compiler performance right there.
The point here is not kotlin or javascript but that this now works with any language that you can get going with wasm. Including Go if you want. Javascript becomes completely optional. I'm sure some will be upset about that. But that would be mainly because it's their preferred hammer.
It's not about what is better in general but about what is better for you. Better here means less time wasted with figuring out syntax, tools, APIs, frameworks, etc. Once you know how to do a certain thing in one language, having to relearn to do the same things in another is slightly annoying. Although, LLMs are actually hugely helpful for this these days.
IMHO we're about to see a minor renaissance in web development. I was playing with the Kotlin WASM compiler a few weeks ago just to verify that I could use existing web APIs. As it turns out, it's are all there. Using them might not be the fastest right now but I'm sure that will get improved over time. Garbage collection is already in (and coming soon to Safari as well). There are some inefficiencies with making calls into js that need some attention. But that's not really a show stopper unless you are doing this many times per second.
What that means is that you can just do web application in wasm; use all the stuff from the browser that you normally use but without any javascript (except for a tiny wrapper that loads the wasm). I actually use kotlin-js so it's not a big leap for me. But wasm loads a bit faster and probably compiles a bit faster too. No more webpack uglification needed (which is actually slower than the kotlin compiler). So that's 2x compiler performance right there.
The point here is not kotlin or javascript but that this now works with any language that you can get going with wasm. Including Go if you want. Javascript becomes completely optional. I'm sure some will be upset about that. But that would be mainly because it's their preferred hammer.
Heard from someone: "C++ is a hammer, but then everything starts to look like your finger"
If all you know is a Hammer…
I was searching for reasons why to use the Go-Hammer when there are comparable ones such as Java, C#, etc. but the article left me wanting.
It strikes me that Go is riding the peak of hype languages, succeeding Rust and Node.js (which are all good pieces of technology and absolutely have their merit). And like with most hype driven decisions there is little (self) awareness of context and alternatives.
Note, this is explicitly not about the languages themselves, but rather the larger cult(ure) of mainstream programmers around them.
I was searching for reasons why to use the Go-Hammer when there are comparable ones such as Java, C#, etc. but the article left me wanting.
It strikes me that Go is riding the peak of hype languages, succeeding Rust and Node.js (which are all good pieces of technology and absolutely have their merit). And like with most hype driven decisions there is little (self) awareness of context and alternatives.
Note, this is explicitly not about the languages themselves, but rather the larger cult(ure) of mainstream programmers around them.
Different strokes for different folks. Used Go for ~5 years, would be happy to never use it again. Typescript is in a similar bucket, lots of professional usage (sadly still using it) would also be happy to never touch it again.
Kotlin/JVM became my hammer and I currently don't feel like there are any gripes I have about it except maybe that the Gradle/Maven dichotomy and associated anxiety that build systems give people makes it harder to sell people on it.
Otherwise language feature wise and runtime wise it's about as good as you are going to ever need for 99.99% of (non-frontend) use cases. You have C++/Rust/Zig to fill in the few places where a runtime isn't viable.
Kotlin/JVM became my hammer and I currently don't feel like there are any gripes I have about it except maybe that the Gradle/Maven dichotomy and associated anxiety that build systems give people makes it harder to sell people on it.
Otherwise language feature wise and runtime wise it's about as good as you are going to ever need for 99.99% of (non-frontend) use cases. You have C++/Rust/Zig to fill in the few places where a runtime isn't viable.
Where I feel go is lacking is for data wrangling.
Group by, filter, map, join. It is just very error prone, inconvenient and slow to implement with for loops.
Group by, filter, map, join. It is just very error prone, inconvenient and slow to implement with for loops.
None of these reasons are specific to Go. They apply just as well to any Turing complete programming language.
Not to say the arguments are bad. Just that the argument is for picking one tool and using it for everything to benefit from your investment in that tool across all your projects.
Not to say the arguments are bad. Just that the argument is for picking one tool and using it for everything to benefit from your investment in that tool across all your projects.
I really want to love Go for side projects but it’s just so verbose and time consuming.
I understand that a framework with ”batteries” goes against Go principles, but coming from Rails, which solves the common boring problems for me, Go just makes it too much of a pain.
At least as far as web dev goes, I’m sure Go is great for other stuff.
I understand that a framework with ”batteries” goes against Go principles, but coming from Rails, which solves the common boring problems for me, Go just makes it too much of a pain.
At least as far as web dev goes, I’m sure Go is great for other stuff.
Related:
Java for Everything
https://www.teamten.com/lawrence/writings/java-for-everythin...
Previously HN discussion of "Java for Everything":
https://news.ycombinator.com/item?id=26934297
Java for Everything
https://www.teamten.com/lawrence/writings/java-for-everythin...
Previously HN discussion of "Java for Everything":
https://news.ycombinator.com/item?id=26934297
I find Go akin to C ; it's really fast to pick up, I can use it without internet if I have to, it has enough functionality and enough stable libraries for me not really to have to bother with the latest and the greatest of everything like in the javascript world.
I use it when I cannot use CL (for basically everything) or Racket (language / code generation), which basically means 'if my clients doesn't accept the above'.
For web/desktop/backend CL and Go are both incredibly productive. CL for me is more productive, mostly because the effortless starting, far more expressive (do a lot with very little code), better repl, debugging, save and die etc. Single binaries are great about both and so is lightning fast compilation.
I guess I have two hammers; one of them has a more comfortable handle for whacking in those slightly more difficult nails.
Lately I cheat by using a subset of CL and generating the Go code.
I use it when I cannot use CL (for basically everything) or Racket (language / code generation), which basically means 'if my clients doesn't accept the above'.
For web/desktop/backend CL and Go are both incredibly productive. CL for me is more productive, mostly because the effortless starting, far more expressive (do a lot with very little code), better repl, debugging, save and die etc. Single binaries are great about both and so is lightning fast compilation.
I guess I have two hammers; one of them has a more comfortable handle for whacking in those slightly more difficult nails.
Lately I cheat by using a subset of CL and generating the Go code.
> So, what, I’m going to limit my career options?
I don't quite get this sentiment. In my experience, the career opportunities come from solving worthy problems, as opposed to using a particular language. Plus, I don't believe that an engineer should be identified by a language, as in a Go programmer, or a Java programmer.
I don't quite get this sentiment. In my experience, the career opportunities come from solving worthy problems, as opposed to using a particular language. Plus, I don't believe that an engineer should be identified by a language, as in a Go programmer, or a Java programmer.
You could have written the same article about C#.
For me, this is very true. Most bioinformatics is done in python, but over the last ~4 years I've ported everything I do over to Go: https://github.com/koeng101/dnadesign
I'm just massively more productive, and the fact that I can read code I wrote years ago and fully understand what I was thinking at the time is amazing, and I haven't experienced that in other languages. I've learned other languages quite in depth, but with Go it is simple enough that when I write code, I'm not thinking about code, it is purely the problem being solved, and the code just comes out onto the keyboard.
Ironically enough, I've recently started porting my entirely-go bioinformatics package to be a python package, mainly because I realize I'm not gonna convince everyone else in my field that Go > python
I'm just massively more productive, and the fact that I can read code I wrote years ago and fully understand what I was thinking at the time is amazing, and I haven't experienced that in other languages. I've learned other languages quite in depth, but with Go it is simple enough that when I write code, I'm not thinking about code, it is purely the problem being solved, and the code just comes out onto the keyboard.
Ironically enough, I've recently started porting my entirely-go bioinformatics package to be a python package, mainly because I realize I'm not gonna convince everyone else in my field that Go > python
For me, expertise in a particular language is rarely very useful. Expertise/specialization is mostly a time tradeoff for particularly thorny issues, but IME they rarely come up in a programming language context (usually it's domain or particular codebase-specific). That being said, Go is a really good "workhorse" language.
Been using go for nearly a year. Don’t like the strange formatting and naming standards and arbitrary rules surrounding it.
The worst thing I hate is the packaging rules. Once something is out in a folder it becomes a package. Once something is in a package there can’t be circular dependencies.
There can be circular dependencies within packages and files but not with other packages. This is fine except in golang and life in general people like to organize things by creating new packages. Why? Because people like folders. It’s instinctive. Rather than programming a project in one flat folder people like to throw their code into little modules by making a bunch of folders organized by semantic meaning rather then dependencies.
This ocd drive that I believe is some intrinsic part of human nature to organize things by semantic meaning in folders results in almost every golang project becoming some massive organization problem on the right place to put a function or a method. You spend an inordinate amount of time organizing things thinking that if go tells you there’s a circular dependency you did something wrong.
Nothing is further from the truth but people just love go so much that they trust this. What is happening is, the go way of making packages and your semantic methodology of organizing things into folders is colliding. Go doesn’t say there’s anything wrong with circular dependencies. The language completely permits circular dependencies in that if you want to create something with circular dependencies (which is an extremely common thing in languages and complex things outside of languages) go says you can’t have folders.
It’s the most strangely arbitrary choice and turns every project into an exercise of organization. Golang pits the human desire to organize things semantically with an opposing rule of organizing things into a tree of dependencies. A lot of people love spend so much extra time resolving this conflict because it makes them think they’re making things “more” organized and cleaner when it’s, in reality, a pointless effort trying to resolve two arbitrary and conflicting rules.
I know people love go. This is just my personal opinion of it. I don’t really like it. I want program organization to be seamless and simple. Go is not this program for me.
Rust handles organization better. Just better ux by allowing people to use folders as they intended to use them. Rust also has its own set of usability problems. But those problems are explicitly implemented for a specific tradeoff. In go the folder thing is completely arbitrary.
The worst thing I hate is the packaging rules. Once something is out in a folder it becomes a package. Once something is in a package there can’t be circular dependencies.
There can be circular dependencies within packages and files but not with other packages. This is fine except in golang and life in general people like to organize things by creating new packages. Why? Because people like folders. It’s instinctive. Rather than programming a project in one flat folder people like to throw their code into little modules by making a bunch of folders organized by semantic meaning rather then dependencies.
This ocd drive that I believe is some intrinsic part of human nature to organize things by semantic meaning in folders results in almost every golang project becoming some massive organization problem on the right place to put a function or a method. You spend an inordinate amount of time organizing things thinking that if go tells you there’s a circular dependency you did something wrong.
Nothing is further from the truth but people just love go so much that they trust this. What is happening is, the go way of making packages and your semantic methodology of organizing things into folders is colliding. Go doesn’t say there’s anything wrong with circular dependencies. The language completely permits circular dependencies in that if you want to create something with circular dependencies (which is an extremely common thing in languages and complex things outside of languages) go says you can’t have folders.
It’s the most strangely arbitrary choice and turns every project into an exercise of organization. Golang pits the human desire to organize things semantically with an opposing rule of organizing things into a tree of dependencies. A lot of people love spend so much extra time resolving this conflict because it makes them think they’re making things “more” organized and cleaner when it’s, in reality, a pointless effort trying to resolve two arbitrary and conflicting rules.
I know people love go. This is just my personal opinion of it. I don’t really like it. I want program organization to be seamless and simple. Go is not this program for me.
Rust handles organization better. Just better ux by allowing people to use folders as they intended to use them. Rust also has its own set of usability problems. But those problems are explicitly implemented for a specific tradeoff. In go the folder thing is completely arbitrary.
The article claims Go supports building GUI apps and links to this.
>Wails is a project that enables you to write desktop apps using Go and web technologies
At that point why not just use Electron and Node JS.
I like Golang, I truly do. But after building mobile apps in both Golang and Fluter, I'm well aware of Go's limitations.
Making anything look remotely nice is painful. Things get really difficult when you use the wrong tool for the job.
A much better argument could be made for JavaScript being a language that can do anything. Even then when ever you run npm install you need to pray the house of cards that is modern JavaScript doesn't collapse.
C# is also a contender, but people, particularly the FOSS crowd doesn't like it because Microsoft == Bad.
>Wails is a project that enables you to write desktop apps using Go and web technologies
At that point why not just use Electron and Node JS.
I like Golang, I truly do. But after building mobile apps in both Golang and Fluter, I'm well aware of Go's limitations.
Making anything look remotely nice is painful. Things get really difficult when you use the wrong tool for the job.
A much better argument could be made for JavaScript being a language that can do anything. Even then when ever you run npm install you need to pray the house of cards that is modern JavaScript doesn't collapse.
C# is also a contender, but people, particularly the FOSS crowd doesn't like it because Microsoft == Bad.
A surprising number of people think this is a very long time. It isn't. This is typically the time it takes to understand enough of the language, the compiler, the runtime, the standard library, and idiomatic ways to do things. It is the time it takes to where you can start to meaningfully contribute to evolving how the language is used and meaningfully coach architects, programmers and system designers. It is also what you need to absorb novices into the organization and train them fast.