Live data from Hacker News

Writing good code: how to reduce the cognitive load of your code

chrismm.com

181–187 of 187 posts

Re: Writing good code: how to reduce the cognitive load of your code

#181

Earlier quoted context omitted.

> "filter" has to be the worst library name. I have no clue what it's doing unless I read the documentation It, I dunno, FILTERS a collection keeping only certain elements (those that match the filter)? What else would it possibly do? Besides a standard CS term, it's also a concept from real life... To me the name is crystal clear.

A filter creates two sets, one with the thing, and the other without. When you filter something, you might be interested in what is filtered in, or what is filtered out. Ponder for a second the phrases, "filtered water", "coffee filter", "camera filter", etc. In all of those cases, you are interested in the set without the filtered thing, not with. Compare this to "select" which is a much clearer name.

>Ponder for a second the phrases, "filtered water", "coffee filter", "camera filter", etc. In all of those cases, you are interested in the set without the filtered thing, not with.

Filtered is akin to "cleansed" (it refers to the "main body") not akin to "picked out" (which would have applied to the undesirable elements.

It's actually the water (or the light, in the case of camera filter) that's filtered (hence the name "filtered water" and not "filtered dust and detritus").

The other stuff is not what's being filtered -- just what's "filtered out".

Re: Writing good code: how to reduce the cognitive load of your code

#182

Hire programmers who can read. Lines like "Don’t use tools that are still too hard to get a grip on" are code for 'your team will get discouraged if they have to do any homework at all to understand your project'. If that's true, how do you expect them to understand the business requirements? Every large project has embedded tools and legacy tricks so the author is implicitly saying 'don't let projects scale'. Simpli…

This is my thought. I LIKE to read clever code. Most often than not it teaches me something. Some neat way to do x. It teaches how to write terse code and I'm probably going to learn how to apply that to other areas of my code.

I would be worried if my code is being reviewed by somebody who doesn't appreciate clever code.

Now, clever is different than complex, or confusing code. Clever code is a neat way to do something. Complex and confusing code can be spotted immediately because it does one or many of the following things:

- Functions get too nested

- Tries to do too much

- Function is too long

- Function is not broken into logical parts

- Confusing parts don't have their own function

- Long conditionals

- Non descriptive variable names

- Modifies state all over the place

And I could go on. Those are the things I would watch out for and that really take a cognitive load on me.

Also, clever code is different than tricky code. To try to use a programming language quirk is crazy. You're asking for your code to be hard to read. Using a little known useful feature is good way to extend your team knowledge of a PL.

Re: Writing good code: how to reduce the cognitive load of your code

#183
post #157

Earlier quoted context omitted.

Ruby version is a pretty clear one-liner: validated_items = items.select { |item| is_validated?(item) } Though I'd expect a check for validation to be an instance method, so it'd probably look like: validated_items = items.select(&:validated?)

Even if it's not an instance method you can write the first as validated_items = items.select(&method(:is_validated?)) (Typed on my phone but I'm pretty sure that's the right syntax)

It is! I'd forgotten about Kernel.method. Thanks!

Re: Writing good code: how to reduce the cognitive load of your code

#184
post #149
post #122

Earlier quoted context omitted.

Functional programming is inscrutable by most. Berkeley uses LISP as a flunk out class to weed out freshman. I find it odd that given in the physical world people require different shoe sizes for different feet that in the intellectual world people believe one size fits all, or that there is ultimately a single style of code that is comprehensible. Do you really believe our brains are all the same? The functional pro…

I always thought different paradigms suited different problem domains rather than different people. I'm not a software engineer by trade, but just for example, I've recently been mucking around making my own videogames and the object-oriented paradigm using the components pattern seems like a very natural way to conceptualise a videogame. E.g. Objects in the game (NPCs, environment) start as a basic object and are gi…

> I always thought different paradigms suited different problem domains rather than different people.

This. Any imperative program can be formally encoded as an immutable functional program, and vice-versa.

Therefore, which paradigm to choose is a matter of what style fits the problem at hand better, and how comfortable you are with the paradigm. But this is true of any coding convention.

Re: Writing good code: how to reduce the cognitive load of your code

#185

Whenever I read articles like this and the ensuing discussion that follows, I'm reminded of this quote from Dijkstra: Don't blame me for the fact that competent programming, as I view it as an intellectual possibility, will be too difficult for "the average programmer" — you must not fall into the trap of rejecting a surgical technique because it is beyond the capabilities of the barber in his shop around the corner.…

Meh. I think you're overshooting the runway a bit here. I'm a functional coder and I like the idea of reducing cognitive load. The procedural guys use it in a different fashion but if you're writing code you can't understand after walking away for a few months and coming back? You're doing something wrong. I don't think that relates to the abstraction or composability of your solution style. I find good naming, decom…

yeah, I'm always amazed at the people who claim they looked at code they wrote 6 months ago and think it's horrible.

I've looked at code I wrote 2-3 years ago, and upon examination thought to myself "that's fairly reasonable code, I got most of it right".

I see people claim that means you're not growing as a developer, but my growth is about being able to build larger and more complex systems rather than perfecting small snippets of code. In other words, I've stopped caring about the specifics of code (within reason), and I get better at building systems.

Re: Writing good code: how to reduce the cognitive load of your code

#186

Earlier quoted context omitted.

One-liners are bad if they are obscure and experienced programmers know that. However I wouldn't go as far as say that experienced programmers don't use one-liners at all. As usual in programming, it's all about balancing clarity/conciseness. For example, I find this much clearer as a one-liner (Python): validated_items = filter(is_validated, items) rather than validated_items = [] for item in items: if is_validated(…

"filter" has to be the worst library name. I have no clue what it's doing unless I read the documentation. On the other hand "append" feels like a much more conventional and comprehensible name.

I agree with you that `filter` is less explicit than something like `copy_if` (C++).

Does it return elements matching the predicate or not matching it? I struggled with this for a while in CS.

After learning different programming languages and getting some field experience I noticed that the `filter` pattern is pretty common in the programming world. It's one of those pervasive functional patterns that are so practical that they were included at some point in imperative languages.

Re: Writing good code: how to reduce the cognitive load of your code

#187
post #137

Earlier quoted context omitted.

> That's because no one even knows how to start doing "science" in this direction I am sorry to disagree, but this is just not true. http://www.ptidej.net/courses/inf6306/fall10/slides/course8/... http://www.cs.kent.edu/~jmaletic/papers/EMSE12.pdf https://link.springer.com/journal/10664 https://scholar.google.com/citations?view_op=view_citation&h... I have to say this: https://brains-on-code.github.io/shorter-identif…

There's nothing to be sorry about, actually, I'm really happy to learn that such research is being done! I tried searching for similar studies quite a few years back and came back empty-handed, so I assumed it's either not done at all or is very niche. As you seem to be knowledgeable about the field, how relevant/applicable you think the studies you linked to are in the general case? In the study about identifier len…

klibertp,

> another thought on the study: does it control for presence or absence of widely known conventions?

I am very happy to encounter other critical thinkers - your question is a really good one :) You are right, the study is not capable of explaining this effect (that is, how commonplace / conventional some abbreviations are), but it was considered in the design. I am sure that this plays an effect but I wouldn't dare to give a definitive answer based on the data from my study.

