Live data from Hacker News

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

seeinglogic.com

91–100 of 383 posts

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

#91
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.

This is what xmldoc/jsdoc/etc are for. If it's not 100% obvious from the name, put a summary of the function's assumptions, side effects, output, and possibly an example in the comment-doc. If you do this right, the next programmer will never have to read your source at all (or even navigate to your file! They'll hover over a method call or find it in the dot-autocomplete and see a little tootip with this documentation in it, and know all they need to know). It's an incredible thing when it works. It's a little bit more effort but I don't accept the FUD around "comments become out of date immediately because the code will change" etc. - that should be part of code review.

https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

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

#92
post #38
post #28

Earlier quoted context omitted.

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.

> I consider code bad if it takes more then 5 seconds to read and understand the high level goal of a function. That's something that's possible only for fairly trivial logic, though. Real code needs to be built on an internal "language" reflecting its invariants and data model and that's not something you can see with a microscope. IMHO obsessive attention to microscope qualities (endless style nitpicking in code re…

I agree with this up to a point - having consistent code style with some sort of formatter (gofmt, black, clang-format) goes a long way to reducing complexity of understanding because it unifies visual style.

I suggest that a codebase should read like a newspaper. While there is room for op-eds in the paper, it's not all op-eds, everything else should read as a single voice.

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

#93
I always shrugged off the concept of code metrics (from LoCs to coverage) as a distraction from getting actual things done. But since doing more code-review I started to lack a framework to properly explain why a particular piece of code smells. I sympathize with the way the author cautiously approaches any quantitative metrics and talks of them more like heuristics. I agree that both Halstead Complexity and Cognitive Complexity are useless as absolute values. But they can be brought up in a conversation about a potential refactoring for readability.

What I didn't find is a mention of a context when reading a particular function. For example, while programming in Scala I was burnt more than once by one particular anti-pattern.

Suppose you have a collection of items which have some numerical property and you want a simple sum of that numbers. Think of shopping cart items with VAT tax on them, or portfolio positions each with a PnL number. Scala with monads and type inference makes it easy and subjectively elegant to write e.g.

  val totalVAT = items.map(_.vat).sum
But if `items` were a `Set[]` and some of the items happened to have the same tax on them, you would get a Set of numbers and a wrong sum in the end.

You could append to the list of such things until the OutOfMemoryError. But it's such a beautiful and powerful language. Sigh.

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

#94
post #75

Earlier quoted context omitted.

>This annoys a lot of computer programmers (and academics) who are inclined to the mathematical mindset and want quantitative answers instead. I find many syntactical patterns that are considered elegant to be the opposite, and not as clear as mathematics, actually. For example, the the ternary operator mentioned in the article `return n % 2 === 0 ?'Even' : 'Odd;` feels very backwards to my human brain. It's better s…

Well of course if you have the freedom to write a mathematical expression you're going to be able to present it in a way that is clearer than if you have to type monospace characters into a text editor. I'm not sure it's realistic to expect to be able to type a mathematical expression using ascii more clearly than you can write it by hand (or implement using special unicode characters).

Quite some years back I worked with JetBrains MPS which used a "projectional editor" instead of a text editor. It was pretty neat to be able to enter "code" as mathematical expressions, or even state machine tables or flow diagrams with actual nodes instead of a text representation.

Sadly not much has happened in that space since then, but it was cool to think about what our tools of the future might look like. (of course ignoring all the practical reasons why we're probably still using regular text files in 100 years)

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

#95

Earlier quoted context omitted.

I find Literate Programming interesting partly because it’s almost the opposite of the much-advocated “many small functions” style. You could literally be writing a book that explains your program, and the code becomes almost secondary material to illustrate the main text rather than the main asset itself. I did once write a moderately substantial application as a literate Haskell program. I found that the pros and c…

The Axiom computer algebra folks seem to manage well --- I'm pretty sure that's the largest publicly available literate program which is available for inspection. I've been working to maintain a list of Literate Programs which have been published (as well as books about the process): https://www.goodreads.com/review/list/21394355-william-adams... I'd be glad of any I missed, or other links to literate programs. The l…

Another not on the list is Scheme 9 from Empty Space. I can't speak to its quality though as I've never looked at the resulting book, just perused the stripped source a little a while back.

https://www.t3x.org/s9fes/

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

#96
post #79

Do people really really agree with "Shorthand constructs that combine statements decreases difficulty"? The author even identifies a problem with the example from the original guide.

Everyone agrees that well made shorthand constructs decreases difficulty, since every programmer uses those every day. Things like function calls, while loops etc are all shorthands for different kinds of jump statements combined with register manipulation. Even assembly uses some of those, and I don't think anyone seriously codes in machine code.

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

#97
I just wanted to point out that "Cognitive Complexity" [1] was not invented by SonarSource, it is an academic principle created in the 1950s and has more to do with psychology than computer science. Computer science has over-simplified the term to mean "hey there's a lot of stuff to remember this is hard".

Psychology tends to have a wider scope of thought and research put into it [2] [3]. For example, one way it's used is not to measure how complex something is, but how capable one particular person is at understanding complex things, versus a different human [4]. This can affect everything from leadership decisions [5] to belief in climate change [6].

I point this out because all too often Engineers hyper-focus on technical details and forget to step back and consider a wider array of factors and impacts - which, ironically, is what cognitive complexity is all about. It's the ability of a person to think about more things in a deeper way. Basically, cognitive complexity is a way to talk about not just things, but people.

We also have a tendency as Engineers to try to treat everyone and everything as a blob. We have to design our language in X way, because all people supposedly work in the same way, or think the same way. Or we have to manage our code in a certain way, because all the team members are assumed to work better that way (usually in whatever way is either easier or simpler).

One thing I wish people would take away from this, is that not only is cognitive complexity actually useful (it describes how language is able to work at all), but some people are better at it than others. So "avoiding cognitive complexity" is, in many ways, a bad thing. It's like avoiding using language to convey ideas. Language and communication is hard, but you're reading this right now, aren't you? Would you rather a pictogram?

[1] https://en.wikipedia.org/wiki/Cognitive_complexity [2] https://www.jstor.org/stable/2785779 [3] https://pubmed.ncbi.nlm.nih.gov/11014712/ [4] https://testing123.education.mn.gov/cs/groups/educ/documents... [5] https://deepblue.lib.umich.edu/handle/2027.42/128994 [6] https://www.sciencedirect.com/science/article/abs/pii/S02724...

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

#98
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.

I would add a blank line to push 'return "Odd";' from the if, and also add brackets around the if-body if the language allows.

There are situations where I allow else, they tend to have side effects, but usually I refactor until I get rid of it because it'll come out clearer than it was. Commonly something rather convoluted turns into a sequence of guards where execution can bail ordered based on importance or execution cost. It isolates the actual function/method logic from the exit conditions.

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

#99

Maybe it's just me, but TypeScript makes code hard to read. It's fine if the data model is kept somewhat "atomic" and devs are diligent about actually declaring and documenting types (on my own projects, I'm super diligent about this). But once types start deriving from types using utility functions and then devs slack and fall back to type inference (because they skip an explicit type), it really starts to unravel b…

I'd prefer to have some type information over nothing if the choice were between TypeScript with some inferred return types, versus JavaScript where you're never really sure and constantly have to walk back up/down the stack and keep it in your mind.

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

#100
post #39
post #28

Earlier quoted context omitted.

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.

There is a call-stack depth problem here that is specific to codebases though. For one familiar with the the conventions, key data abstractions (not just data model but convention of how models are structured and relate) and key code abstractions, a well formed function is easy to understand. But someone relatively new to the codebase will need to take a bunch of time switching between levels to know what can be assu…

the purpose of the function should be clear from its name. if its too complex to convey this information it should have a docstring that clearly explains what it does. it's not rocket science
Post reply on HN