4 ms·
> Clarity is critical. When you need to write high performance code this is a great maxim. I enjoy the simplicity of Go and the guarantees it provides. Being a
by squiguy7 10y ago
> Clarity is critical.
When you need to write high performance code this is a great maxim. I enjoy the simplicity of Go and the guarantees it provides. Being able to reason about code and not having to guess is a win for any development team.
- ridiculous_fish 10y agoIME, clarity and reasoning are weak points of Go, relative to other systems programming languages (but perhaps not to dynamic languages): 1. Slices make it hard to reason about aliasing. bar = append(foo, val): does bar now alias foo? The answer is the worst possible: "sometimes." 2. Closure semantics make it hard to reason about thread safety. I converted this serial loop to parallel using goroutines; did I introduce a race condition? I have to look at each variable to decide. (Any sort of const capturing would go a long way here). 3. Goroutine leaks can be hard to reason about. For example, a channel that is not sufficiently buffered can result in a leak. 4. Nullable maps and channels reduce clarity. 5. The "redeclare" semantics means := sometimes does not introduce a new variable
- squiguy7 10y agoI didn't mean to gloss over the go routine problems. You're absolutely correct, when there exist tools like the race detector it makes it evident that you can write incorrect concurrent programs. Becoming proficient at using the concurrency patterns in Go takes time but it is an advanced topic. Thanks for writing up these common mistakes.
- colin_mccabe 10y agoThose aren't common mistakes, just things he dislikes about the language. For example, I don't care whether := sometimes does not introduce a new variable (have never had a bug related to that). I don't find the closure semantics any worse than Java's (sure Java requires captured variables to be final, but it doesn't require them to be immutable). I find append's semantics to be pretty intuitive. But then again, I'm familiar with realloc in C, which is where it came from. At any rate, slices are references to an underlying array. If you are making one slice from another slice in a way that potentially doesn't involve copying, you should expect the new thing to alias the old thing. People often complain about channels having limited buffer sizes. But if channels had unlimited buffering, they'd complain about memory leaks and inefficiency. A list of common mistakes in Go would be interesting. It would probably start with the "assigning a typed nil value to an interface leads to interface != nil" wart.
- blub 10y agoThey seem to be language issues which make development more error-prone. And dismissing them just like that won't make them go away :)