Live data from Hacker News

Cognitive load is what matters

github.com

431–440 of 552 posts

Re: Cognitive load is what matters

#431

This was my main takeaway from A Philosophy Of Software Design by John Ousterhout. It is the best book on this subject and I recommend it to every software developer. Basically, you should aim to minimise complexity in software design, but importantly, complexity is defined as "how difficult is it to make changes to it". "How difficult" is largely determined by the amount of cognitive load necessary to understand it.

It’s a pain in the ass to source a copy of this book without giving Jeff Bezos all the money. If anyone reading this thread knows John, could you bring this to his attention? I even tried calling the bookstore on his campus and they said try back at the beginning of a semester, they didn’t have any copies. My local book store could not source me a copy, and neither IIRC could Powell’s.

did you try here?: https://www.abebooks.com/book-search/publisher/yaknyam-press...

Re: Cognitive load is what matters

#432
post #299

Earlier quoted context omitted.

This is a trap junior devs fall into DRY isn't free it can be premature optimization since in order to avoid copying code you often add both an abstraction AND couple components together that are logically separate. The issues are at some point they may have slightly different requirements and if done repeatedly you can get to a point that you have all these small layers of abstraction that are cross cutting concerns…

The reverse of that is people introducing bugs because code that wasn't DRY enough was only changed in some of the places that needed to be changed instead of all the places. To me, it's the things that are specifically intended to behave the same should be kept DRY.

An obvious example of that is defining named constants and referring them by name instead of repeating the same value in N places. This is also DRY and good kind of DRY.

Re: Cognitive load is what matters

#433

Earlier quoted context omitted.

