Live data from Hacker News

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

chrismm.com

61–70 of 187 posts

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

#61
post #60

Code Complete is an old book now. Is it still good advice? In my new project I see a lot of code like below. I hate it but I'm not sure if I'm old fashioned or correct in thinking it should be 4 or five lines. Should I reject a code review for stuff like this? return (HadoopSummary)ScopeCoordinator.getInstance().findObject(Scope.getFirst(), new Path (SCOPE_PATH.split("\\.")));

I'm no stickler about pretty code but whatever that is looks disgusting!

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

#62

Some good previous discussion: Simple Ways of Reducing the Cognitive Load in Code https://news.ycombinator.com/item?id=11992684 My comment there is still relevant here: I've noticed recently that especially in online discussions, the term "cognitive load" is used as a catch-all excuse to rag on code that someone doesn't like. It appears to be a thought-terminating cliché. There's definitely room to talk about objecti…

Though your points seem (technically) on-point, you might be missing the one facet of the "cognitive load" concept that I think is the defining one:

as time marches on, entropy increases and in tech that means, cognitive load does. Every day there are new command-line tools and arguments and combinations and compositions, every week new languages, every quarter new syntax sugars in minor releases of major languages, every other year new major framework versions each with twice as many new libs/APIs as the previous release, etc etc .. even with Google and StackOverflow integrated into your hypercontextual IntelliSense etc IDE, it Just. Friggin. Grows. Out. Of. All. Control at least easily perceived so. Nevermind the constant stream of new NPM packages or fresh Haskeller-PhD papers. (And everything constantly sounds game-changing-as-heck too, funnily enough. Guess that happens when we all grow up around advertising ;)

Dead-simple "ELI5" code alleviates many headaches here, simply by not piling even more layers on top of all those we can't afford to ditch in the real world, much as we'd love to.

"Simple code" to "reduce cognitive load" was even an early helpful lesson for the id guys as shown a few days/weeks back: http://blog.felipe.rs/2017/02/25/id-software-programming-pri... --- and they had to deal with way fewer foreign/3rd-party baggage, writing Asm/C for DOS games that run just a tiny level above lowest.

At some point we'll all switch to Brainfuck: at least, there's only 8 primitives to keep in your mind at all times ;) seriously Assembly language is becoming ever more appealing. With fewer abstractions, you get more LoC but at least you grasp exactly what's meant to happen. Higher-level intent not so much, regrettably, unless commented of course.

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

#63

Earlier quoted context omitted.

How about: window .FindCanvasForObject(obj) .Color(RED) .MoveTo(10, 30) .LineTo(50, 20) This avoids the repetition of the local variable name, while still making it clear what's being called on the object.

But on what object? The fact that calling .MoveTo(10, 30) would return the same object it has been called on, and not, for example, a handle to created movement animation, is not exactly obvious. Modern pattern of methods which just return the objects that they've been called on, by default seems to be very trendy, but I fail to see how is it helpful.

Same way that you use any other API: by reading the docs. This is at least a very common pattern; it's highly likely that whoever maintains this code will have seen it before. And if you're using an IDE, the IDE will even tell you this as you hit '.'

BTW, it doesn't have to be the same object: if memory is abundant and CPU is not, it can often make sense to create a fresh object with each call. Doing this lets you share partially-constructed objects without worrying that mutation will result in surprising effects:

  let box = NewCanvas()
    .DrawLine(50, 0)
    .DrawLine(50, 50)
    .DrawLine(0, 50)
    .DrawLine(0, 0)
  let scene = [
    box.Fill(Color.RED).TranslateTo(200,300),
    box.Fill(Color.BLUE).TranslateTo(100, 300),
    box.Fill(Color.GREEN).TranslateTo(400, 500)
  ]
  scene.forEach(box => box.Draw())

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

#64

I like code that reads like a Dick & Jane book ("See Dick. See Jane. See Dick run. See Jane run."). However, it appears to be trendy to write insanely difficult to read code. To use the analogy, Shakespearean code. Instead of one line of code doing one thing the developers will write a ton of functionality into one line of code by using fluent and method chaining. As someone reviewing the code I have to keep this men…

I can't up-vote this enough. As someone that started doing development in the late 80's, I find this style of coding to be infuriating. It completely destroys the ability to map lines of code directly to function calls without resorting to manual coding rules that require that each .function() be on a separate line, and makes debugging way harder than it needs to be. And, for what purpose ? To avoid a local, temporar…

