Large scale software development is unfortunately statistical.
C++ pretends to provide an object-oriented data model, C++ programmers pretend to respect it, and everyone pretends that the code will work.
Remember that the job of your model layer is not to represent objects but to answer questions.
There are plenty of other ways to develop crappy software. Create countless layers of abstraction. Make everything a framework, pushing all the real work (and bugs) into configuration files and the database. Split functionality into tiny pieces that make no sense on their own, but somehow work together.
All repairs tend to destroy the structure, to increase the entropy and disorder of the system. Less and less effort is spent on fixing the original design flaws; more and more is spent on fixing flaws introduced by earlier fixes. As time passes, the system becomes less and less well-ordered. Sooner or later the fixing ceases to gain any ground. Each forward step is matched by a backward one. Although in principle usable forever, the system has worn out as a base for progress.
Frederick P. Brooks, The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition)

The case for Clojure:

• Concurrency is not the problem! State is the problem. Clojure’s sweet spot is any application that has state.

• Don’t burn your legacy code! Clojure is a better Java than Java.

• Imperative programming and gratuitous complexity go hand in hand. Write functional Clojure and get shit done.

• Design Patterns are a disease, and Clojure is the cure.

Stuart Halloway
Yes, you have to worry about memory management and buffer overflows, but if you have valgrind you’re set. Valgrind is awesome because it detects most memory errors fairly flawlessly, assuming you’re not an asshole who codes retarded C tricks.

dibs