Not All codes are liabilities
Categories: Android development code
Tags: code mathematics math
Recently, there is a trend that code is not an asset. Let's think about it!
Above wallpaper reference1
I am not writing here to convince anybody. Just sharing my thoughts. You can see from the title that I am not in agreement with some developers whom claim code is not asset2, or code is a liability 3.
Accounting
Let's start by definitions. Assets and liabilities are accounting terminology. They are describing below equation.
\[ Assets = liabilities + equity \]
There is a notion of time in this equation, where assets are something that someone can own, where they don't lose their value over time, or sometimes their value increase over time, while liabilities are the ones that their value decrease over time. Liabilities are like loan, mortgage, debt. If we stick to objects in reality, liabilities are objects that degrade by the Second Law of Thermodynamics4, such as cars, buildings, etc. For instance, land is an asset because Second law of Thermodynamics cannot decrease its value, but the buildings in that land is a liability. To prove it, just let a building stay without a touch in 10 years, then try to sell it. Hope these stuffs are clear now.
Code
Let's define code. Code is an step-by-step instruction to construct something. It could be a step-by-step instruction, where we use imperative programming languages to refer to them, or they could describe how to construct the thing, where we use declarative programming languages to call them, but even with the declarative ones, behind the scene the step-by-step instruction must happen anyway. For instance, there are a lot of code to construct the operating system of your device, where you are using to read this (Did you get a hard copy to just prove me wrong?). Or any software in your computer had kind of a code to be used to construct it. More examples? Sure! Like logic that Euclid5 used to construct his geometry6. I see! Before this last example you were almost slept while reading this. I agree it was boring, but the last example made some of you disagree. But didn't Euclid construct the Euclidean geometry6 step-by-step by using logic? If so, then the instruction he used is a code by definition.
Mathematics
Here, we reach to another popular claim across the Internet that programming is not mathematics. I don't know about you, but I just showed above that some part of mathematics, which are constructable, has code. By the way, when you talk to people who think code is not mathematics, you notice they are talking about arithmetic, or calculus, where I agree with them! Programming is not arithmetic! Mathematics is a huge area of knowledge, which includes arithmetic, but not everything in mathematics is arithmetic! So it's totally possible that you are very good at programming, but couldn't multiply two two-digits numbers in your mind, just like me!
Here, I just assumed anything that's constructable has an instruction, therefore has a code. It looks like a valid statement to me, but I am open for your counter example.
Let's continue on how code is mathematics. Or a better question, is mathematics all code? In fact, I hear you! There are a lot of examples in mathematics that is not constructable, such as infinities, real numbers, set of all sets, etc. In my humble opinion, not-constructable stuffs are not mathematics, because they are full of contradictions, but this is not what the main stream mathematicians would teach you! I am a programmer! If you want to know more about it, you can search "Curry-Howard correspondence"7. That's an argument for another day. Let's not take that route and focus on code as asset.
Some codes are liabilities
It's obvious that some developers had experience with code that was a liability. I don't have any problem with that. You can write code in a way that you need to change it if a butterfly flies in Amazon jungles. We call it chaos! But, which is a big but, someone can write code that works like a charm after a long long time, which by definition makes it an asset. There are some Fortran8 code, such as LAPACK9, which interestingly is a math library, where has features that are in use after decades their development has stopped. It's not just Fortran codes. There are a lot of ancient C code that are still in use today. Now can you say all codes are liabilities? This brings us to the question why some code doesn't degrade after a long time, which makes them assets? Good question!
Now that we witnessed some codes are not liabilities, someone should answer why? Why not my code is an asset? I want my code to be an asset! I don't want to fix its problems all the time. I don't want to touch it after I carefully crafted it.
Write a code that's an asset
Imagine writing code that is running your business, but you don't need to touch it for a long time. It would print money for you! To answer above questions, we need to answer why Euclid's code was so stable for thousands of years? Because its dependencies didn't change. Euclidean geometry's6 dependencies were its five axioms, and the logic he used to construct it. In fact, Euclid's axioms were so stable that mathematicians tried to break the weakest one, fifth one, for more than a thousand years, without a success! Eventually they succeed to do so and they created curved geometries, but still if someone needs the fifth axiom only, the Euclidean geometry is robust enough. He was clear about those dependencies, and he minimized them until they were stable axioms themselves. So if our code has stable dependencies, we can argue the code itself will be stable, which means that code will be an asset, if it's useful in any business!
But you would argue my code needed these dependencies! How can I remove them?! Entering Dependency Inversion Principle(DIP). It's a plot twist! The actual title of this post is Dependency Inversion Principle - Part III, and it belongs to my Dependency Inversion Principle post series10. The same wallpaper in this post and that post was your hint. Did it work?
The answer to how to remove the dependencies from my code is, you can define the API11 for your code in terms of serializable data, such as JSON, Protobuff, etc over endpoints, or non-serializable data over Java's interfaces, or Rust's traits, etc. Then inject the dependencies on runtime. By the way, we call them differently in our industry. The former architecture is Microservices12, and the latter is called only called DIP, but here I widen the umbrella of DIP. To restrict the dependencies as much as possible, you definitely want to isolate your code and put it inside a module, where I can call it compile time isolation. You can even isolate your code in runtime, by using containers, such as Docker or Podman.
The point is that after the isolation, the API of the code must be stable to argue that the code will stay stable. This means if a code/implementation has smaller number of APIs, with a higher probability it would be more stable in the future, which means the developers need to optimize the code by breaking it into pieces with the smallest number of APIs. This is what Euclid did, right? It's not an easy task, which brings us to the point that good programmers are mathematicians. They divide and conquer.
Trade-off
The biggest trade-off of DIP is simplicity. How much you define more APIs, and make one-file modules, you have to talk more about the idea behind all of them, when you explain them to new programmers on their on-boarding. It's explicitly hard to convince anyone else that your seemingly cluttered code with a lot of APIs here an there is an asset! We'll refer to this as an on-boarding measure of simplicity.
Simplicity is the ruler of current software industry. It's much more respected than stability of the code, so this is maybe why we didn't achieve a lot of stable software over these years! Notice, if you could optimize your code to have a minimum number of dependencies, you actually achieved simplicity.
Regarding the simplicity, I am in the team who says:
Everything should be as simple as it can be but not simpler! --- probably Albert Einstein
It brings us to my other favorite quote:
All physical theories, their mathematical expressions apart ought to lend themselves to so simple a description, 'that even a child could understand them.' --- probably Albert Einstein
Which means, if you have understood what you are doing with your code, you will not have any problem with the on-boarding measure to justify its simplicity.
So I would ask myself the following question before writing my code. Can I minimize the dependencies and APIs, which will lead to simplicity as well, or I cannot handle them? If the latter is true, it's better to don't make unnecessary APIs. But if you can minimize them, that's the way to go.
Conclusion
In conclusion, the formula to be a reach programmer, who makes assets, not liabilities, is the cycle of isolating the code, then minimize the number of its dependencies and APIs, then repeat.
References
Cite
If you found this work useful, please consider citing:
@misc{hadilq2024Code,
author = {{Hadi Lashkari Ghouchani}},
note = {Published electronically at \url{https://hadilq.com/posts/not-all-codes-are-liabilities/}},
gitlab = {Gitlab source at \href{https://gitlab.com/hadilq/hadilq.gitlab.io/-/blob/main/content/posts/2024-10-20-not-all-codes-are-liabilities/index.md}},
title = {Not All codes are liabilities},
year={2024},
}