Go is my hammer, and everything is a nail
Markus, a solo developer, exclusively uses Go for software development, valuing its simplicity and versatility. He believes focusing on one language enhances productivity and deepens expertise without limiting career options.
Read original articleMarkus, a solo developer, shares his experience of using the Go programming language for all his software development needs. He emphasizes the importance of choosing the right tools, particularly for solo developers, to avoid unnecessary complexity and busywork. Initially skeptical about Go, he grew to appreciate its simplicity, readability, and versatility, ultimately abandoning other languages like Python and JavaScript. Markus outlines three main reasons for his choice: Go's capability to handle various tasks, reduced context switching by using a single language, and the opportunity to gain a deeper understanding of Go without the distraction of multiple languages. He believes that focusing on one language allows him to become more productive and proficient, despite the vastness of the software development field. Markus concludes by expressing confidence in his decision to use Go, viewing it as a powerful tool for his projects.
- Markus is a solo developer who exclusively uses Go for software development.
- He values simplicity and reduced complexity in his tech stack to enhance productivity.
- Using one programming language minimizes context switching and allows for deeper knowledge.
- Markus believes that focusing on Go does not limit his career options but rather enhances his expertise.
- He has transitioned from other languages to Go, finding it suitable for a wide range of applications.
Related
Common Interface Mistakes in Go
The article delves into interface mistakes in Go programming, stressing understanding of behavior-driven, concise interfaces. It warns against excessive, non-specific interfaces and offers guidance from industry experts for improvement.
I Probably Hate Writing Code in Your Favorite Language
The author critiques popular programming languages like Python and Java, favoring Elixir and Haskell for immutability and functional programming benefits. They emphasize personal language preferences for hobby projects, not sparking conflict.
First impressions of Go 1.23's range-over-func feature
The author shares positive experiences with Go 1.23's range-over-func feature, initially skeptical but finding it easy to use. Successful adaptation in their project Kivik disproved initial concerns, highlighting benefits for codebase improvement.
Go structs are copied on assignment (and other things about Go I'd missed)
The author reflects on learning Go, highlighting misconceptions about struct assignment, sub-slice modifications, and method receivers. They recommend the "100 Go Mistakes" resource and other learning materials for improvement.
Go structs are copied on assignment
The author shares insights on learning Go, emphasizing struct assignment, slice appending, and value versus pointer receivers. They recommend the "100 Go Mistakes" resource and other tools for better understanding.
- Many appreciate Go's simplicity, productivity, and strong standard library, making it a preferred choice for various projects.
- Critics highlight Go's verbosity and limitations in certain areas, such as data manipulation and GUI development, making it less enjoyable for personal projects.
- Some commenters emphasize the importance of choosing the right tool for the job, suggesting that while Go is versatile, it may not be the best fit for every task.
- There is a recognition of the trade-offs involved in specializing in one language, with some arguing that expertise in multiple languages can be more beneficial.
- Overall, the conversation reflects a mix of admiration and skepticism towards Go, with many advocating for a balanced approach to language selection based on project needs.
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.
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 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’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
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.
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
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 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!
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)
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...
No tool deserves more love or loyalty than the productivity it brings, anything more is infatuation and a game for naive and the fool.
Use what you want.
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."
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.
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.
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.
Group by, filter, map, join. It is just very error prone, inconvenient and slow to implement with for loops.
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 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.
Java for Everything
https://www.teamten.com/lawrence/writings/java-for-everythin...
Previously HN discussion of "Java for Everything":
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 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'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
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.
>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.
What can I do to resolve this? You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.
On bigger projects, the first pain point to appear for me is dependency management. It feels so antiquated in most other ecosystems, with loose compatibility contracts that add mental overhead. Go let’s you focus on the problem you are trying to solve, and you get so used to that luxury that using anything else quickly becomes painful.
Sounds like they are choosing the right tool for the job.
When considering languages, familiarity is a significant aspect. And, the smaller the duration/size of the project, the more significant it is. A decent analysis wouldn't ignore this.
If the language you're most productive with is appropriate for a project (and go is appropriate for a wide variety of things), you need a good reason not to use it.
> Reason 1: Go can do basically anything That is a weak argument. All languages can do everything (for example, you can build GUI desktop apps in PHP). If omnipotency is the main criteria, then C# or Java are better alternatives than go - you can even build an OS on CLR/JVM.
You still should always try to use the right tool for the job. Doesn't mean it has to be the absolute best tool or such a thing exists, the best tools are often the ones you have ready at hand and know or can learn how to use.
Don't make Go the next PHP. PHP has some good updates recently but it still has some people with a negative experience with it.
I have a similar attitude with Python and Go as back hammers and Quasar (Typescript + Vue + Vite + components) as the front hammer.
Whenever there is a date in Python I exclusively use Arrow (even for the simplest, most basic ones).
I know it is not effecive, but I am an amateur dev and having these hard rules keeps me from testing something new all the time.
I leave this for home automation and docker services where my motto is "fix it until you break it"
when you have a programming language that can do everything and vibes with how you think, you're golden
I used to switch to shell or Python to do one-off scripts. But there's not a super great reason why I can't do the same in C++, which is what I know best. All the build stuff is easy to do in my company's repo, so that's not a big blocker.
I want all the things I spend my years studying to be built by committee or otherwise brief specimens of creative genius. Anything else makes me feel like I'm just learning Marvel lore.
Sometimes I wonder if I am just being lazy and justifying not learning new stuff but then I look at the new stuff that keeps landing in the Python ecosystem and conclude otherwise.
I would like a tool in go, that could handle nice GUI, compiled for WASM and run in the browser. Any ideas?
I will follow you @markuwsw.
> Less context switching
For the very same reason, my hammer is javascript.
There have been some good proposals but because people are so passionate about all their requirements and edge cases, that I don't think it'll ever get improved.
Checks all of the checkboxes.
So how do you build an OS kernel in Go? C folks have been doing it for decades. Rust guys are slowly catching up. And Go...?
That's just very not true...
Java for the most part has libraries and IDE's due to its history, but got tripped up on the essential web platform story: it's only achingly small/fast enough for real servers, and just flat out gave up on the browser after the javascript onslaught. For future-proofing, anti-Oracle bias has hamstrung Java of late (notwithstanding the excellent upgrades and engineering Oracle put in).
Go is great if you're on the server side with Google-like concerns, and it's unlikely Google would ever drop Go.
With Rust, the language offers the most for serious systems programming, but the learning curve limits available libraries (converse being true in javascript land). Rust is still early-adopters - likely the best talent-wise, but not scaling.
Swift is interesting. Can be as easy as Java, but is becoming as correct as Rust wrt lifetimes and more deployable than Go, to both server and embedded. But no real incentive from Apple for deploying on Windows or to the web, so that's handled by a few heroes. And unfortunately, libraries are sort of an open-source zoo of minor offerings. But Apple's betting the company on Swift, so you can, too.
Python pretty much lucked into popularity by supporting the scientific computing that would become data analysis and AI after building significant community inertia. It's sort of the default prototyping language in a time when prototypes are often good enough. It's gradually been adding typing and performance to stay good enough.
So Python would be my recommendation as the one language to rule them all for indie developers, who are more likely to be plumbing together applications than writing database engines. It's also where the money is now for most developers.
That said, it may depend most on the market for skills. It might be easier to build an indie business as a Go developer because the supply/demand curve favors you. And as far as I know, there's no good data on point for that.
Just look at this beautiful test page [0]. I’m pretty sure I spent more time on that than on the blog post.
On a more serious note, thank you for all the discussion! It’s hard keeping up with all the comments, but I’m truly appreciative of the quality of discourse here.
Also, the newsletter subscription is up now, if you’re into that. [1]
[0]: https://www.maragu.dev/typography [1]: https://www.maragu.dev/blog/go-is-my-hammer-and-everything-i...
Related
Common Interface Mistakes in Go
The article delves into interface mistakes in Go programming, stressing understanding of behavior-driven, concise interfaces. It warns against excessive, non-specific interfaces and offers guidance from industry experts for improvement.
I Probably Hate Writing Code in Your Favorite Language
The author critiques popular programming languages like Python and Java, favoring Elixir and Haskell for immutability and functional programming benefits. They emphasize personal language preferences for hobby projects, not sparking conflict.
First impressions of Go 1.23's range-over-func feature
The author shares positive experiences with Go 1.23's range-over-func feature, initially skeptical but finding it easy to use. Successful adaptation in their project Kivik disproved initial concerns, highlighting benefits for codebase improvement.
Go structs are copied on assignment (and other things about Go I'd missed)
The author reflects on learning Go, highlighting misconceptions about struct assignment, sub-slice modifications, and method receivers. They recommend the "100 Go Mistakes" resource and other learning materials for improvement.
Go structs are copied on assignment
The author shares insights on learning Go, emphasizing struct assignment, slice appending, and value versus pointer receivers. They recommend the "100 Go Mistakes" resource and other tools for better understanding.