It's very rare that I come across weird patterns or someone trying to be very clever. Its always straightforward code.
It's very rare that I come across weird patterns or someone trying to be very clever. Its always straightforward code.
Is Go perfect at this? No. I too would love to see some higher level functions exist for to help reduce boilerplate. For example, this proposal: https://github.com/golang/go/issues/45955 to add Filter, Map, etc. to slices. That seems like a practical set of functions to add to minimize boilerplate while at the same time not breaking away from simple idioms.
That depends entirely on what style of programming you're most accustomed to. I've primarily written functional code the past several years, and even in that relatively short time, it's become for me in general easier to read chained/piped/composed function expressions than equivalent loops.
But sure, I can understand if you don't want that flexibility in Go. It's a fair position if you want the language to be confined to a certain imperative style of programming.
However, it's interesting to note that even if one can do loop-based imperative programming in Haskell and OCaml if one so desires, it's not idiomatic. Presumably, same would apply in Go.
I'm not a fan, but it fits with google's goal when creating the language.
For devs who want a more functional approach, there are a number of alternatives, including Rust (which is not a fully functional language, but has many aspects thereof).
With Go, it's usually pretty straightforward. Yes, there are interfaces, but they're used in places where people actually want the choice of code to be dynamic, rather than people just having fun building up crazy hierarchies in the name of DRY.
So, with Go I find it very easy to read because of high code locality and the ease of following to the correct destination with function calls.
For things that are already local, "ease of reading" is just code for "familiar". Go is strictly easier to read because tracing through is strictly simpler. Anything else is just spelling and those barriers disappear with only minimal experience.
In go, you can either do this as a nested for loop, which is harder to read and n^2 instead of n, or explicitly loop over each iterator and convert to a map (which, to be fair, is exactly what python does too), and then write the map-diffing yourself, which is easy to screw up and should probably be thoroughly tested to ensure you didn't make any mistakes in your implementation.
In python its one line of clear, expressive, known-to-be-correct, code. Granted the generics proposal should do a lot to improve things here, but I disagree that go is "strictly easier", because there's often far more to trace through, as there is far less abstraction provided for you by the language, so instead of having to perhaps unwind a single complex expression that uses some advanced language features, you have to unwind the pseduo-reimplementation of those abstractions in the local project.
Fewer constructs for the price of higher Signal-to-Noise ratio.
Go eschews almost any kind of syntactic sugar that might be unfamiliar to you.
The endemic "if err != return err" issue is also highly indicative of this choice.
I really find that quite hard to stomach. For small apps, this can be acceptable, but for any Go app that gets large enough, this trade-off becomes untenable. You have to scan through too much visual noise to get a clear understanding what the code is doing.
I used to write Python. I was very happy writing Python but dealing with other peoples Python bullshit is not something I miss.
Even beyond the question of self hosting, I would say that it's rare for much of a scripting language's standard library to be written in that language... especially performance critical parts of the standard library. There would just be too much performance left on the table.
The person you're responding to specifically mentioned they came from JavaScript, where the standard library implementations weren't written in JavaScript.
(PyPy is a notable exception to this rule of thumb... perhaps as part of its desire to prove how good the JIT is, it seems to be mostly written in Python, which is neat.)
I used to work on a team that maintained a large Perl codebase: Perl can be both expressive and terse which decreases readability, especially at times when a colleague felt like expressing their cleverness/individuality in a 'brilliant' one-liner using obscure language features. When the clever code is buggy, you'd have to fix the edge-cases in an even more 'cleverer' way, or unroll it into a readable function.
But expressiveness, when used correctly, can also improve reability. Which is more readable?
longNames := users.filter(x -> len(x.name) > 10)
longNames := make([]User)
for _, x := range users {
if len(x.name) > 10 {
longNames := append(longNames, x.name)
}
}
The only world in which the second example is more readable is one where developers never heard of filter, but have fully memorized (and are not confused by) all 3 variants of make(), the strange syntax of append (including all of its shared data pitfalls) and just got used to mentally parsing this behemoth pattern above as "filter".This world is probably real in some corners of the wider world where Go is used, but it is not the only possible world, and I don't think it's a good one.
In theory there's no difference between theory and practice. In practice Go is a lot younger than Haskell, to take that as some kind of comparison, and there seem to be a lot more successful projects written in Go despite that. I like Haskell, I haven't even be bothered to learn Go yet on my own. But lets be sensible about readability. Simplicity almost always wins or at worst ties, as in the simple filter above.
Everyone writing serious Haskell tends to end up writing new additions to the standard library to make it work. Reading Haskell can be challenging on this basis. There absolutely is pyrotechnical showing off. I don't see this kind of issue at all in Go - for good or ill. I'd be astounded if Go is 5% of the fun of writing Haskell. I'd be more likely to choose Go than Haskell if I have a large project than needs to work in short-ish amount of time. (And when isn't the amount of time short-ish?)
We use Ruby/Rails and Go pretty heavily at work it's much easier to jump in and grok Go code than rails (written by the same engineers mind you).
Go removes abstractions (to a fault sometimes) so, anecdotally, it's pretty damn easy to just read and figure out what's happening.