Live data from Hacker News

Simple Ways of Reducing the Cognitive Load in Code

chrismm.com

171–180 of 203 posts

Re: Simple Ways of Reducing the Cognitive Load in Code

#171

"Use names to convey purpose. Don't take advantage of language features to look cool." I can't say enough about this. Please write code that is easy to read and understand, not the most compact code, and not the most "decorated" code, or "pretty" code or neat because it uses that giant list expression or ridiculous map statement thats an entire paragraph long. Similarly what bugs me is when I receive a pull request w…

Maybe I've been shaped by my history... but I've been writing core code for other devs to extend for 5 - 8 years by now. And hell, the smart code I've written is necessary, sadly, but impossible to maintain. I've written non-blocking, lock-free holy-balls pieces of code, but there are very few people I know who could maintain that kinda code.

The best code I've written is when a junior can hit me up and go "Yo, I've tried to implement this feature here. I've picked up on those patterns over there to get started. I'm not sure about those two parts, can we talk about those a little? I think the rest of the code I've done is good, let's look at that though. That part over there just looks weirds, I'm not certain it'll work right."

Overall, I think smart code not a good thing to do. 90% of your code, or more, should just obviously work because it follows "the pattern".

Re: Simple Ways of Reducing the Cognitive Load in Code

#173
post #125

Earlier quoted context omitted.

Perhaps an alternative would be valid_user = loggedIn() && hasRole(ROLE_ADMIN) if (valid_user) { valid_data = data != null && validate(data) if (valid_data) { ... } }

For whatever reason, I'd prefer comments to this version. Note: I actually agree with the OP about pulling the logic into named conditionals whenever possible, but in the case you do want the short-circuiting behavior I would not bother with the variables at that point. if (loggedIn() && hasRole(ROLE_ADMIN)) { // User has permission to do this if (data != null && validate(data)) { // Submitted data is valid ... } }

I prefer code over comments

  userHasPermission = (loggedIn() && hasRole(ROLE_ADMIN))
  if (userHasPermission) {
    dataIsValid = (data != null && validate(data))
    if (dataIsValid) {
      ...
    }
  }
That's shorter, introduces terms in reading order (readers do not have to wonder what if (loggedIn() && hasRole(ROLE_ADMIN)) means before encountering userHasPermission. Yes, you can write the comment before the if statement, but then, it tends to become longer: "check whether the user has permission to do this") and less likely to become inconsistent when code evolves.

I see such comments as symptoms of time pressure or a somewhat sloppy, but caring, programmer.

Re: Simple Ways of Reducing the Cognitive Load in Code

#174

Earlier quoted context omitted.

For whatever reason, I'd prefer comments to this version. Note: I actually agree with the OP about pulling the logic into named conditionals whenever possible, but in the case you do want the short-circuiting behavior I would not bother with the variables at that point. if (loggedIn() && hasRole(ROLE_ADMIN)) { // User has permission to do this if (data != null && validate(data)) { // Submitted data is valid ... } }

I prefer code over comments userHasPermission = (loggedIn() && hasRole(ROLE_ADMIN)) if (userHasPermission) { dataIsValid = (data != null && validate(data)) if (dataIsValid) { ... } } That's shorter, introduces terms in reading order (readers do not have to wonder what if (loggedIn() && hasRole(ROLE_ADMIN)) means before encountering userHasPermission . Yes, you can write the comment before the if statement, but then,…

That's an interesting trick, but it does create a whole bunch of throwaway booleans. Still, I can see that if the situation gets really complex breaking it down like this can be a benefit (but not so much in the current example where it actually increases cognitive load because you will have to read more lines to figure out what is really going on rather than what the boolean name indicates, for instance, userHasPermission does not fully cover the load and if validate would return false on being sent 'null' for that data element then you could get rid of the flag altogether).

Re: Simple Ways of Reducing the Cognitive Load in Code

#175

His second example to "modularize" a branch condition is not functionally equivalent in _most_ in-use programming languages: valid_user = loggedIn() && hasRole(ROLE_ADMIN) valid_data = data != null && validate(data) if (valid_user && valid_data) … Is not equivalent to: if (loggedIn() && hasRole(ROLE_ADMIN) && data != null && validate(data)) … His version will always execute `validate(…)` if `data` is not null regardl…

I guess the alternative would be: if (isValidUser() && isValidData(data)) … Which would avoid the potentially expensive `validate()` without putting it all on the one line.

Not really, because the code comment above mentioned that one of the primary purposes of this technique is to reduce function overhead.

Re: Simple Ways of Reducing the Cognitive Load in Code

#176
post #161

His second example to "modularize" a branch condition is not functionally equivalent in _most_ in-use programming languages: valid_user = loggedIn() && hasRole(ROLE_ADMIN) valid_data = data != null && validate(data) if (valid_user && valid_data) … Is not equivalent to: if (loggedIn() && hasRole(ROLE_ADMIN) && data != null && validate(data)) … His version will always execute `validate(…)` if `data` is not null regardl…

If validate() doesn't have a side effect then the short-circuiting doesn't matter. The micro-optimization of skipping the validation for performance reasons is premature optimization. If the performance optimization is necessary it should be stated more explicitly in the code then just being hidden being a && short circuit I've always thought this kind of short-circuiting as an implementation detail of the runtime th…

And then when stuff is rewritten s.t. once you get there there's always a user logged in and non-null data? Presumably you do away with the temporary variables and just write:

  has_role(ROLE_ADMIN) && validate(data)
If validate(data) needed to be called regardless of has_role, you now have a problem.

Re: Simple Ways of Reducing the Cognitive Load in Code

#177
post #41

Earlier quoted context omitted.

I agree in general case, but this example transactions.stream() .filter(t -> t.getType() == Transaction.GROCERY) .sorted(comparing(Transaction::getValue).reversed()) .map(Transaction::getId) .collect(toList()); seems to be net improvement to me. It reads like SQL, and eliminates many causes of error (wrong indexing variables, off-by-one, copy-paste error in boilerplate). Yes it requires learning several new concepts,…

While some people may like to read code that looks like SQL, I've found Java 8 features like this are poorly supported by the debugger, so debugging stuff like this tends to require "horse whispering" or rewriting the logic into something that can be stepped through.

That reads more like Haskell than like SQL. (Doesn't have any bearing on the rest of your point one way or another.)

Re: Simple Ways of Reducing the Cognitive Load in Code

#180
post #47

Earlier quoted context omitted.

That's like the function composition operator [1] in Haskell, right? Very neat :D I wonder if there's an equivalent macro in Scala ... [1]: http://lambda.jstolarek.com/2012/03/function-composition-and...

|> from scalaz. API is not that usable though. F# have List.map, List.filter functions for example, which are not present in scala.

It doesn't seem to have worked out for F# as they have recently adopted what Scala has been doing for years.
Post reply on HN