Wednesday, July 22, 2009

Do You Believe In Magic?

A couple months ago, a pro-Django, anti-Rails screed annoyed me, but not for the normal reasons. I have no problem with people writing these screeds. As long as there are people, the majority will always quibble over minutiae and choosing to aim higher will always be unusual.

Most people who use either language don't make full use of its advanced features, and programming simple monkey code in Python is so similar to programming simple monkey code in Ruby that they might as well be the same language, at that level. My Hacker Newspaper mini-site runs on both Python and Ruby, and it doesn't make a shit's worth of difference. But X vs. Y is a reasonable question, for the many people whose ambition fails them and strands them in the swamps of mediocrity. I pity them, but I don't think there's anything wrong with comparing notes about the sizes of mosquitos from swamp to swamp. No problems with any of the usual "Python vs. Ruby" blah blah blah, except for the fact that the whole question is boring and small-minded. Say what you want; choose whichever language you prefer.

What really bothered me was the title:

I Hate Magic: Why Django Rocks!

Specifically, the horrible term "magic."

So I got my rantin hat on, stomped down to the comments section, and I ranted me up a rant:

The concept that particular language features are more "magical" than others is insane bullshit. None of it involves fairy dust or anything particularly complicated; it's all just Ruby. There is no such thing as metaprogramming. It's all just programming.

This is a thing that's been bugging me lately. I have no interest in this thing of Rails vs. Django. Use what makes you happy. But there is absolutely no logic in calling language features "magical." It implies that certain programming techniques are inherently fantastical and strange. That's only the case if you don't understand the language.

If you take on this attitude that some language features are "real" and some language features are "magic" you're not going to make rational choices when it comes to deciding what language features to use. You're going to make superstitious choices, because this division between the "real" and the "magical" is a superstitious world view.

Rationality is a better mental attitude for programming than superstition.

If you want to see my prediction about superstitious programming decisions come true, find a place where there is no logical reason not to use eval() in your code, put eval() in there, and watch motherfuckers freak out like you were throwing elephant dung at the Pope. There are plenty of places where it is intensely dangerous and foolish to use eval(). I'm not disputing that. But it is so easy to find ways to use eval() which are completely immune to any danger of any kind, and yet which still trigger paranoia in superstitious programmers.

The problem goes much deeper than this, however. Ask yourself this question: if you were a Lisp programmer coming to Ruby, would you describe any of Ruby's features as magical? From a Lisp point of view, Python has more magic in it than Ruby. From a Lisp point of view, both languages feature a certain number of invisible walls, blocking you (for no comprehensible reason) from taking simple, direct paths from A to B. Python is more magical than Ruby, from a Lisp point of view, because it features a larger number of invisible walls, and the paths around them are less consistent.

A superstitious programmer might answer that the Lisp point of view is a strange point of view. The implication is that a point of view which considers "normal" various arbitrary restrictions in a programming language's power is the rational point of view. I disagree. It might be the common point of view, or the popular point of view, but it's not the rational point of view. If it were the rational point of view, it wouldn't include a belief in magic.

Like many of the current, new generation of Rubyists, I came to Ruby because of Rails. However, unlike many of my generation, I stayed because Ruby is an acceptable Lisp. Prior to discovering Ruby, my programming fascinations were artificial intelligence and Lisp. If using Ruby as a Lisp were as cumbersome as using Python as a Lisp (or as unruly as using Perl as a Lisp), it's very likely I would have moved on.

One of the great things about Ruby is that you can come to Ruby from Lisp, and be happy, and you can come to Ruby from PHP, and be happy. Ruby is a fantastic melting pot, in this regard. But let's take that metaphor a little further. Here's what's going on if you complain about "magic" in Ruby. Some of us came to Ruby from more sophisticated places and we know that this so-called "magic" is a little on the quaint and limited side, but we don't make a big deal about it. But if you're coming to Ruby from PHP, that's like coming to New York City from Palookaville, Omaha. You're staring at the electric lights and you're wondering if there's some kind of witchcraft involved.

I'm from Chicago. I used to live in San Francisco. San Francisco is a beautiful city, but I always used to think it was silly when people from smaller towns called San Francisco "the big city." Chicago's population is about 40 times San Francisco's population, and it felt tiny to me. Beautiful, no doubt, but tiny. That's how I feel when I hear small-minded programmers calling a few mostly-elegant shortcuts "magic." Because if you think that's magic, you haven't seen shit. That is some Palookaville, Omaha bullshit, and you need to see the fucking world.

Now, again, when people complain about "magic" the reason they do it is because Ruby's mostly-elegant shortcuts are not quite as elegant as they could be, and also because since everything at the beginner level in Ruby is easy to get right the first time, a lot of Ruby beginners assume its "magic" will be also, and codebases suffer as a result - because Ruby's "magic" is only easy to jump right into for Lispers and Smalltalkers who have seen it all before and already learned the necessary skills. For everyone else, there's pain, there's codebases falling apart, there's ridiculous incomprehensible errors. I'm not disputing that. I understand that. I sympathize. I have felt that pain.

However, a rational viewpoint will serve you so much better, as a programmer, than a superstitious one. It's not magic. There is no magic involved. It's just, if you never learnt Lisp, then you never learned to program, and Ruby's power is exposing a deficiency in your skills. That's all. And with so many former PHP people and Java people who never really learnt to program jumping on the Ruby bandwagon, it's no surprise that a lot of code is breaking at that exact point in Ruby where the monkey-code features end and the real-language features begin.

The correct response is not calling arbitrary features "magic". The correct response is to finish learning how to write code. And please believe me, you're not going to be able to master it until you stop calling it magic. Recognize it for what it is. It's programming. That's all.

Will he finish what he begins?