Live data from Hacker News

Cognitive load is what matters

github.com

351–360 of 552 posts

Re: Cognitive load is what matters

#351

The ability to create code that imposes low cognitive load on others not only is a rare and difficult skill to cultivate- it takes active effort and persistence to do even for someone who already has the ability and motivation. I think fundamentally the developer is computing a mental compression of the core ideas - distilling them to their essence - and then making sure that the code exposes only the minimum essenti…

I think one issue is that some people just find very different things intuitive. Low cognitive load for one person might be high cognitive load for another.

Because of some quirk of the way my brain works, giant functions with thousands of lines of code doesn't really present a high cognitive load for me, while lots of smaller functions do. My "working memory" is very low (so I have trouble seeing the "big picture" while hopping from function to function), while "looking through a ton of text" comes relatively easily to me.

I have coworkers who tend to use functional programming, and even though it's been years now and I technically understand it, it always presents a ton of friction for me, where I have to stop and spend a while figuring out exactly what the code is saying (and "mentally translating" it into a form that makes more sense to me). I don't think this is necessarily because their code inherently presents a higher cognitive load - I think it's easier for them to mentally process it, while my brain has an easier time with looking at a lot of lines of code, provided the logic within is very simple.

Re: Cognitive load is what matters

#352
post #299

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.

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…

All my younger colleagues have heard my catchphrase:

Copy-paste is free; abstractions are expensive.

Re: Cognitive load is what matters

#353

I'm probably one of the "smart developers" with quirks. I try to build abstractions. I'm both bothered and intrigued by the industry returning to, what I call, "pile-of-if-statements architecture". It's really easy to think it's simple, and it's really easy to think you understand, and it's really easy to close your assigned Jira tickets; so I understand why people like it. People get assigned a task, they look aroun…

I think one issue you can run into with clever abstractions is that it can be harder to fix/change them if something is wrong with their fundamental assumptions (or those assumptions change later). Something like this happened at my work a while back, where if I had written the code it would have probably just involved a few really long/ugly functions (but only required changing a few lines in and after the SQL query to fix), but instead the logic was so deeply intertwined with the code structure that there wasn't any simple way to fix it without straight-up rewriting the code (it was written in a functional way with a bunch of functions taking other functions as arguments and giving functions as output, which also made debugging really tough).

It also depends how big the consequences to failure/bugs are. Sometimes bugs just aren't a huge deal, so it's a worthwhile trade-off to make development easier in change for potentially increasing the chance of them appearing.

Re: Cognitive load is what matters

#354

Earlier quoted context omitted.

