Many non-functional properties denote a potential. Reusability indicates a potential for reuse. That potential is fulfilled when we actually reuse an artifact. Information hiding indicates the potential to change a design decision without impacting other modules. It is fulfilled when you actually change that decision. Even readability indicates a potential. It is fulfilled when someone actually goes in and reads the code.
Suppose that you have some code in a stable (working) state X. However, that code is lacking some non-functional property, say extendibility in a specific area. From the perspective above, what you want is to move it into another stable (working) state Y with a higher potential. As usual, that won't come for free: you need to apply some energy (work) to change the state of your code.
Borrowing a page from chemistry, we can see a similarity with the notion of activation energy: "the minimum energy that must be input to a chemical system with potential reactants to cause a chemical reaction [...] Activation energy can be thought of as the height of the potential barrier (sometimes called the energy barrier) separating two minima of potential energy".
In a picture:
Suppose that you have some code in a stable (working) state X. However, that code is lacking some non-functional property, say extendibility in a specific area. From the perspective above, what you want is to move it into another stable (working) state Y with a higher potential. As usual, that won't come for free: you need to apply some energy (work) to change the state of your code.
Borrowing a page from chemistry, we can see a similarity with the notion of activation energy: "the minimum energy that must be input to a chemical system with potential reactants to cause a chemical reaction [...] Activation energy can be thought of as the height of the potential barrier (sometimes called the energy barrier) separating two minima of potential energy".
In a picture:
Here we have two stable states X and Y, which differ in potential by DH, but the activation energy, indicated there with Ea(X->Y), is higher than DH.
The fact that activation energy (the energy you actually need to add to the system to move it from X to Y) is higher than the mere difference in potentials is commonly experienced in software design / development. Every time you see the possibility of a change that would increase some non-functional property, but decide not to pursue it because the effort may not pay off, you're experiencing a case where Ea >> DH.
Of course, software is different from chemistry, because the dynamics of information are not exactly the same as the dynamics of matter. For instance, once you move to an higher potential state (say, reusability) you can benefit from that many times over, therefore balancing the initial investment. Still, a significant difference between Ea and DH may easily stop us from moving our code to Y, as Y is often just a potential. A lot of engineering common sense is merely pointing out these facts.
The fact that activation energy (the energy you actually need to add to the system to move it from X to Y) is higher than the mere difference in potentials is commonly experienced in software design / development. Every time you see the possibility of a change that would increase some non-functional property, but decide not to pursue it because the effort may not pay off, you're experiencing a case where Ea >> DH.
Of course, software is different from chemistry, because the dynamics of information are not exactly the same as the dynamics of matter. For instance, once you move to an higher potential state (say, reusability) you can benefit from that many times over, therefore balancing the initial investment. Still, a significant difference between Ea and DH may easily stop us from moving our code to Y, as Y is often just a potential. A lot of engineering common sense is merely pointing out these facts.
Languages and Tools
One of the niceties of writing software in the 21st century is that many languages come with decent development tools, which include more or less advanced support for automatic refactoring. Being able to select a portion of code and move into a new method, with all parameters figured out by a tool, or to automatically abstract some methods into an interface, etc., all lower the human effort (energy) required to move from state X to state Y. In chemistry, this is the role traditionally played by a catalyst; the purpose of a catalyst is exactly to lower the activation energy, as you see here:
Some language features act themselves as catalysts. Unlike many younger programmers, I learnt functional programming before object oriented programming. Lambdas and higher level functions were my bread and butter. In my first OO language (Smalltalk) I could still pass around code fragments with ease (as I always tell people, if is a method in Smalltalk, taking two code fragments as parameters). But when I moved to C++ and Java, I always missed lambda functions (until recently).
Of course, there is nothing you can do with lambdas that you can't do with an interface, an implementation, and polymorphism. But the activation energy is quite high, and people tend to go with the "lower resistance path" (that is, stay with the lower potential, which in many cases means less information hiding here). In fact, the anonymous inner class idiom in Java was meant as a mild catalyst, but lambdas are way more effective as catalysts.
A dynamic language tends to lower the overall activation energy for most reactions as well. Which brings me to the conclusion for this short entry: although I have shown only one direction, reactions go both ways. You can move from a higher potential to a lower potential. You can mess up your code, so it still works (state X is stable) but it no longer possess some non-functional property you had in Y.
A catalyst may lower activation energy both ways, from X to Y or from Y to X. It's easier to make a non-functional mess in a dynamic language, because implicit contracts make many non-functional properties hard to see. Lambdas, although extremely convenient, may prevent a bunch of functions to coalesce into new, meaningful abstractions (a richer interface), which is instead split into single pieces. Acknowledging this duality is part of a deeper understanding of things, and a good antidote to the superiority complex that comes with so many languages and paradigms.
Notes
[1] The pictures above have been adapted from a work in wikimedia commons, which license allows unrestricted use, including modifications.
[2] I wish I could say that I know how to put numbers on Ea and DH. I'm very far from there.
Of course, there is nothing you can do with lambdas that you can't do with an interface, an implementation, and polymorphism. But the activation energy is quite high, and people tend to go with the "lower resistance path" (that is, stay with the lower potential, which in many cases means less information hiding here). In fact, the anonymous inner class idiom in Java was meant as a mild catalyst, but lambdas are way more effective as catalysts.
A dynamic language tends to lower the overall activation energy for most reactions as well. Which brings me to the conclusion for this short entry: although I have shown only one direction, reactions go both ways. You can move from a higher potential to a lower potential. You can mess up your code, so it still works (state X is stable) but it no longer possess some non-functional property you had in Y.
A catalyst may lower activation energy both ways, from X to Y or from Y to X. It's easier to make a non-functional mess in a dynamic language, because implicit contracts make many non-functional properties hard to see. Lambdas, although extremely convenient, may prevent a bunch of functions to coalesce into new, meaningful abstractions (a richer interface), which is instead split into single pieces. Acknowledging this duality is part of a deeper understanding of things, and a good antidote to the superiority complex that comes with so many languages and paradigms.
Notes
[1] The pictures above have been adapted from a work in wikimedia commons, which license allows unrestricted use, including modifications.
[2] I wish I could say that I know how to put numbers on Ea and DH. I'm very far from there.