It's one message I struggle to convey to people I do code reviews for: don't make me understand it, make it more self explanatory so every reader does. (And, yes, I ask for it explicitly too) (I sometimes "ask" questions for something it took me a few back and forths through code to get so they'd think about how it could be made clearer) Unfortunately, most people focus on explaining their frame of mind (insecurity?)…

Yeah, not easy, but it helps to build some rapport first, so people learn what you’re after. The way I tend to do that is by leaving a review comment with an example code snippet that makes me understand it better, and a question “what do you think about this version? I tried to clarify a few things here.”. + Explain what was clarified. I find the effort usually pays off.

But this might require too much effort from the reviewer

Re: Cognitive load is what matters

#434

Earlier quoted context omitted.

I think the most common way to approach that problem would be to have a "default config", and overrides. Could you go into more detail about why you didn't do this instead? Downsides with your approach is: 1. Now whenever you want to change something both in Europe and (assuming) USA you have to do it in 2 places. If the change is the same for both, in my system, you could just update the default/shared config. If th…

I don’t do this because with a complete copy I get progressive rollouts across regions without the complexity of if statements and feature flags. That is to say, making the change twice is a feature not a bug when the changes are staggered in time. From an operational perspective it’s much more important to ensure the code is clear and readable during an incident. Overrides are like inheritance. They are themselves c…

The "rules" for config are different. Code, test code, and config are different, their complexity scales in different ways of course.

By way of analogy for why the two configs are different, for example Two beaches are not the same because they both have very similar sand.

You really have two different configs.. You also have one set of configs. You didn't set up an application that also fetches some config that is already provided. It would be like having a test flag in both config and database, sane flag - two places.

Where config duplication goes bad is when repeatedly the same change is made across all N, local variations have to be reconciled each time and it is N sets of testing you need to do. Something like that in code is potentially more complex, more obviously a duplication of a module, just more likely to be a problem overall.

Re: Cognitive load is what matters

#435

This was my main takeaway from A Philosophy Of Software Design by John Ousterhout. It is the best book on this subject and I recommend it to every software developer. Basically, you should aim to minimise complexity in software design, but importantly, complexity is defined as "how difficult is it to make changes to it". "How difficult" is largely determined by the amount of cognitive load necessary to understand it.

I'm struggling with the amount of complexity. As an inexperienced SWE, I found it difficult to put everything into my head when the # of function calls (A) + # of source code files (B) to navigate reach N. In particular, if B >= 3 or A >= 3 -- because, B equals the number of screens I need to view all source code files without Command+Tab/Alt+Tab, and cognitive load increases when A increases, especially when some "p…

Experience helps to recognize intent sooner. That reduces cognitive load. Getting lost 5 levels deep seemingly never stops being a thing, not just you.

Re: Cognitive load is what matters

#436
post #361

Earlier quoted context omitted.

> Every rule can be used to argue anything. Unless it's a rule prohibiting complexity by removing technologies. Here's a set of rules I have in my head. 1. No multithreading. (See Mozilla's "You must be this high" sign) 2. No visitor pattern. (See grug oriented development) 3. No observer pattern. (See django when signals need to run in a particular order) 4. No custom DSL's. (I need to add a new operator, damnit, an…

Visitor pattern is extremely useful in some areas, such as compiler development.

That’s only true in languages that do not have Algebraic Data Types and pattern matching, which nowadays is a minority of languages (even Java has it).

Re: Cognitive load is what matters

#437

It's always interesting that many people who push the cognitive load argument also push for simpler languages. To me once I have learned a language well the features it has don't add to the cognitive load. they become basically second nature. It even has a great benefit, many things that are explicit in simple languages because there is no language support fall away in more complex languages. So more complex language…

>So more complex languages reduce cognitive load, at least for me.

Even C++ and all it's crazy features of last 5-10 years?

Re: Cognitive load is what matters

#438

Earlier quoted context omitted.

DRY isn't about not reimplementing things; it's about not literally copying and pasting code. Which I have seen all the time, and which some might find easier now but will definitely make the system harder to change (correctly) at some point later on.

I’ll bite. We’re expanding into Europe. I literally copied and pasted our entire infrastructure into a new folder named “Europe” Now there’s a new requirement that only applies to Europe and nowhere else and it’s super easy and straight forward to change the infrastructure. I don’t see how it was a poor choice to literally copy and paste configs that result in hundreds of thousands of lines of yaml and I have 25 yoe.

> I don’t see how it was a poor choice to literally copy and paste configs that result in hundreds of thousands of lines of yaml

Perhaps one day you will. I'm a dev who worked with infra people who had your philosophy: many copy pasted config files.

Sometimes I needed to add an env var to a service. Expressing "default to false and only set it to true in these three environments" took changing about 30 files. I always made mistakes (usually of omission), and the infra people only ever caught them at deployment time. It was hell.

Re: Cognitive load is what matters

#439

This was my main takeaway from A Philosophy Of Software Design by John Ousterhout. It is the best book on this subject and I recommend it to every software developer. Basically, you should aim to minimise complexity in software design, but importantly, complexity is defined as "how difficult is it to make changes to it". "How difficult" is largely determined by the amount of cognitive load necessary to understand it.

I'm struggling with the amount of complexity. As an inexperienced SWE, I found it difficult to put everything into my head when the # of function calls (A) + # of source code files (B) to navigate reach N. In particular, if B >= 3 or A >= 3 -- because, B equals the number of screens I need to view all source code files without Command+Tab/Alt+Tab, and cognitive load increases when A increases, especially when some "p…

You should not need to read every line of code in every file and function to understand what’s going on to the level you need to solve a particular problem. You must make a decision to NOT look deeper at some point on any non- trivial code base. A good program with good names and comments in the appropriate places is what allows you to do exactly that more easily . When you see sort(usernames) in the middle of a function do you need to dive into sort to be able to understand the code in that function?? Probably not, unless you are fixing a bug in how usernames are sorted!

With that said , get good at jumping into definitions, finding all implementations, then jumping back where you were. With a good IDE you can do that at the speed of thought (in IntelliJ that’s Cmb+b, Cmd+Alt+b, Cmd+[ on Mac). I only open more than one file at the same time when comparing them. Otherwise it’s much easier to jump around back and forth (you can even open another function inline if you just want to take a Quick Look, it’s Alt+Space). Don’t use the mouse to do that, things you do all the time can be made an order of magnitude faster via shortcuts. Too many developers I see struggle with that and are embarrassingly slow moving around the code base!

Re: Cognitive load is what matters

#440

I think most programmers agree that simpler solutions (generally matching "lower cognitive load") are preferred, but the disagreements start about which ones are simpler: often a lower cognitive load comes with approaches one is more used to, or familiar with; when the mental models one has match those in the code. For instance, the article itself suggests to use early/premature returns, while they are sometimes comp…

> For instance, the article itself suggests to use early/premature returns

I like premature returns and think they reduce complexity, but as exclipy writes (I think quoting Ousterhout) 'complexity is defined as "how difficult is it to make changes to it"'.

If premature returns are the only premature exit your language has then they add complexity in that you can't then add code (in just one place) that is always executed before returning.

A good language will also have "break" from any block of code, such that the break can also carry a return value, AND the break can be from any number of nested blocks, which would generally mean that blocks can be labelled / named. And also of course that any block can have a return value.

So you don't actually need a distinguished "return" but only a "break" that can be from the main block of the function.

A nice way to do this is the "exit function", especially if the exit function is a first class value and can also exit from called functions. (of course they need to be in a nested scope or have the exit function passed to them somehow).

It is also nice to allow each block to have a "cleanup" section, so that adding an action to happen on every exit doesn't require wrapping the block in another block, but this is just a convenience, not a necessity.

Note that this is quite different to exception handling try / catch / finally (Java terms) though it can be used to implement exception handling.

Post reply on HN