Live data from Hacker News

What makes code hard to read: Visual patterns of complexity (2023)

seeinglogic.com

131–140 of 383 posts

Re: What makes code hard to read: Visual patterns of complexity (2023)

#131
post #115
post #109

> Chaining together map/reduce/filter and other functional programming constructs (lambdas, iterators, comprehensions) may be concise, but long/multiple chains hurt readability This is not at all implied by anything else in the article. This feels like a common "I'm unfamiliar with it so it's bad" gripe that the author just sneaked in. Once you become a little familiar with it, it's usually far easier to both read an…

authors_of_long_books = set() for book in books: if len(book.pages) > 1000: authors_of_long_books.add(book.author) return authors_of_long_books You are told explicitly at the beginning what the type of the result will be, you see that it's a single pass over books and that we're matching based on page count. There are no intermediate results to think about and no function call overhead. When you read it out loud it's…

also it's natural, clear, and in the right order

That isn't natural to anyone who is not intimately familiar with procedural programming. The language-natural phrasing would be "which of these books have more than thousand pages? Can you give me their authors?" -- which maps much closer to the parent's linq query than to your code.

Re: What makes code hard to read: Visual patterns of complexity (2023)

#132
post #65

I think the only one I disagree with here is the function chains example. I may agree with a different example, but with this one I find the chained version without variables much easier to understand because I'm traversing the graph visually in my head, while the variables are additional state I have to keep track of in my head. ---- Really I was hoping this would be about actual visual patterns and not syntax. It's…

Vertical alignments really makes me want to create a devtool stack that operates at more of an AST level and less of an "monospaced text + extra bells and whistles" level.

Aligning similar expressions for ease of reading seems like exactly the sort of thing an editor should display for us without requiring some arbitrary number of spaces to be stored in a text file ...

Re: What makes code hard to read: Visual patterns of complexity (2023)

#133
post #61

My pet peeve: function getOddness4(n: number): if (n % 2 === 0): return "Even"; return "Odd"; While it is shorter, I prefer vastly prefer this one: function getOddness2(n: number): if (n % 2 === 0): return "Even"; else: return "Odd"; Reason: getOddness4 gives some sense of asymmetry, whereas "Even" and "Odd" are symmetric choices. getOddness2 is in that respect straightforward.

  function getOddness(n: number):
    return (n % 2 === 0)
      ? "Even"
      : "Odd";
Lowest boilerplate makes it the most readable. If working in a language with the ternary operator it ought to be easily recognized!

Re: What makes code hard to read: Visual patterns of complexity (2023)

#134
post #28

There is a (large, I believe) aspect of good code that is fundamentally qualitative & almost literary. This annoys a lot of computer programmers (and academics) who are inclined to the mathematical mindset and want quantitative answers instead. I love dostoyevsky and wodehouse, both wrote very well, but also very differently. While I don't think coding is quite that open a playing field, I have worked on good code ba…

I consider code bad if it takes more then 5 seconds to read and understand the high level goal of a function. Doesn't matter how it looks. If its not possible to understand what a function accomplishes within a reasonable amount of time (without requiring hours upon hours of development experience), it's simply bad.

Sounds like you are content to limit yourself to problems that do not contain more irreducible complexity or require more developer context than what fits within five seconds of comprehension.

That's a good rule for straightforward CRUD apps and single-purpose backend systems, but as a universal declaration, "it is simply bad" is an ex cathedra metaphysical claim from someone who has mistaken their home village for the entirety of the universe.

Re: What makes code hard to read: Visual patterns of complexity (2023)

#135
post #115
post #109

> Chaining together map/reduce/filter and other functional programming constructs (lambdas, iterators, comprehensions) may be concise, but long/multiple chains hurt readability This is not at all implied by anything else in the article. This feels like a common "I'm unfamiliar with it so it's bad" gripe that the author just sneaked in. Once you become a little familiar with it, it's usually far easier to both read an…

authors_of_long_books = set() for book in books: if len(book.pages) > 1000: authors_of_long_books.add(book.author) return authors_of_long_books You are told explicitly at the beginning what the type of the result will be, you see that it's a single pass over books and that we're matching based on page count. There are no intermediate results to think about and no function call overhead. When you read it out loud it's…

Much of both sides of this argument are opinion, but wrt this comment.

> ... no function call overhead.

This code has more function calls. O(n) vs 3 for the original

Re: What makes code hard to read: Visual patterns of complexity (2023)

#136
post #131
post #115

Earlier quoted context omitted.

authors_of_long_books = set() for book in books: if len(book.pages) > 1000: authors_of_long_books.add(book.author) return authors_of_long_books You are told explicitly at the beginning what the type of the result will be, you see that it's a single pass over books and that we're matching based on page count. There are no intermediate results to think about and no function call overhead. When you read it out loud it's…

