Once again confirmation of Greenspun's 10th law:<p>"Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp."<p>You can, of course, safely drop the "C or Fortran" part.<p>Every program I've ever written, if it keeps getting used, maintained and expanded after ~2 years it gets it's own programming language, and therefore usually becomes turing-complete.<p>The most powerful abstraction one can make in an application is the ability to quickly combine large parts of the application into new functionalities, effectively implementing a programming language. Usually this starts with "macros": the ability to specify sequences to be executed in series with either fully implicit data-passing (e.g. we're always acting on this global state), and then someone points out that variables would be really good, and then you do that : local, named variables in macros. And there's your programming language.