Live data from Hacker News

Cognitive load is what matters

github.com

501–510 of 552 posts

Re: Cognitive load is what matters

#501

Earlier quoted context omitted.

Most programmers can't make much sense of the output of a C compiler, either. We'll all be in that boat before long. (To anticipate the usual reaction when I point that out: if you're going to sputter with rage and say that compilers are deterministic while AI isn't, well... save it for a future argument with someone who can be convinced that it matters.)

on the other hand, I'd love to read an argument that persuades me that determinism doesn't matter in this case because I can't form any mental model that makes determinism-ed-ness a non factor in my decision making. of course, this comes with a disclaimer that I have no experience as a vibe coder lol

Real-world code bases are already far too large for any one programmer to internalize. They might as well be uninspectable. This problem isn't going to get anything but worse in the years to come. Incremental improvements in languages and methodologies won't suffice; future systems will simply have to be designed differently. They will be based on very high-level descriptions that can be used to synthesize tests that programs written and maintained by AI models can satisfy.

Human involvement will end after the first phase, once the required test targets exist.

Basically we are going to have to stop micromanaging our toolchains and start telling them what outcomes we want. Call it "vibe coding lol" or whatever, that's how it's going to work. When you write code in a traditional high-level language, you are telling your compiler how to generate the code that actually gets executed by the CPU. But this object code, again, might as well be completely inaccessible as far as most developers are concerned. If the compiler were to achieve the same result in different, unknowable ways each time it runs, that's a horrifying notion to those same developers... but we all might as well get used to it, because soon there will be no other way forward.

Notice that the math guys are already having to deal with similar problems. Mochizuki or somebody drops a thousand-page proof on the community, and experts at the very highest levels have to waste years looking for bugs in it. They can't go on like this and they know it. They will have to give up the quaint idea of understanding something completely in order to prove or refute it, just as programmers and engineers will have to relinquish control over how our own creations work.

Re: Cognitive load is what matters

#502

Earlier quoted context omitted.

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.

I found that to be a double edged sword: some copy and paste it verbatim without thinking it through and adjusting at all. It's a delicate balance we need to keep in mind between many of: - maintainable code - getting things done - feeling of accomplishment - feedback loop speed - coaching - motivation and emotional state ("why are they pestering me, the code works, I just want to feel productive and useful: this was…

Yeah, this does require a certain team culture building effort. Just starting cold without any expectation-setting might not be received well.

One "rule" I try to meta-promote is — working code is the first step, and a great foundation to then proceed to clear and maintainable code.

Another, is that code reviews are first-class citizens deserving mindfulness.

Re: Cognitive load is what matters

#503
post #474

Earlier quoted context omitted.

> one would have to look up what "isSecure" means, while "(condition4 && !condition5)" would have shown it at once You would feel the need to look up a variable called isSecure , but would not need to look up condition4 or condition5 ? I think the point TFA was making is that one could read isSecure and assume what kind of implementation to expect, whereas with condition4 I wouldn't even know what to look for, or I'd…

> isSecure = user.role == 'admin' I would rather name intermediate variables to match the statement rather than some possible intent, it's basically a form of semantic compression. For example isAdminUser = user.role == 'admin' - here we are hiding away the use of roles which is not relevant for the conditional, but isSecure can mean anything, we don't want to hide the concept of being an admin user, just the details…

Not the GP. I agree that you can always find a better name, as the old joke goes, naming things is hard.

That said, there is a significant difference in cognitive load between isSecure and isAdminUser to condition4.

I've had the pleasure of debugging a piece of code that was something like:

     if (temp2 && temp17) temp5 = 1;
In the end, I gave up, and just reimplemented it, after studying in detal about what its expected inputs and outputs were. (note: this was before the time unit tests were the norm, so it was painful).

Re: Cognitive load is what matters

#504

Earlier quoted context omitted.

