Do You Believe in (Coding) Magic?
This article reflects merely my own thoughts and opinions. I doubt it applies to you personally, so don’t think I’m proposing a new law.
Last night, as my LAN-party-attending friends and I drove home from the pizza place, I was asked to explain the concept of Turing-completeness. I managed to give a somewhat coherent overview of the topic without simultaneously befuddling my listeners, and gave examples of Turing-complete and non-complete languages. Listing off my favorite programming languages, all of which fell in the former category, I was struck by a realization, and drifted off into thought until awoken by the derision of my peers.
I appreciated the furor on reddit regarding my How to Beat Rails and Blocks != Functional Programming posts; debates between programmers are often informative and always entertaining. The contests between languages, though they rarely (if ever) change anyone’s mind, are fertile ground for inflammatory quotes and flame wars. But the realization I came to in the car yesterday was this - since almost all programming languages are Turing-complete, what’s the difference? At a fundamental level, they’re all the same, right?
Then why do I like Python and Ruby so much more than C or Java? Why, indeed, doesn’t everyone just write bare machine code? Am I wasting my time wondering about abstracts instead of actually coding? I pondered these questions through many hours of video games, and eventually came to a conclusion.
The largest factor in whether I like a language is its attitude towards “magical” behavior. “Magical” behavior is difficult to define - my best effort is ‘the ability to redefine the most fundamental aspects of the language’ - but here’s an example, taken straight from the perlvar man page:
$[
The index of the first element in an array, and of the first character in a substring. Default is 0, but you could theoretically set it to 1 to make Perl behave more like awk (or Fortran) when subscripting and when evaluating the index() and substr() functions.
Perl, which I loathe with every fiber of my being, condones - nay, encourages - the deep, evil, horrible black magic to find the quickest way around a problem. Ruby, which I like more and more with every passing day, allows for happy, Good-Witch-of-the-North-esque magic with metaprogramming, different eval() scopes and near-total introspection. Python, which I’ve loved since the seventh grade, really discourages the use of magic - custom infix operators are the extent to which Pythonistas have dabbled therein. However, it always tries to permit the clearest, most concise non-magical solution to a problem. Scheme, which I respect, isn’t so much a language as a wellspring of magic through which you can do whatever you want. In the right hands, it’s brilliant, and in the wrong ones impotent. Rails and Pylons reflect the different attitudes towards magic - Pylons requires you to render the templates explicitly, while Rails just evaluates instance variables and goes with the flow.
In summary, my preferred language depends on attitude towards magic - my favorite languages either allow for positive, as-readable-as-possible magic (Ruby) or disallow it altogether (Python.) Which is better? It depends on your situation - and on the necessity of good documentation. (Documentation, and therefore long-term maintainability, cannot coexist with magic.) Overall, though, I enjoy a little code magic - do you?
13 comments February 25, 2007