Go really does do well in the zero-to-hero case, that’s for certain. Unfortunately it doesn’t fare nearly as well in terms of ease when it comes to continued development.
Is there a language that anyone would say really does fare well for continued development or is it just that few people enjoy maintaining code? I’ve maintained some pretty old Go programs I wrote and didn’t mind it at all. I’ve inherited some brand new ones and wanted to rage quit immediately. I’ve also hated my own code too, so it’s not just whether or not I wrote it.
I have found maintainability is vastly more about the abstractions and architecture (modules and cohesive design etc) chosen than it is about the language.
Rust is extremely geared toward maintainability at the cost of other values such as learnability and iteration speed. Whether it’s successful is of course somewhat a matter of opinion (at least until we figure out how to do good quantitative studies on software maintainability), and it is of course possible to write brittle Rust code. But it does make a lot of common errors (including ones Go facilitates) hard or impossible to replicate.
It also strongly pushes toward specific types of abstractions and architectural decisions, which is pretty unique among mainstream languages, and is of course a large part of what critics dislike about it (since that’s extremely limiting compared to the freedom most languages give you). But the ability for the compiler to influence the high-level design and code organization is a large part of what makes Rust uniquely maintainability-focused, at least in theory.
Go has a heavy focus on simplicity and ease-of-use by hiding away complexity through abstractions, something that makes it an excellent language for getting to the minimum-viable-product point. Which I definitely applaud it for, it can be a true joy to code an initial implementation in it.
The issue with hiding complexity like such is when you reach the limit of the provided abstractions, something that will inevitably happen when your project reaches a certain size. For many languages (like C/C++, Ruby, Python, etc) there’s an option to - at that point - skip the abstractions and instead code directly against the underlying layers, but Go doesn’t actually have that option.
One result of this is that many enterprise-sized Go projects have had to - in pure desperation - hire the people who designed Go in the first place, just to get the necessary expertice to be able to continue development.
Another reason is kind of a general thing with programming language design: Go, like Java or C, has relatively few concepts in the language and stdlib. This means you’re relatively quick to have seen all of them.
But this also means that for various tasks, these concepts that were left out, would have been the right tool. For example, Go doesn’t have enums.
Generally, it’s still possible to create all possible programs, because of turing-completeness, but it will be more cumbersome and more boilerplate-heavy.
So, as a rule of thumb, the more concepts are provided by the language and stdlib, the more you have to learn upfront, but the less pain you have long-term.
Ananace and the article they linked are using their dislike of Go to conclude that it’s a bad language*. It is not a bad language. Every language has hidden complexity and foot guns. They don’t like Go. Maybe you won’t like Go. That’s ok. But that doesn’t make Go a bad language. The language designers are very opinionated and you might dislike them and their decisions.
I haven’t used Rust but from what I’ve seen, it’s a lot less readable than Go. And the only thing more important than readability is whether or not the code does what it’s supposed to do. For that reason I doubt I’ll ever use Rust outside of specific circumstances.
*I’m using “a bad language” as shorthand for “a language you shouldn’t use”. Maybe they don’t think it’s bad but amounts to the same thing.
Go really does do well in the zero-to-hero case, that’s for certain. Unfortunately it doesn’t fare nearly as well in terms of ease when it comes to continued development.
Is there a language that anyone would say really does fare well for continued development or is it just that few people enjoy maintaining code? I’ve maintained some pretty old Go programs I wrote and didn’t mind it at all. I’ve inherited some brand new ones and wanted to rage quit immediately. I’ve also hated my own code too, so it’s not just whether or not I wrote it.
I have found maintainability is vastly more about the abstractions and architecture (modules and cohesive design etc) chosen than it is about the language.
Rust is extremely geared toward maintainability at the cost of other values such as learnability and iteration speed. Whether it’s successful is of course somewhat a matter of opinion (at least until we figure out how to do good quantitative studies on software maintainability), and it is of course possible to write brittle Rust code. But it does make a lot of common errors (including ones Go facilitates) hard or impossible to replicate.
It also strongly pushes toward specific types of abstractions and architectural decisions, which is pretty unique among mainstream languages, and is of course a large part of what critics dislike about it (since that’s extremely limiting compared to the freedom most languages give you). But the ability for the compiler to influence the high-level design and code organization is a large part of what makes Rust uniquely maintainability-focused, at least in theory.
I’m a beginner in both (heavily leaning towards putting more time into learning Rust though). Could you please elaborate a bit?
Go has a heavy focus on simplicity and ease-of-use by hiding away complexity through abstractions, something that makes it an excellent language for getting to the minimum-viable-product point. Which I definitely applaud it for, it can be a true joy to code an initial implementation in it.
The issue with hiding complexity like such is when you reach the limit of the provided abstractions, something that will inevitably happen when your project reaches a certain size. For many languages (like C/C++, Ruby, Python, etc) there’s an option to - at that point - skip the abstractions and instead code directly against the underlying layers, but Go doesn’t actually have that option.
One result of this is that many enterprise-sized Go projects have had to - in pure desperation - hire the people who designed Go in the first place, just to get the necessary expertice to be able to continue development.
Here’s one example in the form of a blog - with some examples of where hidden complexity can cause issues in the longer term; https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride
Another reason is kind of a general thing with programming language design: Go, like Java or C, has relatively few concepts in the language and stdlib. This means you’re relatively quick to have seen all of them.
But this also means that for various tasks, these concepts that were left out, would have been the right tool. For example, Go doesn’t have enums.
Generally, it’s still possible to create all possible programs, because of turing-completeness, but it will be more cumbersome and more boilerplate-heavy.
So, as a rule of thumb, the more concepts are provided by the language and stdlib, the more you have to learn upfront, but the less pain you have long-term.
Ananace and the article they linked are using their dislike of Go to conclude that it’s a bad language*. It is not a bad language. Every language has hidden complexity and foot guns. They don’t like Go. Maybe you won’t like Go. That’s ok. But that doesn’t make Go a bad language. The language designers are very opinionated and you might dislike them and their decisions.
I haven’t used Rust but from what I’ve seen, it’s a lot less readable than Go. And the only thing more important than readability is whether or not the code does what it’s supposed to do. For that reason I doubt I’ll ever use Rust outside of specific circumstances.
*I’m using “a bad language” as shorthand for “a language you shouldn’t use”. Maybe they don’t think it’s bad but amounts to the same thing.
Isn’t that exactly what Rust is supposed to be good at
And conversely, something Go is very bad at. For example,
os.Chmod
silently not doing anything on Windows.