4 ms·
Warning: brain dump ahead. Broadly speaking, in any system, there is necessary complexity (imposed by the problem domain) and unncessary complexity (imposed by
by desc 7y ago
Warning: brain dump ahead.
Broadly speaking, in any system, there is necessary complexity (imposed by the problem domain) and unncessary complexity (imposed by the tools, the developers, the customer's interpretation of The Matrix, etc).
Go aims to minimise the latter, which is a worthy goal: I understand very personally how easily it is to add unnecessary complexity while trying to 'contain' the necessary complexity...
However, languages also provide useful and usable means to tame the necessary complexity. It's a tradeoff.
These days I try to write C# like Go: no IoC, composition over inheritance, specificity over genericity, etc. But enforcing those kinds of limitations at the language layer places a hard cap on the abstractions available later on.
To some extent, again, that's a good thing: far too many abstraction astronaut libraries in DotNet-land, spawned by someone's pet project getting overgeneralised. Such things need to be better considered and better contained within the developer group using them, unless they're extremely well-designed which is rare.
But if you remove the clean way to do something, people will do it anyway and it will be a mess. Quite probably in an 'edge' codebase, in a system where the senior devs have enough to deal with already, and the clique of devs looking after that particular edge develop their own little dialect of the language. (I don't care how much you think 'any dev can modify anything' in your code, if you've got more than ~10 devs you have 'preferred' people for certain areas, and some newbies will pick up some bits preferentially.)
Or you could give them a tool with higher-order concepts, and they'd be able to work within its idioms.
Restricting the available idioms just forces people to create new ones. You get doubleplus ungood code from that in fairly short order. Idioms get generated when the culture doesn't already have them, and the culture fragments according to the idioms its subcultures generate if they can't crosspollinate effectively.
Don't try to solve a social problem with technology. Solve it with education, discussion and code review instead. If you don't have time for that, you don't have time to fix the mess resulting from the technical solution either.
That said, the smaller the service the less likely that it's going to need to deal with higher-order abstractions. If you really are 'just' gluing together services in interesting ways (note that the filesystem is a service of sorts, and Git LFS is written in Go) and you can confine your code to solving specific problems, you probably don't need the higher order abstractions anyway.
In which case any other language could probably do the job too, to be honest, but they'd make it easier to sprawl... which brings us back to a language which puts an 'awkward' cap on making things sprawl.
Remember that it's very easy for a project to grow beyond its initial scope, and choice of language can encourage, enable, smother or doom that, and any of those outcomes can be good depending on your outlook...