> one would have to look up what "isSecure" means, while "(condition4 && !condition5)" would have shown it at once You would feel the need to look up a variable called isSecure , but would not need to look up condition4 or condition5 ? I think the point TFA was making is that one could read isSecure and assume what kind of implementation to expect, whereas with condition4 I wouldn't even know what to look for, or I'd…

> You would feel the need to look up a variable called isSecure, but would not need to look up condition4 or condition5? I assume that those "conditions" are placeholders, not to be read literally in the example (since the example is not about poorly named variables, but about complex conditions), so I did not mean them literally, either. Supposedly those would be more informative names, such as "channel_encrypted",…

Well, from my experience, as well as from tools figuring out complexity of functions (so, seems to be accepted and not my personal preference), nested ifs add to cognitive load.

So, we know that early returns are easier to understand.

In a lot of code reviews, I am in debates how to name things. I know the juniors are cross with me, as if it's bike shedding, but it's important for clarity when reading/debugging.

--- Disregard: I also have to disagree with you on HTTP error codes. Those are well documented and cannot be counted as obscure and unnecessary knowledge that not everybody needs to understand. They have to. It's their freaking job. If they don't, they should not write nor review any HTTP related code.--

EDIT: Above paragraph: It seems I misread you comment, sorry.

Re: Cognitive load is what matters

#505

Love it. Make code accessibility a first-class citizen. Turn the rule books and their principles into guidelines . A smart coder knows to follow rules. A master knows code is meant to be read and develops contextual awareness for when and why to break a rule, or augment it, as the case may be. So, reintroduce judgment and critical thinking in your coding practice. Develop an intuitive feel for the cognitive costs and…

> Make code accessibility a first-class citizen. This is a good article but the main thing that bugs me about it is that the author completely disregards germane overhead. Germane overhead is about recognition and practice and, at scale, it matters just as much. Intrinsic and extraneous overhead is about the information itself and how it’s presented. Germane overhead is about the receiver so in order to make code acc…

You might have opened the article thinking that it was going to be a discussion on cognitive load theory in general. It's not and I don't believe it needed to be for its purpose, since it's been well framed: code. Intrinsic, extraneous, germane loads? Why talk in abstract? The field of professional programming is an exemplar that evidences all those concepts. We pretty much live the theory. Programming is inherently complicated, we know how/why. We tend to needlessly add to the complexity, we know how/why. We are also notoriously ignorant, oblivious even, of our minds' true limitations and have strange beliefs regarding our abilities. Check, check, and check. Article can just speak plainly. "Don't make complicated things more complicated than they need to be. You're only human".

Re: Cognitive load is what matters

#506

Earlier quoted context omitted.

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

AbeBooks has been a subsidiary of Amazon since 2008. (Sure, this wouldn’t give Jeff B. “all the money”, but neither would that seller’s listing on Amazon.)

Re: Cognitive load is what matters

#507

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…

> programmers agree that simpler solutions...are preferred, but the disagreements start about which ones are simpler Low ego wins. 1. Given: The quality of a codebase as a whole is greatly affected by its level of consistency + cohesiveness 2. Therefore: The best codebases are created by groups that either (1) internally have similar taste or (2) are comprised of low ego people willing to bend their will to the estab…

I don't think this necessarily is accurate I've come into a lot of projects that no one understands well, but everyone continues to follow the same bad conventions that already exist which just adds to the problems. Ex: deep nesting, no early exit, deep object inheritance.. this happens because a lot of developers don't want to rock the boat, AND because they don't have the skills to unwind the complexity in a manageable amount of time without also causing serious problems.

Re: Cognitive load is what matters

#508
post #504

Earlier quoted context omitted.

> You would feel the need to look up a variable called isSecure, but would not need to look up condition4 or condition5? I assume that those "conditions" are placeholders, not to be read literally in the example (since the example is not about poorly named variables, but about complex conditions), so I did not mean them literally, either. Supposedly those would be more informative names, such as "channel_encrypted",…

Well, from my experience, as well as from tools figuring out complexity of functions (so, seems to be accepted and not my personal preference), nested ifs add to cognitive load. So, we know that early returns are easier to understand. In a lot of code reviews, I am in debates how to name things. I know the juniors are cross with me, as if it's bike shedding, but it's important for clarity when reading/debugging. ---…

