Live data from Hacker News

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

seeinglogic.com

361–370 of 383 posts

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

#361
post #359

Earlier quoted context omitted.

Two space indentation is fairly common in C code bases. GNU projects use a kind of hybrid indentation where child statement are indented by two spaces, but if they are compound statements the indent their interior by another two spaces: if (proprietary(program)) roll_on_floor_twitching(stallman); else { calm_down(stallman); make_indent_weirdly(stallman, everyone); } Google’s style guides for various "C likes" also re…

Just because it's not uncommon doesn't mean it is not wrong, though! And it's still easier to see in C code than something with a bunch of angly parenthesis.

[deleted]

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

#362

Earlier quoted context omitted.

I'm more partial to the first one because it keeps a linear flow downwards, and a uniform structure. The second one kind of drifts off, and reshuffling parts of it is going to be … annoying. IME the dot style lends itself much better to restructuring. Depending on language you might also have some `.flat_map` option available to drop the `.reduce`.

True! Good point on the restructuring, I haven't thought about it in that way. I think I like the second approach because the loop behavior seems clearest, which helps me analyze the time complexity or when I want to skim the code quickly. A syntax like something below would be perfect for me if it existed: var favoriteFoodsOfFurryPetsOfFamousAuthorsOfLongChineseBooksAboutHistory = books[i].author.pets[j].favoriteFoo…

Hm, LINQ query syntax form is kinda going in that direction

  (from book in books
   where book.pagecount > 100 
        && book.language == "Chinese"
        && book.subject == "History"
        && book.author.mentions > 10_000
   from pet in book.author.pets
   where pet.is_furry == true
   select pet.favoriteFood)
  .Distinct()
But it also demonstrates the...erm, chronic "halfassedness" of LINQ's query syntax form with distinct() not available there and having to fall back to method syntax form anyway...

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

#363

Earlier quoted context omitted.

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 t…

> is an ex cathedra metaphysical claim I have a cargo ship-sized suspicion that your code is difficult to read for reasons other than intrinsic complexity. You’ve found a way to explain it to yourself and excuse it to others, but you won’t always be the smartest person in the room. Also that’s not what was said. > more then 5 seconds to read and understand the high level goal of a function Understanding what somethin…

If you find compact language above your level of proficiency confusing, you can literally ask an LLM to explain it for you to trade efficiency for accessibility.

You sound unhappy and seem to be lashing out, and your username can only be read as an allusion to a mentally ill would-be assassin. Given those, you can maybe begin to understand why your opinions are not credible as a contribution even in relation to other anonymous people.

A small part of your comment is salvageable, though:

> Understanding what something is for is not understanding how it accomplishes it

I can think of at least one area I know something about where the 5 second rule fails - sometimes when working on a shader and optimizations for it, it takes more than 5 seconds for the person who wrote the code to describe what it's for at a high level.

If even the person who wrote the code can't meet that arbitrary constraint, other people looking at the code for the first time have no chance.

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

#364

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…

>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…

I understand that you might find the mathematical notation clearer but I think it's presumptuous of you to speak on behalf of all humans, or even all human mathematicians. I'm a mathematics graduate and I find the conditional operator more readable in a program because it corresponds to what the program actually does (it checks the condition first); but I also recognize that the two notations have exactly the same information content and only differ superficially in syntax, making it entirely a matter of familiarity.

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

#365

Earlier quoted context omitted.

There is just no way that reasonable people consider this to be clearer. One certainly might be more familiar with this approach, but it is less clear by a long shot. You've added a temp variable for the result, manual appending to that temp variable (which introduces a performance regression from having to periodically grow the array), loop variables, unused variables, multiple layers of nesting, and conditional log…

> performance regression What? Golang append()s also periodically grow the slice. > Conditional logic it's just a single if, really, the same thing is there in your filter() > Multiple layers of nesting 2... You're talking it up like it's a pyramid of hell. For what it's worth, I've seen way way more nesting in usual FP-style code, especially with formatting tools doing func( args ) For longer elements of the functio…

> What? Golang append()s also periodically grow the slice.

If you already know the size of the result (there are no filtering operations), the functional approach can trivially allocate the resulting array to already have the correct capacity. This happens with zero user intervention.

IIRC the Rust optimizer basically emits more or less optimal machine code (including SIMD) for most forms of iteration.

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

#366

Earlier quoted context omitted.