Which is why I consider DRY (Don't Repeat Yourself) to be an anti-rule until an application is fairly well understood and multiple versions exist. DO repeat yourself, and do not create some smart version of what you think the problem is before you're attempting the 3rd version. Version 1 is how you figure out the problem space, version 2 is how you figure out your solution as a maintainable dynamic thing within a cha…

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.

Re: Cognitive load is what matters

#355

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.

Only half joking: I don’t think I trust a book from an author who has inflicted decades of TCL pain on me (and on the entire community of EDA tool users.)

I know you're only half joking, but I don't think you can pin the blame on John or TCL. Osterhaut's thesis, as I recall, was that there is real benefit to having multiple programming languages working at different levels of the domain (e.g. a scriptable system with the core written in a lower level language). Of course now this is a widespread practice in many domains (e.g. web browsers, numerical computing: matlab, numpy). It's an idea that has stood the test of time. TCL is just one way of achieving that aim, but at the time it was one of few open-source options available. I think scheme/lisp would have been the obvious alternative. AutoDesk went in that direction.

I remember using TCL in the 90s for my own projects as an embeddable command language. The main selling point was that it was a relatively widely understood scripting language with an easily embeddable off-the-shelf open source code base, perhaps one of the first of its kind (ignoring lisps.) Of course the limitations soon became clear. Only a few years later I had high hopes that Python would become a successor, but it went in a different direction and became significantly more difficult to embed in other applications than was TCL -- it just wasn't a primary use case for the core Python project. The modern TCL-equivalent is Lua, definitely a step up from TCL, but I think if EDA tools used Lua there would be plenty of hand-wringing too.

Just guessing, but I imagine that at the time TCL was adopted within EDA tools there were few alternatives. And once TCL was established it was going to be very hard to replace. Even if you ignore inertia at the EDA vendors, I can't imagine hardware engineers (or anyone with a job to do) wanting to switch languages every two to five years like some developers seem happy to do. It's a hard sell all around.

I reckon the best you can do is blame the vendors for (a) not choosing a more fit-for purpose language at the outset, which probably means Scheme, or inventing their own, (b) or not ripping the bandaid off at some point and switching to a more fit-for-purpose language. Blaming (b) is tough though, even today selecting an embedded application language is vexed: you want something that has good affordances as a language, is widely used and documented, easily embedded, and long-term stable. Almost everything I can think of fails the long term stability test (Python, JavaScript, even Lua which does not maintain backward compatibility between releases).

Re: Cognitive load is what matters

#356

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 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 the change is different for both it's equally easy, but faster, since the overrides are smaller files.

2. It's not clear what the difference is between Europe and USA if there is 1 line different amongst thousands. If there are more differences in the future, it becomes increasingly difficult to tell the difference easily.

3. If in the future you also need to add Africa, you just compounded the problems of 1. and 2.

Re: Cognitive load is what matters

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

This is the correct take - if you're getting this type of bug, it's now past time for DRY

Re: Cognitive load is what matters

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

If you notice that two parts of the code look similar, but have a good reason not to merge or refactor, that deserves a signpost comment. If you're copying and pasting something, there probably isn't a good reason for that. (The best common reason I can think of is "the language / framework demands so much boilerplate to reuse this little bit of code that it's a net loss" — which is still a bad feeling.) If you rewri…

I don't think it's as cut and dry as that. In my team we require 100% test coverage. Every file requires an accompanying test file, and every test file is set up with a bunch of mocks.

Sure, we could take the Foo, Bar, and Baz tables that share 80-90% of common logic and have them inherit from a common, shared, abstract component. We've discussed it in the past. Maybe it's the better solution, maybe not. But it would mean that instead of maintaining 3 component files and 3 test file, which are very similar, and when we need to change something it is often a copy-paste job, instead we'd have to maintain 2 additional files for the shared component, and when that has to change, it would require more work as we then have to add more to the other 3 files.

Such setups can often cause a cascade of tests that need updated and PRs with dozens of files changed.

Also, there are many parts of our project where things could be done much better if we were making them from scratch. But, 6 years of changing requirements and new features and this is what we have - and at this point, I'm not sure that having a shared component would actually make things easier unless we rewrite a huge amount of the codebase, for which there is no business reason.

Re: Cognitive load is what matters

#359
post #328

Earlier quoted context omitted.

I’m accustomed to this principle as a musician, so it’s been interesting to see it withstand my journey into software.

Can you expand on this?

Not the commenter, but also had experience with making music and writing software. I think the same applies to any creative endeavor. It’s super hard to consume what you produce as “someone else” (I.e. read what you write, listen to what you compose with fresh perspective). Usually it takes time to forget and disassociate from your work, because you get too used to it while producing it. Coming back to it another day can work sometimes, but very quickly you’ll get used to it again. I think this is one of the most effective ways to achieve quality tasteful results in anything. If you can train yourself to read your own code with fresh eyes almost as soon as you write it, you’d be unlocking a powerful shortcut, a cheat code to life. It’ll make the biggest impact on your code’s (and any other creative work’s) quality. This is also why sometimes you can spend hours painstakingly trying to design something, and it comes out terrible, nobody likes it. And you can do something in 20 minutes just improvising your way through, and it comes out an elegant masterpiece. That’s because you never gave yourself time to “get used to” your work such that you couldn’t perceive the problems with it anymore. You maintained that fresh impatient perspective the entire time.

Re: Cognitive load is what matters

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

All my younger colleagues have heard my catchphrase: Copy-paste is free; abstractions are expensive.

One of the many great takeaways from Sandi Metz's talk at Railsconf 2014: "Duplication is far cheaper than the wrong abstraction."

https://www.youtube.com/watch?v=8bZh5LMaSmE

Worth watching in its entirety, but the quote is from ~13:59 in that video.

Post reply on HN