←back to thread

1534 points nromiun | 1 comments | | HN request time: 0.001s | source
Show context
defanor ◴[] No.45081057[source]
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 compared to "goto", making the control flow less obvious/predictable (as paxcoder mentioned here). Intermediate variables, just as small functions, can easily complicate reading of the code (in the example from the article, one would have to look up what "isSecure" means, while "(condition4 && !condition5)" would have shown it at once, and an "is secure" comment could be used to assist skimming). As for HTTP codes, those are standardized and not dependent on the content, unlike custom JSON codes: most developers working with HTTP would recognize those without additional documentation. And it goes on and on: people view different things as good practices and being simpler, depending (at least in part) on their backgrounds. If one considers simplicity, perhaps it is best to also consider it as subjective, taking into account to whom it is supposed to look simple. I think sometimes we try to view "simple" as something more objective than "easy", but unless it is actually measured with something like Kolmogorov complexity, the objectivity does not seem to be there.

replies(9): >>45081450 #>>45081668 #>>45082133 #>>45082314 #>>45082455 #>>45082707 #>>45082777 #>>45082899 #>>45083671 #
brucehoult ◴[] No.45081450[source]
> For instance, the article itself suggests to use early/premature returns

I like premature returns and think they reduce complexity, but as exclipy writes (I think quoting Ousterhout) 'complexity is defined as "how difficult is it to make changes to it"'.

If premature returns are the only premature exit your language has then they add complexity in that you can't then add code (in just one place) that is always executed before returning.

A good language will also have "break" from any block of code, such that the break can also carry a return value, AND the break can be from any number of nested blocks, which would generally mean that blocks can be labelled / named. And also of course that any block can have a return value.

So you don't actually need a distinguished "return" but only a "break" that can be from the main block of the function.

A nice way to do this is the "exit function", especially if the exit function is a first class value and can also exit from called functions. (of course they need to be in a nested scope or have the exit function passed to them somehow).

It is also nice to allow each block to have a "cleanup" section, so that adding an action to happen on every exit doesn't require wrapping the block in another block, but this is just a convenience, not a necessity.

Note that this is quite different to exception handling try / catch / finally (Java terms) though it can be used to implement exception handling.

replies(4): >>45081619 #>>45082414 #>>45082568 #>>45083909 #
derf_ ◴[] No.45081619[source]
> A good language will also have "break" from any block of code, such that the break can also carry a return value, AND the break can be from any number of nested blocks, which would generally mean that blocks can be labelled / named. And also of course that any block can have a return value.

Even in a language that is not "good" by your definition... you have basically just described a function. A wrapper function around a sub-function that has early returns does everything you want. I use this pattern in C all of the time.

replies(1): >>45081663 #
1. brucehoult ◴[] No.45081663[source]
It is more inconvenient to make a wrapper function for a function than to make a wrapper block for a block, especially in C where you can't lexically nest functions (not counting GNU extensions).

Naturally all programming languages are equivalent, but some are more convenient than others. See the title of this post "Cognitive load is what matters".