When learning C in college, I was specifically taught to use CONTSTANT == variable. Accidentally omitting a '=' is common and putting the constant on the left side ensured the compiler would catch the mistake.

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

#65

Earlier quoted context omitted.

But on what object? The fact that calling .MoveTo(10, 30) would return the same object it has been called on, and not, for example, a handle to created movement animation, is not exactly obvious. Modern pattern of methods which just return the objects that they've been called on, by default seems to be very trendy, but I fail to see how is it helpful.

Same way that you use any other API: by reading the docs. This is at least a very common pattern; it's highly likely that whoever maintains this code will have seen it before. And if you're using an IDE, the IDE will even tell you this as you hit '.' BTW, it doesn't have to be the same object: if memory is abundant and CPU is not, it can often make sense to create a fresh object with each call. Doing this lets you sh…

> Same way that you use any other API: by reading the docs.

Best APIs are written in such an obvious way that you don't need to read the docs to read the code and understand what's happening.

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

#66
post #29

I like code that reads like a Dick & Jane book ("See Dick. See Jane. See Dick run. See Jane run."). However, it appears to be trendy to write insanely difficult to read code. To use the analogy, Shakespearean code. Instead of one line of code doing one thing the developers will write a ton of functionality into one line of code by using fluent and method chaining. As someone reviewing the code I have to keep this men…

I love chaining, but one verb per line. Instead of something like Me.getFish.skin.debone.flour.salt.fry.eat It would be something like Me.getFish .skin .debone .flour .salt .fry .eat I find this more readable than doing it without chaining like this: fish = Me.getFish fish.skin fish.debone fish.flour fish.salt fish.fry Me.eat(fish)

personally I prefer without chaining, makes much more sense as its what I've always seen until the last ~5 years.

The other part you didn't mention is that you have to amend all the functions like getFish, skin etc to return the object which I think makes their signature unnecessarily less clear.

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

#67

Earlier quoted context omitted.

Same way that you use any other API: by reading the docs. This is at least a very common pattern; it's highly likely that whoever maintains this code will have seen it before. And if you're using an IDE, the IDE will even tell you this as you hit '.' BTW, it doesn't have to be the same object: if memory is abundant and CPU is not, it can often make sense to create a fresh object with each call. Doing this lets you sh…

> Same way that you use any other API: by reading the docs. Best APIs are written in such an obvious way that you don't need to read the docs to read the code and understand what's happening.

That doesn't apply to any of the code examples posted so far in this thread: they would all require documentation about side-effects, shared state, immediate vs. delayed effects, etc.

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

#68
post #2

I don't understand the first example. if (null != variable) If this was C, it should be NULL, and it is almost always better to just write `if (variable)` to check for NULL pointers instead. If this was JavaScript, this check includes undefined too. Not sure why it didn't use triple equal. If this was just talking about placing a constant value to be compared before a more complicated expression, I really don't see a…

Nowadays you should do it the readable way and let the compiler detect problems for you. If you use -Wall on any modern compiler, this will be caught.

There are some weird use cases when you actually want assignment in the condition statement, but all those cases could be added with an extra line, e.g. the valid statement:

    if(Foo* someFoo = getFoo()){
could just be replaced with

    Foo* someFoo = getFoo();
    if(someFoo){

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

#69

Earlier quoted context omitted.

You'll also find that some experienced programmers specifically turn 1 line into 5. It's the beginner that tries to create the 1 liner because they think it's genius.

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

Or:

validated_items = [x for x in items if is_validated(x)]

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

#70
post #68
post #2

I don't understand the first example. if (null != variable) If this was C, it should be NULL, and it is almost always better to just write `if (variable)` to check for NULL pointers instead. If this was JavaScript, this check includes undefined too. Not sure why it didn't use triple equal. If this was just talking about placing a constant value to be compared before a more complicated expression, I really don't see a…

Nowadays you should do it the readable way and let the compiler detect problems for you. If you use -Wall on any modern compiler, this will be caught. There are some weird use cases when you actually want assignment in the condition statement, but all those cases could be added with an extra line, e.g. the valid statement: if(Foo* someFoo = getFoo()){ could just be replaced with Foo* someFoo = getFoo(); if(someFoo){

The former constrains the scope of someFoo to if statement, while the latter does not. Minimizing variable scope is one of the things I find really helps reduce cognitive load, so I'm not sure I'd want to make that replacement.
Post reply on HN