Q: Why is programming fun?
A: It is a form of play and exploration in which a "one-time" "small" effort (writing the program) yields a large reward (the program does something). It combines the artistic joy of creation with the scientific reward of nutting out a puzzle.
Q: Why is programming hell?
A1: When the program fails to produce the expected results a diagnostic process of "debugging" follows. As the program grows in size and power and (hence) complexity, this debugging phase dominates the programmer's time, and brings mainly relief rather than reward.
A2: When requirements change the program may need to be re-jigged to accommodate them, and this re-jigging, similar to debugging lacks the immediate rewards.
* * *
So, to increase the rewards of programming -- and incidentally productivity and profitability -- techniques are sought to reduce the dross (debugging and re-jiggering), and increase the rewards (features and elegance).
On the Yang side of programming I include design, architecture, algorithm invention, and implementation of new features.
On the Yin side I include practices like Design By Contract (DBC), Test Driven Development (TDD), and Continuous Integration (CI). These provide no up-front reward, but pay for themselves over time.
Interestingly, all three involve using programming to write better programs. DBC and TDD may be regarded -- with some licence -- as simple forms of meta-programming. We are writing program fragments to help test our programs. Also, the act of making tacit assumptions explicit helps us to think about and hence improve the underlying design.
By putting in place these effective (Yin) measures, we can be bolder (Yang) in adding new functionality, having built a software safety net as we step forward.
True meta-programming, writing programs that write programs brings us back to the Yang side.
We are now truly working at a higher level of abstraction, with correspondingly more leverage, but when bugs appear in our meta-programs the debugging gets harder too ...