A feedback loop is a powerful mental model. As progammers, we experience it numerous times a day. Let’s try to peek into a few dimensions of loops.
There are three elements to a loop. We start with an objective, a desired outcome. Second, the action kicks off the loop. Finally, we have the feedback, an intermittent notion of progress. While objective and triggers almost always have a good intention, it is the feedback which helps us continuously evaluate each iteration and mitigate any risks of failing to meet the objective.
Loop ensures we keep tweaking the action and feedback system until desired outcome is reached. Let’s take an example of Continuous Deployment.
Programming 101 starts with several constructs to create a set of instructions for the computer to act on well defined inputs and produce a desired output. We learn about the editor and compiler. This is also the first time we see a loop in action.
Figure 1 (above) outlines an example of this. We write Text (code) in an Editor. Save action persists the text to a file on the hard disk. Editor provides us a feedback that the File is saved. This file is then provided as an Input to the Compiler, which Compiles (an action) the code into an Executable. Compiler provides us feedback if there are errors in our code. The objective of this loop is to identify syntax errors early, and save the user time and cost.
It is possible to extend a loop with additional functionality. Figure 2 (above) modifies the objective from “syntactic correctness” to “syntactic and behavioral correctness”. The loop is extended with an additional Test action. It runs the Executable with a well known set of inputs and provides us feedback if the code functions as expected. We will name this loop as an “Inner Loop” and try to extend it further below.
Loops can be leveraged with composition to achieve a much powerful objective. Figure 3 demonstrates this. We widen the scope of our objective to “ensure code from inner loop can be integrated”. We add few more actions - Integrate, Build and Test. Outcome of the inner loop is first merged with a repository. It is then packaged and tested together. We will call this as the “Continuous Integration (CI)” loop.
We create another loop that extends the CI with Deployment and Monitoring. Call this the “Continuous Deployment (CD)” loop. Story need not end here. We can take the CD for every feature, compose them together for the entire product and further augment it with steps to measure customer satisfaction (say NSAT or CSAT scores) or quality and so on.
Alright, we know how to create a loop, extend and compose them together. Let me represent them in the context of a fictional organization with 80 developers spread across 10 teams. We’ll try to reason over few other characteristics.
Figure above attempts to look at the loops from a perspective of impact - a) number of times a loop is executed per day, and b) scope of the objective. An inner loop is run by every developer several times an hour. Continuous Integration (CI) represents the scope of a team (10 developers). Scope of CD is even larger.
Take an hypothetical case of an error that blocks the Inner Loop. It will immediately block the loops composed on top of it (CI and CD). An error on part of a single developer in a team of 80 can cripple the entire organization.
Equally interesting is the reverse scenario. Any efficiency introduced in the inner most loop, immediately shows the results in several orders of magnitude. It turns out, loops can be amplifying or diminishing based on the scope and levels of complexity.
It may be easy to imagine amplifying loops (also called as Virtuous Cycles) in economy and other fields. E.g. more industries lead to more jobs which lead to higher purchasing power and that feeds back to create even more industries. Similarly, more enterprises lead to more competition which reduce the price and provide better value at a larger scale.
Can the loops be ever amplifying or always diminishing?
Intuitively, it may appear to violate the laws of physics ;) Faster CI & CD will lead to better code that reaches the customer faster. But the efficiency of a team will saturate at some point. To go beyond, we will need to scale the loops to more developers. And that will inevitably bring more complexity to the operation of loops.
I think it is worth calling out that humans often slow down the loops. E.g. we introduce processes like every deployment must be signed off by John Doe while being watched over by Jane Doe. Needless to say, it defeats the entire purpose of a loop. And the reverse, algorithms tend to amplify the loops unnecessarily. Remember that youtube/facebook recommendation algorithm that keeps you hooked. Heck, I go to LinkedIn searching for opportunities and end up reading “10 ways to be a better leader”.
So while we’re onto the awesomeness of loops, let’s also ensure that they remain balanced and autonomous. Keep watching out for a point of saturation, and push in the one or two changes to give life to the loops again.
In summary, loops are a powerful mechanism to evaluate progress towards an objective. They can be extended and composed together to widen scope of the objective. With feedback at each action within an iteration, loops also help us reduce the risk of a negative outcome. Try to create autonomous and amplifying loops. Represent your hypotheses as loops too, and measure them from day one.
It turns out loops play an integral part in rhythms of nature. There’s the trigger for you to scroll through youtube endlessly ;)
May the loop be with you!