I like Python! No, wait, Ruby! No, but Python…

I hate Ruby.

There I was, just buzzing along, using Python, satisfied that I knew one of the coolest languages around, and definitely the coolest language you could actually get a job with.

Then Ruby came along.

It was English-like. It was practical. It was fun. It was possible to get a job with it. It was even Japanese.

Almost everything about Ruby’s syntax, language features, and library just made sense to me almost immediately. I don’t mean I immediately understood the entire language—blocks took me quite a while to understand, and metaprogramming can be pretty confusing for almost anyone, unless you’re Dan Friedman. I mean that I almost immediately saw, on some intuitive level, why Ruby had been designed the way it was. My mind easily fell into thinking the way Ruby wanted. Even when I barely knew the language, I could figure out just where to bust out a line-ending if or while. I immediately loved string interpolation.

By contrast, there are plenty of things in the Python language and libraries that, to this day, do not make sense to me. I learn them by memorization and use them. Examples are len being a function instead of a method, and the entire os.path module. Once, I needed a quick script to process a few files in some nested directories. I’d only been learning Ruby for about three days, and I wanted it done quickly, so I used Python. I struggled for an hour to write a Python program using os.path.walk, and finally decided to look into how Ruby would do it. I had the thing done in Ruby in ten minutes.

Other parts of Python make sense in a tortured sort of way, like writing ' '.join([1, 2, 3]) instead of, say, join([1, 2, 3], ' ') to join some strings. Yeah, fine, I understand that it makes some kind of sense to think of it as “String ‘ ‘! Join the list [1, 2, 3]!” rather than “List [1, 2, 3]! Join yourself using the string ‘ ‘!”. Just like it makes some kind of sense that C++ uses virtual void flagellate(int flagellant) = 0; to declare a pure virtual function, since you’re initializing the function’s pointer to null. But just because they kind of make sense when you think really hard about them, that doesn’t make them obvious (like the Zen of Python claims to want), and definitely doesn’t justify the kind of condescending blather that the Python FAQ presents in response to the question of why it’s ' '.join([1, 2, 3]).

Maybe it’s because I started as a natural language guy, in English and linguistics, that Ruby makes so much sense to me. People complain that it has too many different ways of accomplishing the same thing. It definitely flies in the face of Python’s “There should be one obvious way to do it”. On the other hand, Python itself frequently chooses ways to do things which aren’t incredibly obvious, like the aforementioned os.path.walk. That there is only one way to do it, if anything, just makes the non-obvious nature of that way hurt even more, because there’s no way to get out of it.

To me, Python is designed like a formal system, while Ruby’s design is more like a natural language. Of course, there are languages much more like formal systems than Python; there’s Lisp, and Haskell, and Scala. Even Java, once you stop looking at syntax and warts like arrays and primitive types, and just look at its efforts to be “objects all the way down”. But Python seems to have aspired to the same kind of minimalism as Lisp. Python aspires to rid itself of synonyms and homonyms, to make all antonyms expressible by sticking “not” at the front. Ruby takes on extra syntactic baggage like “unless” and suffers methods with different names that do the same thing, in the name of being more obvious and readable to humans. Python believes that explicit is better than implicit. Sometimes you have to write more for the sake of making it explicit. Ruby tolerates weirdnesses like the flip-flop operator, which does a boatload of implicit stuff behind the scenes, on the principle that it’s fairly common to do something like that, so you can memorize one set of implicit behavior.

Please don’t take this to mean I think Ruby is better than Python. I said that Ruby, the language, and several of the libraries, fit my style of thinking better than Python. And even more, please don’t take this to mean that I think crazy things like Perl’s implicit $_ variable are okay. Ruby, I think, gets just the right amount of redundancy and implicit behavior; if Python has too little, then Perl has far, far too much. Ruby, I think, gets just the right distance between natural language and formal system; Scheme and Haskell are a little more like a formal system than I prefer, but Cucumber and AppleScript get much closer to natural language than they should. Cucumber and AppleScript are wonderfully easy to read, but horrible to write, while Scheme and Haskell are nice to write, and the end product is very aesthetically pleasing in a classical sort of way, but can be rather hard to read.

So, given that I liked the Ruby language better than the Python language, why haven’t I dumped Python yet? Third-party libraries.

Ruby has amazing libraries related to the web. Rails has been extensively talked up. I made another visit to it after I put some serious effort into learning Ruby, and I found it a lot more pleasant than I remembered. By contrast, I started to find Django code-y and somewhat laborious. Sinatra is also well-liked. Nokogiri blows away any HTML/XML processing library anywhere that I can think of; Python’s Beautiful Soup is great for scraping HTML, but less useful for XML, while Clojure’s Enlive is great for scraping and templating, but again, less useful for XML than Nokogiri. Let’s not even talk about Python’s standard library HTML and XML parsers; the HTML parser is a horrible Java-wannabe library that makes you implement your own API, while the XML parsers are cumbersome and limited.

