Software is a Conversation Scattered Over Time in a Truly Foreign Language

06 Apr 2021

This, in my honest opinion, is the most important concept to actively apply over a life spent in software development. After experiencing some quality time with a programming language, it is easy to forget that a computer language is an attempt to converse with silicone using a syntax that has a heavy math influence. This rather unnatural construction must serve two very different masters and one type of those masters might not have much mastery. Nevertheless, we expect future maintainers of our code to understand its implications born from the past into the ever expanding future.

The following are some examples of why is it crucial to keep the “communication + math like language + time = software” concept around when developing:

Naming a boolean variable ‘match_found’ seems pretty obvious as to its intent. If, over time, the code shifts to finding ‘only the matches we care about’ and the name hasn’t changed then we’ve created a nice little place for bugs to hide. Add in some PII (personally identifiable information) scrubbing via an over-eager regex and the issue of “certain user and customer names are not showing up in the report” can be a doozy of an issue to solve.

Someone on the team gets into functional programming while doing a personal project but their day job involves an object oriented language. They start introducing functional Ruby code into the project by using Ruby’s collection interface. In Ruby one can combine a ‘map’ with a ‘reject’ perhaps a ‘tap’ and then pull it all together with a ‘reduce’ and you have some pretty concise functional instructions like so:

[1,2,3,4,5].
  map {|i| i * 3}.
  reject {|i| i.even?}.
  map {|i| i.to_s}.
  tap {|array| array.shuffle!}.
  reduce {|m,o| m + o}

Now imagine the above structure but each block is performing business logic. Clearly, from a ‘conversation with the other developers over time’ point of view, this type of code has some severe implications. Is the team ready to become that multi-paradigm? Will the future maintainers of this code be able to debug it?

A developer wants to apply the ‘Something-Or-Other Pattern’ they just learned about and it really does seem to organize the code into logical chunks. Should the team adopt this architecture? Well, It is devastatingly easy to break code into nice modular chunks using a pattern and also nearly destroy a future developer’s ability to reason about its intent. Does the increased modularity (and almost always decreased readability) make some other aspect of coding so much better that justifies the cost? How is the team implementing the pattern planning on overcoming the indirection that the modularity of pattern will introduce? Documentation works best when lying breaks it. This is a fancy way of saying that writing an automated test that clearly demonstrates how these fancy objects interact is highly advised.

As a friend of mine once said: “I wouldn’t have gotten into software if I knew it was all about humans.” Yes, this was the functional programming guy.