3 ms·
I don't think "screen real estate" is the right argument here. The problem is just that every line creates cognitive load and there's a tradeoff between concis
by lamontcg 5y ago
I don't think "screen real estate" is the right argument here.
The problem is just that every line creates cognitive load and there's a tradeoff between concision and descriptiveness.
A language with piles of syntactic sugar and magic gets it wrong with too much concision and can read like line noise when it gets overused.
Go goes the other way though and makes it way too verbose and just makes it difficult to read the code. When a method needs to have 6 different error handling clauses in it, then it isn't as clear that 5 of those just bubble up the error while one of them has some unique handling. It also increases the chances that some programmer copypastas the boilerplate bubble-up code to all six of those cases and it sails through PR review. You can write a static analysis linter to force programmers to always handle errors and not ignore them, but you can't force them to handle errors correctly. When humans are reading the code, concision helps and verbosity hurts -- up until that crossover point where magic causes readability to suffer.
Go programmers seem to focus on abhoring magic and rejecting the benefits of concision. But when it comes to PR review your job is to stare at the whole method (or the whole file) and be able to "see" the bug, and more lines of code will make this job more difficult (and is also why some of the recommendations of the "clean code" book are pretty bad since extracting more tiny little methods can harm overall readability). There's a happy optimum somewhere where cognitive load is minimized. That isn't attained though by just having the simplest language design possible and offloading complexity into more verbose code.
- throwaway894345 5y agoI disagree. IMO, there's much more cognitive load in parsing dense, "minified" code than there is in scanning code whose control flow mirrors its visual structure. Humans are very good at seeing visual structure (which is why we tend to indent, split code across lines, and other syntactically insignificant usage of whitespace). By convention in most mainstream programming languages, this visual structure mirrors code flow, so we can see the control flow at a glance; however, many languages have special hidden control flow (exceptions) or control flow which is otherwise isn't part of the visual structure and thus easily overlooked at a glance (e.g., Rust's `?`). In my opinion, this "hidden" control flow allows more errors to slip past reviewers (though some languages might recoup some quality by other means).
- lamontcg 5y agoI mean I spent quite a few words talking about how there's a happy optimum where beyond that you start to get too much magic and code gets too terse and unreadable. You just did prove my point though which is that this is the only argument that Go programmers consider, and they blindly reject that adding more lines of code can harm readability.
- throwaway894345 5y ago> You just did prove my point though which is that this is the only argument that Go programmers consider, and they blindly reject that adding more lines of code can harm readability. Can we lower the rhetorical temperature a notch? Just because someone disagrees with you doesn't mean they're "blindly rejecting" your reasoning. In particular, I'm not just a Go programmer--I've used Java, C#, Python, JS, C++, and C in various professional over the course of my career and I've also played around with dozens of other languages and I have more experience with several of those languages than I have with Go. My opinions are shaped by those other languages at least as much as they're shaped by Go, and indeed I didn't start out having these "pro-Go" opinions--rather, I adopted them over time after allowing my preconceptions to be challenged. Note also that some of my preconceptions haven't changed--I still think sum types and enforced handling of return values are a good idea, for example.
- lamontcg 5y agoI was never arguing for "minified" code, which is ridiculous. Lower your own rhetorical temperature.
- throwaway894345 5y agoI don't know how you interpreted "minified" in any disparaging way, but that was never my intent. I apologize for any emotion that stirred up.
- eweise 5y agoI don't think not handling errors after every single method call, makes the code dense. Its just way easier to read. 99% of the time you're just going to wrap the error in your own error and return so why not just have a single place that does that?
- preseinger 5y agoCognitive load is unrelated to SLoC. This expression let a = x.iter().filter(...).apply(...).map(...); is equally or even potentially _more_ cognitively complex than this expression for _, v := range x { if !filter(v) { continue } vv := apply(v, ...) vm := map(vv, ...) ... }
- lamontcg 5y agofocusing on a pedantic detail that i clearly didn't intend and which doesn't change my point. consider it from a blocks-of-code metric, or some better slightly more abstract metric, that isn't affect by simple things like whitespace transformations, and try assuming that we all understand that we should write code that isn't monstrous to begin with.
- preseinger 5y ago"Monstrous" is an opinion, not a metric. I would personally much rather maintain the code in the second example than in the first.