Cognitive load vs DRY

The effort to consolidate all variables may be putting too much complexity on your team

Cognitive load vs DRY

I’ve seen this more than a few times in my career, where engineers embark on an all-out offensive to implement DRY-ness. But then at what cost does the solution come?

For an example:

This pattern is completely understandable. Believe me, I get what you’re trying to accomplish and it’s admirable - to an extent. I’ve attempted to squash this kind of pattern in code reviews, and I’ve come across it a few times in existing code. I don’t like it, but I had a hard time articulating why.

Finally the moment of clarity: I don't like it because it places too much cognitive load on the reader. Imagine that the template file is itself basically a template file. As in, say, a helm charts value file (or, think if it were a hieradata file from Puppet). Now, imagine what a reader of this code would have to go through to figure out what will ultimately deploy to their cluster:

  • Starting with the original helm chart, find the variable name that it uses
  • Then find that in the corresponding template file that you’ve made (template.yaml in the example above)
  • Now, find that variable in the variables file (prod-variables.sh)
  • Finally, check what the script (deploy.sh) is going to do to ensure what you think will get placed will actually happen

Is it impossible? no. Programmers do this all the time. Which is why it’s easy to fall into this pattern. But it’s much more difficult than it needs to be. Now, my "shower thought" this was: the analogy would be doing 3 or 4 dimensional arithmetic. finding your coordinates becomes challenging, and doing it over and over again... well, yuck.

Leave that to computers. Which, ironically is what this pattern is optimizing for - not humans.

The other issue I have with this pattern is its brittleness. This can be improved by using something like jq/ yq for "editing" the files, but my defensive-programmer spidey senses start rising when I see things like this.

So, a solution, then? Just put the values in the files that you want - directly. To continue with the example above, put the values in template.yaml. In fact, the file should actually become prod.yaml

prod.yaml

---
something: 12345678
  location: somewhere1
  another: static item

In my opinion, it's better to reduce the cognitive load of your teammates (thereby improving everyones productivity) than to wring every last variable DRY. Similar to how database normalization can go too far in terms of its practical application to the business purpose (I'm looking at you, 5th normal form). For the sake of your teammates, reducing cognitive load provides a much quicker path to becoming productive contributors. Someday, they could even thank you.