Stop Using Variables – Learning Through Constraints
My new year’s resolution for 2017 was to stop using variables. My goal was to force some learning by applying a constraint to my work. Over the course of the year, I attempted this while writing various types of code:
- Restful api endpoints – good. It felt quite natural to write code without variables in this environment.
- Parsing – good. The end result is a series of small functions with well defined responsibilities. The code was much easier to understand when compared to other parsers I have written with variables. The main reason for this is when I am reading a line of code I don’t have to wonder if the value of something is going to change.
- Stateful view-controllers – mixed. Obviously ‘stateful’ is the problem here. I ended up continuing to use member variables, but eliminated local variables. This did result in small functions with a clear purpose, but I can’t really call this a complete success.
- Stateless services – good. Whenever state is not a requirement, eliminating variables typically results in cleaner code.
- Unit Tests – bad. The unit tests are easier to read, write, and understand with variables.
The method I chose to use is to break functions into multiple functions that do more limited things. So basically what would have been variables become parameters. Also I almost exclusively used collections as data streams when available. This style led most of my functions to begin with the return keyword. Other effects were an increase my use of the ternary operator and reduced my usage of brackets when making if-else blocks. The brackets seem unnecessary when I am just executing one line of code or calling a function. The only place where this felt awkward is when creating an instance of an object, doing something with it, and returning it.
With this method, there are definitely some holes that you can dig yourself into. Particularly if the language allows easy declarations of anonymous functions. It is easy to follow a chain of thought that would result in several nested ternaries branching into anonymous functions that may or may not also contain ternaries. The solution is to refactor to reduce cyclomatic complexity – which should be done regardless of programming style. However, I find that un-refactored procedural programming is easier to follow than un-refactored functional programming.
Overall I believe this experiment to have been a success. I feel like my programming has improved by operating under this constraint. Going forward I’ll be mixing variables back into my code, but I will be using them sparingly.
Below is a basic example of the two programming styles.