> performance regression What? Golang append()s also periodically grow the slice. > Conditional logic it's just a single if, really, the same thing is there in your filter() > Multiple layers of nesting 2... You're talking it up like it's a pyramid of hell. For what it's worth, I've seen way way more nesting in usual FP-style code, especially with formatting tools doing func( args ) For longer elements of the functio…

> What? Golang append()s also periodically grow the slice. If you already know the size of the result (there are no filtering operations), the functional approach can trivially allocate the resulting array to already have the correct capacity. This happens with zero user intervention. IIRC the Rust optimizer basically emits more or less optimal machine code (including SIMD) for most forms of iteration.

We are talking about making an array with unique elements here. You cannot know the correct capacity for that without overallocating.

If overallocating is indeed OK for your usecase, then you can do so yourself

  uniq := make([]MyObject, 0, len(my_objects))

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

#367

Earlier quoted context omitted.

> The problem is that it's easy to overdo it. Welcome to all features of every programming language? Sacrificing readability, optimization, and simplicity for the 95% case because some un-principled developers might overdo it in the 5% case (when the cost of fixing it is trivially just inserting variable assignments) is… not a good trade-off.

5% is common enough that you'll encounter it almost every time you read code. And fixing it is not easy, because you first need to understand the code before you can add useful variable names. Besides, programming language evolution is mostly driven by the fact that everyone is lazy and unprincipled at least occasionally. If you need to be disciplined to avoid footguns, you'll trigger them sooner or later.

It's not clear what point you are trying to make because so far you are describing problems common to all programming languages.

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

#368
post #343
post #316

Earlier quoted context omitted.

To me the functional style is much more easy to parse as well. Maybe the lesson is that familiarity can be highly subjective. I for example prefer a well chosen one-liner list comprehension in python over a loop with temporary variables and nested if statements most of the time. That is because usually people who use the list comprehension do not program it with side effects, so I know this block of code, once unders…

> Maybe the lesson is that familiarity can be highly subjective. Over the years I've come to firmly believe that readability is highly subjective. And familiarity is a key contributor to that, but not the only one. There are other factors that I've found highly correlate with various personality traits and other preferences. In other words, people shouldn't make claims that one pattern is objectively more readable th…

Pragmatic, but good, advice that I would recommend anybody to follow in their daily pracrise.

However I'd defend the notion that on the bad end of things you can have such a thing as (objectively?) hard to read code. With "hard to read" I do not mean "nobody can figure it out with time", what I mean is, that figuring it out takes 99% of programmers longer than the equivalent in another language or style. As you rightly point out, it is important to realize that this is a statistical realization and not an universal law of nature, so it really matters on which cohort of people you look at and recommendations stemming from such observations should be taken with a grain of salt.

Yet, underneath all of that isn't there such a thing as truly objectively hard to read style? Brainfuck for example is an objectively hard to read language – they put that even into the name of the language. Does that mean there is not a single person who can read it fluently? Probably not, but that doesn't invalidate the point. A double black diamond ski track is objectively harder to ski, exactly because there are less people that are able to ski it.

If you see programming as working with language and symbols to achieve some behavior, it is clear that there are patterns who match more with the known (familiar) of most people. If you ask non-programmers or non-mathematicians how to describe some action in any way they like they will probably use their daily language. That means code that looks somewhat similar to how a regular person would write it down is surely on the "very familiar"-end of things. Now I did argue that maximum familiarity to regular people is not in itself a desireable goal, we need to make a tradeoff between familiarity and suitability to express program structures and operations. The latter is not how regular people think at all, so using them as an absolute guide isn't a good idea. However thinking about how to write things that they are both expressive in terms of programming behavior and easy to reason about is a desireable goal. There just isn't a single right way of doing that and sometimes good enough is just that.

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

#369

Earlier quoted context omitted.

Here's an abomination of my own design in Rust for example: for (index, node) in nodes .expect("Error: No blocks for the Body") .children() .expect("Error: blocks node has no children") .nodes() .iter() .enumerate() { let block = Block::new(node, index); self.blocks.push(block); }

Why the for loop instead of mapping the enumerate iterator into Block::new and collect::Vec?

I lack a good answer other than it didn't occur to me, now I have some code to refactor. Thanks!

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

#370
post #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 Cognitiv…

> But it's such a beautiful and powerful language. Sigh.

Don't give up. Half of the time when a good language has problems, it just means that the bad languages don't have those problems yet.

You don't need global type-inference and monads to run into your problem. Dynamic languages exist, and even the static ones usually have some kind of 'var x =' local type-inference. And collections like Set probably have a map function.

Post reply on HN