Simple or Complex? Familiar Imperative Code Or Makes-Me-Think Declarative One?

We have had a heated discussion today about the two alternatives of JavaScript code that filters out elements with a different hardwareType (if supplied):

// Using as `_`
_(bundles).filter(function includeOnlyHandsets(bundle) {
if (!filter.hardwareType) return true;
return (bundle.product.type === filter.hardwareType);
_(bundles).filter(filter.hardwareType ?
{bundle: {product: {type: filter.hardwareType}}} : null)

view raw


hosted with ❤ by GitHub

The imperative solution (1) is familiar to all of us and thus easy to grasp. However the declarative solution (2) is not familiar, we have to think about what it does, we need to know that .filter({bundle: {product: {type: filter.hardwareType}}}) keeps only bundles that have the given product.type and that .filter(null) does keep all. Thus (1) is easy to understand, (2) isn’t.

As my colleague that prefers (1) put it,

I am human, not a computer. This second suggestion is more confusing and less readable than the original. Here, I have no clue what is going on, and have to stare at it and study it for ages to make any sense of it. I know lodash, and sometimes using it harms readability. I have learned what (2) means. I still think it is not simpler.

I prefer (2)​ because there is only the relevant stuff (aside of the null). I do not need to “study it for ages” – I look at it and know what is going on, faster than in the imperative versions with its “noise” that my brain has to filter out. I see at once that it is an optional filter and that it compares bundle.product.type with the filter value – without needing to skip over various JS keywords.

I think that those who do prefer (1) do so because that is what they are familiar with. Because their brains have learned what parts of that text to skip over and what to look at, while (2) makes them think because it is new (even if they have learned to parse it). I thus believe that if you used (2) for a while, you would find it superior – similar that people do after a while with functional programming and immutability. Of course, this is just a hypothesis (though based on my experience, in particular with Clojure).

There are good reasons to write code that other developers and new team members can immediately understand. However there are also good reasons to prefer code that contains no irrelevant text and to expect and require that people have certain prior knowledge of their main tools (lodash in our case, as it is a key part of our code, and the core library in the case of Clojure). Yes, learning it takes time and effort – but the reward of shorter, no-nonsense code is worth it in my opinion. Rich Hickey makes this point nicely in his famous talk Simple Made Easy. You should not optimize for beginners – you should optimize for the experienced developers you have / want to have.

What would you prefer?

PS: I admittedly am quite biased here. Make your own conclusion! 🙂


3 thoughts on “Simple or Complex? Familiar Imperative Code Or Makes-Me-Think Declarative One?

  1. Michal Příhoda (@mprihoda)

    I think the poll questions do not stress enough that both of these pieces of code need prior knowledge to be understood. And gaining that knowledge is one-time investment.

    If I ask “which piece of code would be more readable, if I had the necessary prior knowledge?”, the answer is obviously 2, for the lack of noise.

    As soon as I have the knowledge and experience, I can read and comprehend #2 faster. So in the long run, it is better to learn a little and gain a lot, than to repeat the same keywords again and again. After all – I am a human, not a computer – I’m good at learning, bad at mechanical repetition.

    1. Jakub Holý Post author

      I would say that it is primarily a question of how high you set your expectations for what people should learn before becoming productive in your codebase. It should be neither too high – not too low.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s