For example, config or cfg are arguably so common that there they don't hurt comprehension. Similar for single letter variables. Point.x and point.y are easily identifyable as coordinates. Or the variable name i in a for loop may not be problematic, as it becomes almost meta-syntactic (much like foo and bar). However, i,j,k,l index names may really hurt comprehension, when you have a complicated looping strucutre with many lines in between, as they are likely to strain your working memory. As for the point.x example: I would explain this as a priming effect. The name of x is fine, because point already preactivates the right direction. X in isolation might be worse, and if you encounter new MessageBrokerInstance().X() you might as well read your code in base64... Thus, based on my experiment, I can talk about variables in isolation, but usually, code is mixed and here, other effects might be relevant.

In the longer versions of my experiment, I considered the effect of common abbreviations as well. Psychology lists several word frequency effects. Common words can be immediately accessed *(from the so called mental lexicon, a mind-dictionary if you will), but uncommon words have to be synthesized on the fly though their phonetics (see, for example the dual route cascade model, coltheart 2001, http://www.cogsci.mq.edu.au/~ssaunder/files/DRC-PsychReview2...). Thus, high-frequency words (=often occuring, common words or strings) are quickly read and their meaning is understood, whereas uncommon words or strings do not have a representation in the mental lexicon and you have to synthesize their meaning first, thus slowing down comprehension.

My argument is simple: It is always possible to understand code, no matter how mangeled or obfuscated it is (after all, reverse engineers are doing amazingly hard work). The question is how easyly the code can be comprehended. Abbreviations that are common to some (e.g. experts), may not be common to others (e.g. novices in their first job). Of course, the newbies will get there eventually, but abbreviations have a higher learning curve, thus new people will be unproductive for a longer time.

Think about yourself, you surely know this effect:

1. Write code. 2. Problem solved 3. don't touch it for 4 months 4. Changes needed, need to fix bug, add feature 5. How does this work? 6. Wtf, what was I thinking?

For the sake of all newbies, your company, or even your own, I encourage the use of identifiers that can be read, because you can READ and know LANGUAGE, and not because of arbitrary conventions. There are many conventions (e.g. x:xs, for i=0;i> how relevant/applicable you think the studies you linked to are in the general case?

This is really hard to say. Many processes take place when programming, and many programmers have theories about why it is hard and how to make it easier (as the entry article citing cognitive load, which is a good methaphor, imho). So far, I know of many such scientists who are trying to isolate the different effects. For example, I am focused on identifier names, as I find them to be impactful. Their meaning can't be analyzed automatically (even with sound nlp techniques which are relatively limited), and the programmer is totally free to name their variable names what ever the hell they want. I am sure that in comprehension of programs, identifier names play a big role, but when I encounter "clever code", with weird recursions, counterintuitive measures, or plain magic (https://en.wikipedia.org/wiki/Fast_inverse_square_root) the value of identifiers are limited, or, in other words, there are other things going on that impact my comprehension BESIDES identifiers. How they interact, I cannot say for sure, but if complex code has no clear identifiers, it becomes complicated.

I believe that each of the effects in isolation is relevant, but I am not sure which one is the most dominant, or, for that matter, whether there is ONE thing that will solve all problems.

Post reply on HN