Live data from Hacker News

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

chrismm.com

51–60 of 187 posts

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

#51

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…

> And, don't get me started on: if = ...

That seems to be quite the pet peeve with many and I quite like the style in certain scenarios: namely the common one where the constant is a simple literal and the variable portion is a longer (no, not excessively long, just.. longer ;) chain of things, a call within a call or some operator etc. It's as if to signal "there is some crunching/intricacy here but look, it's just to check against this simple value here right at the start". Kinda reassuring. Likewise find it quite readable for checking for magic strings / code-monikers (of course to be avoided but sometimes not when dealing with certain input formats etc) and especially when a couple of such in a row are tested..

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

#52
post #30

Earlier quoted context omitted.

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…

To get you started, I'd like to compare my problems regarding `if = ` with yours. This assumes you aren't the kind of lunatic to actually assign a constant inside of an if's condition. 1. I can't articulate exactly why, but that should totally be flipped. The constant should be on the right side! `if(3.17 == possiblyPi)` would make me seriously question the author's motives. 2. It's personal preference, but in almost…

> 3.17 == possiblyPi

Seems bad style to me, but also contrived. Whereas

> PI == validate(parseFloat(fetchUserInput({ timeout: minutes(1), defaultOnCancel: 0.0 })))

as pseudo-code example seems rather more insta-grokkable to me than flipped. Get my drift? And it's lit==varExpr

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

#53

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…

Hmm -- you're talking about programming in the small, as in line-by-line style.

Cognitive load also affects devs at the scale of a whole project, i.e. understanding how the program fits together across different modules, across state changes and across time.

What's the dick & jane solution for project-scale organization?

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

#54
post #51

Earlier quoted context omitted.

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…

> And, don't get me started on: if = ... That seems to be quite the pet peeve with many and I quite like the style in certain scenarios: namely the common one where the constant is a simple literal and the variable portion is a longer (no, not excessively long, just.. longer ;) chain of things, a call within a call or some operator etc. It's as if to signal "there is some crunching/intricacy here but look, it's just…

I like your example a lot. It's easy to imagine a monstrosity of an equation stretching off to the right, but knowing the solution (or at least a solution) can constrain the knee-jerk reaction of "oh, that looks complicated"

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

#56
post #38
post #31

Earlier quoted context omitted.

I hear you. I don't like method chaining either. Instead of window.FindCanvasForObject(obj).Color(RED).MoveTo(10,30).LineTo(50,20). ... I much prefer: o = window.FindCanvasForObject(obj) o.Color(RED); o.MoveTo(10,30); o.LineTo(50,20); (Where, in C++ I would enclose this inside a { curly block } to give o the right type and make it local, and in Python I would add a "del o" at the end; and yes, I reuse 'o' to mean 'ob…

Just to nitpick, those aren't quite equivalent. The second should be: o = window.FindCanvasForObject(obj); o = o.Color(RED); o = o.MoveTo(10,30); o = o.LineTo(50,20); Which leaves more room for error in the general case - if the API gives you a new object each time, and you fail to assign it every time (or say you have multiple and get the letters mixed up, or you do this rarely and forget), you lose some of the conf…

You are correct, of course; the only API I used this with on JavaScript kept returning the original object (and that was documented behaviour) so it didn't matter.

I most often use this with C++, where it is

    {
        CanvasObject *o = window.FindCanvasForObject(obj);
        o->Color(RED);
        o->MoveTo(10,30);
        o->LineTo(50,20); 
    }
Your point about helper functions is spot on. They break the form in C++ (and Python if you don't modify classes), but with this form it is still much better than breaking a fluent style line.

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

#57
post #31

Earlier quoted context omitted.

I hear you. I don't like method chaining either. Instead of window.FindCanvasForObject(obj).Color(RED).MoveTo(10,30).LineTo(50,20). ... I much prefer: o = window.FindCanvasForObject(obj) o.Color(RED); o.MoveTo(10,30); o.LineTo(50,20); (Where, in C++ I would enclose this inside a { curly block } to give o the right type and make it local, and in Python I would add a "del o" at the end; and yes, I reuse 'o' to mean 'ob…

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.

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

#58
post #5

Earlier quoted context omitted.

To paraphrase the comment above that line, they say its purpose is to avoid accidental assignment. That's not an issue with "not equals" though, but that may just be their point. As for whether it's more readable, I'm skeptical: It may save you going through some of the condition, but I believe getting used to it would make you more likely to overlook parts of the condition. Plus, the way it reads is the opposite of…

To provide a different opinion, I'm not a fan of the macro NULL because the C spec leaves it rather open to compiler authors how to expand it. It says it must be 0, but they don't specify the type. It could be 0, 0L, (void*) 0, 0UL, 0LL, etc. However, the spec does say that only the null pointer evaluates to false and all other points are true. So doing if(ptr) is much more well-defined than the NULL macro.

If anything, NULL's opacity is another argument for doing the comparison. NULL is guaranteed not to equal any pointer to an object/function, and the result of the comparison will be an int 0 or 1.

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

#59
post #39
post #30

Earlier quoted context omitted.

To get you started, I'd like to compare my problems regarding `if = ` with yours. This assumes you aren't the kind of lunatic to actually assign a constant inside of an if's condition. 1. I can't articulate exactly why, but that should totally be flipped. The constant should be on the right side! `if(3.17 == possiblyPi)` would make me seriously question the author's motives. 2. It's personal preference, but in almost…

I can't articulate exactly why, but that should totally be flipped. Should it? If you accidentally use an assignment operator (eg = ) instead of a comparison (eg === )[1] with the constant on the left your code will throw an exception, which is what you want. If you put the variable on the left and accidentally use an assignment then you'll overwrite the variable with the constant value and return true, consequently…

Unit testing helps with this.

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

#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("\\.")));

Post reply on HN