NOTE this post is borrowed from my old blog, with permission.
One of the greatest virtues of programmers is that we are lazy. Regularly this means that we do not want to spend a lot of time and/or energy in doing stuff that bore us.
We should be lazy in that common-sensical way, but we should also make our code lazy in two ways, whereof only the second one is analogous to the aforementioned human laziness, whereas the first one is usually considered its dual, “planning ahead”:
- Do not repeat labor
- Do not do anything before you need to
Even though these two statements seem simple and obvious, it is one thing to just read them and imagine oneself intrinsically following them by the nature of being a “programmer.” Actually, there are quite few “programmers” who follow these statements to their fullest, and reach that delicate balance of duals. A balance of expression.
Let us look further at these two seemingly simple statements.
Do not repeat labor
There are two aspects to this: logic and data.
As to not repeating logic, this means identifying a recurring pattern of labor, describing that pattern formally and, finally, using these magnificent machines we call computers to carry out the corresponding laborious tasks over and over again. This goes for all levels, from the simplistic level of actually automating manual work – this is what conventionally is called programming - to writing generic code, such as employing the notions and ideas of Generic Programming.
There is also a data aspect to not repeating labor and that is to not calculate the same data over and over again. This is called caching.
Do not do anything before you need to
This ranges from not trying to optimize code in advance to actually not calculating data we might not need.
Unfortunately, only non-common programming languages have intrinsic support for this kind of laziness. Those languages are almost always in the category of functional languages, such as Haskell. Those languages are called lazy – or non-strict if you are into language semantics.
Luckily, there are both libraries for more common languages that provide lazy evaluation, such as the eminent FC++ for C++, and frequently used notions that are intrinsically lazy. Consider TCP/IP streams for this latter category. The revival of asynchronous queuing is also a variant of that example. The problem is that these realizations of the “lazy pattern” are purely inter-modular and quite often even inter-process.
What I am saying?
Be lazy, but never ever sloppy
I will provide examples of how one can use laziness in C++ later.
Computer Science lazy software practice