Are you arguing against simplicity being subjective, or as a tangent, with the topics brought up as examples (particularly advocating early returns)? I already mentioned that I view it as subjective, so perhaps as an illustration of that, it is worthwhile to point out why I do not find early/premature returns simpler (and would not consider it as knowledge that they are easier to understand for everyone, though acknowledging that those must be easier for some). I work primarily with Haskell in the past decade, and occasionally other functional languages, which have no such return and break statements (not counting their emulation, as whole imperative languages can be emulated; and neither does lambda calculus have those, which is the simpler model one usually has in mind while working with functional languages), operating on expressions, so I am rather used to control flow mostly following the syntactic structure (and I dislike exceptions for that reason: I find that they make control flow more confusing). Sometimes I do use early returns in imperative languages, though often I still prefer to use a "ret" variable in those, setting it instead of returning, and returning it in the very end of a function, so that the correspondence between code structure and control flow is maintained, and the code can be read and thought of more like Haskell or Scheme, rather than like assembly or C with goto. Which, I think, helps to avoid confusion: adding an early return statement and making the function to skip some cleanup in the end (particularly in lower-level languages), or adding a cleanup and forgetting that there is an early return already in place above it, looks like an easy way to introduce a bug. As an example of me not being the only crazy person, there is the NASA C style guide [0] with a section on the return statement, and I recall online articles along those lines as well (as mentioned above, comparing those to goto). I do not claim that this is the one true view/approach, but there it is, existing.

As a bonus (an additional example of differing views on simplicity), even goto itself is still in use these days, with some advocating its use, and others (famously) arguing against it, both camps using some kind of a simplicity (or complexity of the opposing approach) as an argument.

[0] https://ntrs.nasa.gov/api/citations/19950022400/downloads/19...

Re: Cognitive load is what matters

#509
post #497
post #327

Earlier quoted context omitted.

I like to make truth tables for understanding piles of ifs. Like there's 5 ifs with 5 different conditions - so I make 5 columns and 32 rows, and enumerate all the possible combinations of these 5 ifs and write what happens for each. And then what should happen. Of course, the disadvantage is the exponential growth. 20 ifs means a million cases (usually less because the conditions aren't independent, but still). Then…

Often you can check validity one time before everything else. 5 bools might only actually be valid in 7 possible combinations instead of 32. Convert in one place to a 7 element enum and handle with exhaustive switch statements everywhere else can sometimes be a lot cleaner. Making invalid data unrepresentable simplifies so much code. It's not always possible but it is way underused. You can do some of it with object…

> Making invalid data unrepresentable simplifies so much code

That's the dream. Error handling is what crushes it :)

Re: Cognitive load is what matters

#510
post #225

Earlier quoted context omitted.

> "A single order ships to a single address, keep it simple, build it, oh actually, a salesman promised a big customer, so now we need to make it so a single order can ship to multiple addresses"--you've heard something like this before, haven't you? I don't see the problem. Okay, so we need to support multiple addresses for orders. We can add a relationship table between the Orders and ShippingAddresses tables, fix…

> I don't see the problem. Okay, so we need to support multiple addresses for orders. We can add a relationship table between the Orders and ShippingAddresses tables Which items ship to each of those locations and in which quantities? What is the status of each of those sub-orders in the fulfillment process? Should the orders actually ship to those addresses or should the cartons just be packed and marked for those l…

You're completely right, those are things that need to be considered and accounted for if necessary. Maybe a different solution would be better, like leaving the orders the way they are but adding new table CompoundOrders or something.

The details don't really matter for my main point though. The point is you don't solve this problem with workarounds. You find a way to redesign the system to suit your new needs - assuming the business thinks that's worth it. That's like our whole job, we build systems and when they need to change we change them. The only question is how we make those changes - do we do it properly or do we add workarounds until our codebase is a big pile of workarounds?

Post reply on HN