Ruby’s libraries in other areas that are of interest to me are less impressive. Python has NumPy, SciPy, Natural Language Toolkit, BioPy. Clojure puts in an appearance with Incanter and OpenNLP, and there are some Java libraries here that you can use. Ruby has basically nothing in scientific computing, NLP, or bioinformatics. It could be great for all of these areas, because they’re all interdisciplinary, and I suspect that people from outside math and computer science would find Ruby easier to just get than other languages, the same way I did. But the Ruby community’s main concern is the web, and it shows.

If Python were a bad enough language, I wouldn’t feel so conflicted. But Python’s not a bad language; it’s a great language with a few annoying facets, most of them superficial. I like Ruby the language better, but Python’s sure better than a cup of hot Java in the face, to say nothing of being skewered by a C++. Most of the libraries I want are in Python. Some are in Ruby, but the ones that aren’t are huge ones that aren’t likely to be replicated in Ruby any time soon. Python is, in fact, probably the only language that has all the libraries you could ever want, is pretty nice to read and write, and can also get you a job. And I would have been happy with it forever, if that stupid Ruby hadn’t come along.

But I’m also mad at Ruby for creating this internal conflict for another reason: if I had never learned of its existence and just committed to Python, maybe I would know it well enough to have a job by now.

Stupid Ruby.

I’m a bad programmer; where do I get a job?

I’m a bad programmer.

I did everything in my power not to be. I read widely in the field. I read blogs. I read texts. I read programming language manuals. I read code. I studied ancillary fields like discrete math and electrical engineering. I took challenging courses. I took Steve Yegge’s trifecta of compilers AND operating systems AND machine learning. I learned several programming languages, including an imperative language (C), some object-oriented languages (Java, C++, Python, Ruby, Visual Basic.Net), a functional language (Clojure), a prototype-based language (JavaScript), an assembly language (x86, with MASM). I did side projects. Not huge ones, but I wasn’t spending my summers playing D&D or anything.

I still ended up a bad programmer.

I’m honestly puzzled that it turned out this way. Sometimes I think that maybe I wasn’t meant to be a programmer. But the evidence is mostly against that; even though I discovered programming relatively late (22 years old), I turned out to have so many of the common traits of programmers—a pedantic, nitpicky attitude; a comfort with abstraction; a lifelong interest in computers and technology—that it almost seems like destiny wanted me to be a programmer, and I just screwed it up somehow.

So, fine. I’m a bad programmer. I’d still like to work as a programmer. I don’t have the temperament to be a manager or a sales rep, nor the education to be in marketing. I’m no good at working with my hands, and I’m not the kind of person who’s interested in building up a business. My grades were too mediocre to get me into graduate school (because I took challenging classes as a bad programmer), so I can’t be a professor or a lecturer. So I’d like to work as a programmer. There’s just one problem: I can’t figure out where bad programmers get jobs.

I know they get jobs. The Daily WTF is full of stories about bad programmers who got jobs, and left behind awful code to torment future good programmers. While I feel somewhat bad when I think of all the innocent good programmers I’ll unknowingly torment in the future if I do get a job, I can quash those feelings. My current job involves handling the excrement or vomit of random strangers on a daily basis. To get away from that, I’ll let the howling wails of a few good programmers, seeping across time from the future, fall upon deaf ears in the present.

I tried applying to companies that were looking for good programmers, hoping maybe I could fool someone. So far, no one has been fooled. The irksome thing is, only one company so far has actually outed me as a bad programmer. The rest knocked me out because of years-of-experience requirements which weren’t even on the job ad, or because I don’t know Spring MVC when it wasn’t even on the job ad, or some other thing that wasn’t even on the job ad. If your interview process is able to uncover what an awful programmer I am, I guess I can accept my defeat. But most of these guys didn’t even give me the chance to trick them. It’s pretty annoying; for all they knew, I was a good programmer. For all they knew, I was the best programmer ever. They didn’t bother to find out.

But bad programmers must get jobs. There are too many stories on The Daily WTF. They can’t all be good programmers who just missed their morning coffee the day they wrote that five hundred-line quintuply nested switch statement, or whose dog died the day before they wrote those preprocessor macros to make C look like Pascal. Bad programmers are working somewhere. I need to find out where that is. I need to figure out how to get a job at Bad Programmer Central, writing awful code, using mind-numbing technologies to solve boring problems, coming in to work at nine and leaving at five and giving not a single thought to code except when I’m at the office. These mythical people must exist; they’ve been mentioned too many times on The Daily WTF and Coding Horror and Joel on Software and Scott Hanselman’s blog not to exist. Scott Hanselman attributed something negative (I don’t remember what) to these people on Hanselminutes once. He wouldn’t do that if they didn’t exist, right? That would be like Charlie Rose attributing problems in the Middle East to Bigfoot, right?

So tell me. Tell me where bad programmers get jobs. Because I’m a bad programmer, and I need a job. If you tell me now, I’ll swear never to work at the same company as you. Then you won’t be the one howling with anguish at the awful code I leave behind, and you can feel good about helping out a bad programmer in an hour of darkness.