also it's natural, clear, and in the right order That isn't natural to anyone who is not intimately familiar with procedural programming. The language-natural phrasing would be "which of these books have more than thousand pages? Can you give me their authors?" -- which maps much closer to the parent's linq query than to your code.

That isn't natural to anyone who is not intimately familiar with procedural programming.

This is not about "procedural programming" - this is exactly how this works mentally. For kicks I just asked me 11-year old kid to write down names of all the books behind her desk (20-ish) of them and give me names of authors of books that are 200 pages or more. She "procedurally"

1. took a book

2. flipped to last page to see page count

3. wrote the name of the author if page count was more than 20

The procedural is natural, it is clear and it is in the right order

Re: What makes code hard to read: Visual patterns of complexity (2023)

#137
post #135
post #115

Earlier quoted context omitted.

authors_of_long_books = set() for book in books: if len(book.pages) > 1000: authors_of_long_books.add(book.author) return authors_of_long_books You are told explicitly at the beginning what the type of the result will be, you see that it's a single pass over books and that we're matching based on page count. There are no intermediate results to think about and no function call overhead. When you read it out loud it's…

Much of both sides of this argument are opinion, but wrt this comment. > ... no function call overhead. This code has more function calls. O(n) vs 3 for the original

[deleted]

Re: What makes code hard to read: Visual patterns of complexity (2023)

#138
post #131

Earlier quoted context omitted.

also it's natural, clear, and in the right order That isn't natural to anyone who is not intimately familiar with procedural programming. The language-natural phrasing would be "which of these books have more than thousand pages? Can you give me their authors?" -- which maps much closer to the parent's linq query than to your code.

That isn't natural to anyone who is not intimately familiar with procedural programming. This is not about "procedural programming" - this is exactly how this works mentally. For kicks I just asked me 11-year old kid to write down names of all the books behind her desk (20-ish) of them and give me names of authors of books that are 200 pages or more. She "procedurally" 1. took a book 2. flipped to last page to see pa…

You are describing how to execute the procedure, while the gp is describing what the result should be. Both are valuable, but they're very different.

My personal take is that "how to execute" is more useful for lower level and finer grained control, which "what the results should be" is better for wrangling complex logic

Re: What makes code hard to read: Visual patterns of complexity (2023)

#139
post #131

Earlier quoted context omitted.

also it's natural, clear, and in the right order That isn't natural to anyone who is not intimately familiar with procedural programming. The language-natural phrasing would be "which of these books have more than thousand pages? Can you give me their authors?" -- which maps much closer to the parent's linq query than to your code.

That isn't natural to anyone who is not intimately familiar with procedural programming. This is not about "procedural programming" - this is exactly how this works mentally. For kicks I just asked me 11-year old kid to write down names of all the books behind her desk (20-ish) of them and give me names of authors of books that are 200 pages or more. She "procedurally" 1. took a book 2. flipped to last page to see pa…

That's when you're doing the job, not what the mental representation of the solution. I strongly believe if you ask her to describe the task, she would go:

1. (Take the books)->(that have 200 pages or more)->(and mark down the name of the authors)->(only once)

Re: What makes code hard to read: Visual patterns of complexity (2023)

#140
post #57

Earlier quoted context omitted.

I found this example troubling because once all the line noise is added, first-op second-op third-op fourth-op fifth-op sixth-op feels so much more impenetrable than - first-op - second-op - third-op - fourth-op - fifth-op - sixth-op The point of functional styles isn't purely brevity (as implied by the commentary around this example), it also puts a focus on the clear sequence of operations and helps reduce "operato…

IME what we want is generally for the code to be close to the left margin and flow predictably downwards. The example with intermediate values has a lot more value to me for complex instantiations, where we can avoid nesting like it's json or yaml by using some helper variables. That problem is fundamentally the same as with deeply nested if/while/try/etc: It gets hard to visually tell what's in which scope. (Rainbow…

Agree with you completely. I'm not against intermediate variables (though I tend to appreciate the way comments separate context from code, more than my hardline "code should be self-documenting" colleagues do). But I don't think they should come at the cost of textual clarity.

I think you could look at this through a "dimensional" lens. I'm ok with linear dot chains (or even better, pipe chains) – you read operations top to bottom. I'm also ok with single line chains where they fit, especially when contained neatly in a single-line function – in this case operations read left to right. But the second form in this example forces you to read operations top-to-bottom AND left-to-right at once, creating a 2-dimensional "wall of noise" effect for me. I'd expect the issues compound as ops are added, instead of increasing linearly with chain syntax. All very subjective and familiarity-dependent of course.

Post reply on HN