Earlier quoted context omitted.
I think people underestimate the cost of vertical length. It's less obvious in small examples, but there's a huge difference in readability between a class or function that fits on one page and one that doesn't, so it's well worth making individual lines a bit less readable if it means you need less of them.
> so it's well worth making individual lines a bit less readable if it means you need less of them What does it mean?
Simple Ways of Reducing the Cognitive Load in Code
191–200 of 203 posts
Re: Simple Ways of Reducing the Cognitive Load in Code
#192I really like the advice from "Perl Best Practices" to code in paragraphs. Sometimes, a large function cannot be broken up usefully, because a lot of state needs to be shared between the different parts, or because the parts don't have a meaning outside of the very specific algorithm. In that case, code in paragraphs: Split the function body into multiple steps, put a blank line between these and, most importantly, a…
Situations like this are exactly where nested functions can be helpful. I've always thought that it was a shame that C didn't have them. Sometimes I almost wish that Algol flavored languages like Pascal anf Modula 2 would have won out for systems programming, instead of C and the languages it inspired. Actually, GNU C supports nested functions, and a new round if standardization is just starting up, so maybe there's…
Indeed. When I'm writing Haskell, I'm using a lot of nested functions in `where` blocks, sometimes cascaded down.
Re: Simple Ways of Reducing the Cognitive Load in Code
#193Earlier quoted context omitted.
In languages where braces define a scope even if there's no if, for, etc. keyword around, you can get a lightweight version of that just by sticking braces around your "paragraphs", as needed. They aren't the same as nested functions, in particular because you can't invoke a naked block multiple times, but if you've got a long function that hasn't got any useful break points in it, but you just want to chunk things,…
The thing is, naked scope blocks are missing the main reason I'd use a nested function: the ability to be named. I do occasionally use scope blocks when I want to constrain the scope of one or more local variables, and there isn't an otherwise appropriate scope already created by a flow control construct.
Re: Simple Ways of Reducing the Cognitive Load in Code
#194Earlier quoted context omitted.
state can be passed through as arguments...
Sure, but then there are more questions :) e.g. how many parameters ? 3, 4 ... ? what if they are of the same type ? would you change your numbers then ? users can get the order wrong etc. another thing : if you pass too many parameters, isn't that a hint to the fact that something is amiss ? edit-1 : fixed typo
Variable naming will only add to that, as you can rename variables in the extracted methods for their local purpose.
If you have too many arguments you can package them up in a object/map/tuple of your choosing (depending on language).
(Reverting to local state would in my opinion increase confusion and decrease readability.)
Re: Simple Ways of Reducing the Cognitive Load in Code
#195My current pet-peeve: - If your code deals with values where the units of measure are especially important and where they may change for the same type of value in different contexts, PUT THE UNITS USED IN THE VARIABLE NAME! I work primarily with systems that talk money values to other systems, some of which need values in decimal dollars (10.00 is $10.00) and some that need values in integer cents (1000 is $10.00). T…
Re: Simple Ways of Reducing the Cognitive Load in Code
#196Earlier quoted context omitted.
Stream based programming is a paradigm that with some training and proper code indentation is much , much faster to read than a nested for loop. Once you get used to it,you can literally fast-scan code written in this style with the confidence that you are not missing anything. Also, assuming you do not use mutable state, it also has the advantage of being easily parallelizable without any code changes. (As well, as…
"Stream-based code is certainly not something you can read off the cuff." List transactionsIds = transactions.stream() .filter(t -> t.getType() == Transaction.GROCERY) .sorted(comparing(Transaction::getValue).reversed()) .map(Transaction::getId) .collect(toList()); I honestly think most programmers fluent in Java 7 programming, can guess this is finding "grocery" type transactions, sorting by "value" transaction prop…
Even in Java 8 plain streams, the Collector is a powerful paradigm for grouping operations with a large amount of variations and it takes (at-least it did for me) some involved time learning how to effectively leverage this in day to day code.
Re: Simple Ways of Reducing the Cognitive Load in Code
#197Earlier quoted context omitted.
Using intermediate variables is one of the most underrated tools to make code more understandable. It's the definition of something completely unnecessary from a technical standpoint that is all about conveying meaning and clarity to other programmers. And it can be used to help group and "modularize" chunks of code within a routine without necessarily going to the extreme of pulling out a separate subroutine, which…
Agreed about using intermediate variables. What's better than comments to describe what the code does? CODE that describes what the code does. (Let the code describe WHAT the code does, and if necessary, the comments describe WHY the code does it like that.) In C++, if I use an intermediate variable to decompose a complicated expression into easier-to-understand sub-expressions, I like to make the intermediate variab…
I need actual examples to get on board, and not just the usual "idiot" programmer strawmen - actual examples that aren't obviously unreasonable.
My main reason for skepticism - Full, proper English sentences are capable of a lot more nuance, and precise semantics than whatever the programming-language syntax might support. I agree code can be written with more clarity, but it cannot substitute actual text, i.e. Code is not documentation.
Re: Simple Ways of Reducing the Cognitive Load in Code
#198His 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 though a test might be added to check for this, "Was this function run" is easier to determine than "Does this function have side-effects".
Re: Simple Ways of Reducing the Cognitive Load in Code
#199Earlier quoted context omitted.
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…
Allowing the extra constraint "doesn't have a side effect" is more dangerous than clarity in this case because it increases what a dev needs to know to modify the code, and allows for a bug to easily be introduced if the validate code is modified to have side-effects. And though a test might be added to check for this, "Was this function run" is easier to determine than "Does this function have side-effects".
Re: Simple Ways of Reducing the Cognitive Load in Code
#200His 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…
valid_user = loggedIn() && hasRole(ROLE_ADMIN)
valid_data = valid_user && data != null && validate(data)
if (valid_user && valid_data) …
I think this makes it clear that valid_data has a dependency on valid_user that was being hidden in the previous version, which we're now making clear. It will look a bit weird, but I think that's a positive because it draws attention to the fact that the short-circuiting is required and that double-look coupled with a short comment will make everything much more readable. The previous version does not convey as much meaning, in my opinion. if (loggedIn() && hasRole(ROLE_ADMIN) &&
data != null && validate(data)) …