How I got here

An entry published by James Bennett on October 16, 2006, Part of the categories Django, Frameworks, Meta and Programming. 14 comments posted.

I’m not a formally-trained programmer. I wasn’t a computer science major in college (my degree is in philosophy), and my first job after graduation didn’t involve programming (it was phone-based customer service at a health-insurance company). But here I am, developing software for a living.

I’ve never written a compiler. I’ve never hand-tuned something by dropping in bits of assembly, or even by writing C extensions for an interpreted language. I’m too young to have ever hacked on a Lisp Machine. But here I am, developing software for a living.

My language of choice is Python. I don’t evangelize it a lot, and not just because Python in general doesn’t market itself very much, or because I feel that language cheerleading isn’t a particularly productive use of my time. I also don’t evangelize it much because I feel like I’m not the sort of person to turn to for advice on choosing a programming language; I’m just a jumped-up liberal-arts kid who never took an algorithms class in college and is still playing catch-up on that front.

But every once in a while I feel like I should explain how I got here, and why I’m writing in Python, instead of PHP or Perl or Ruby or Java or C# or any other language that’s applicable to the domain I work in. So here goes.

Entry point

I didn’t grow up hacking. I learned BASIC as a kid (in fact, I learned a few different flavors of it at various points), and when I was in the second grade I learned Logo and used it to draw amusing pictures. But outside of brief encounters, programming wasn’t a part of my formative experiences. A lot of this had to do with the economic situation I grew up in; aside from a third-hand Apple II, neither I nor anyone else in my family had owned a computer until I was in my second year of college. Now, sitting on my couch with one computer in my lap and four more strewn around my apartment, I can’t help feeling that I’m living in unbelievable luxury; I could, if I wanted to, throw one of them away and buy a new one. What affluence!

So it wasn’t until I was in college that I had a chance to really learn much about computers. I started, ignominiously, with HTML, which I learned almost on a whim. I had to produce a web page for a class I was taking, and HTML didn’t look too difficult, so I dove in.

Naturally, I didn’t stop with the web page I was supposed to produce for the class; now that I knew how to write HTML, I took advantage of the free web space my college provided to all its students, and set up my very first personal web site. I had an irregularly-updated journal which I managed by hand, and I was proud of myself.

The next step, logically, was to learn a programming language I could use to automate the management of that site.

In those days, there were two choices for an amateur who wanted to dabble in web programming: Perl/CGI and PHP. I spent a little time looking at examples of both before I made my choice, but it wasn’t a particularly difficult choice to make.

Why PHP won

Most of the “serious” web programmers I came into contact with back then with wrote Perl, and tended to look down their noses at PHP. Looking at it now I can sort of understand why, but I also understand why they all kept a working knowledge of PHP on their résumés: PHP was winning over the Web. Perl was a more mature language and certainly a more robust language, but Perl was losing. It had been the language of web programming for quite a while, but still it was losing.

The reason is simple: PHP was easy. You just wrote your code, threw in a little bit of HTML, tacked a .php on the end of the filename and uploaded it. Whereas Perl, even at its best, required you to learn a few things about CGI and web servers before it would work on most hosting accounts.

And that’s putting it nicely. In more accurate terms, PHP stomped the ever-lovin’ crap out of Perl for a first-time web programmer. Perl was originally designed as a glue language to do text processing on Unix systems, and only later grew CGI functionality and server integration. PHP was originally designed to do web programming, and integrated into Apache in a way that even a mentally-impaired chimpanzee could understand. In the hearts and minds of a generation of new web developers, one of whom was me, Perl didn’t stand a chance.

My web hobby continued to be mostly a hobby for the remainder of my college years. I learned CSS, and I learned SQL and I learned JavaScript for the first time (and hated every second of it), and my little personal site grew lots of interesting new capabilities. Most of my disposable income was being spent on ways to impair the computer inside my head, so I never bought a real domain or real web hosting; when I graduated and didn’t have free hosting from the college anymore, I set up Apache on my personal computer (I’d been converted to Linux by that point), got a dyndns.org subdomain and kept on chugging. Once or twice, people paid me to build sites for them, but they never involved any serious programming.

Broadening horizons

I did eventually learn Perl, but I never really liked it. I usually attributed that to the fact that PHP had been so much easier, but as time went by I came to understand the real reason why I didn’t like it, a reason which was also behind my eventual break with PHP.

Right around the time I graduated, I started learning Python. Given that my first foray into JavaScript had been fairly shallow and I’d been using PHP 4 for web stuff, this was my first experience with real object-oriented programming. OOP was easy for me to pick up; it was an abstraction, and a useful, sensible abstraction to boot. Just for kicks I did learn some Java on the side, to get a feel for a “pure” object-oriented language, but I didn’t really enjoy that and don’t like to admit to it now.

Python was also my first experience with a language that allowed you to do functional programming, and my first exposure to the concept of functional programming in general. So I read up on it. I learned about Alonzo Church and the lambda calculus; I learned about Haskell Curry and the various things named after him; and I worked through a few basic Lisp tutorials.

The more I learned, the more I wanted to learn. I read as much as I could understand of the fundamentals of computer science (my degree in philosophy ended up doing a lot of good there; a philosophy major doesn’t have very many direct applications to the real world, but a solid grounding in logic and formal systems really paid off in this particular case), and particularly in the philosophies behind different programming languages. The guiding principles behind the various languages I’d learned started to stand out more clearly, and even though I started recognizing the flaws in Python I kept right on liking it.

And I kept wishing I could use it for the web stuff I was doing (by this point I’d quit my customer-service job and was freelancing full-time). Some guys in the local LUG were making good money building stuff with Zope, but it didn’t feel right to me, and I didn’t have the time or the energy to invest in learning it; Zope was such a mind-bogglingly huge thing that the only way to get a handle on it was to start memorizing pieces and hope they’d eventually come together and make sense.

Finally, something clicked.

Memorize this

One day a little light went off in my head, and I understood why I didn’t like Perl or PHP, and part of why I liked Python and a few of the other languages I’d dabbled with. Much later I was reading Steve Yegge’s rant about Perl and got to this bit, which explained it far better than I could ever hope to:

Every operator in Perl (not just the Range operator) has six different behaviors depending on the invisible context in which its surrounding expression is being evaluated. When you evaluate a hash in a string context, for instance, you get back a string that’s a fraction, such as “7/10”, the numerator of which represents the current number of keys in the hash, and the denominator of which represents of total number of buckets allocated. And so on, and so forth. There are no rules, no heuristics, no patterns. It’s pure memorization.

He’s right that a huge amount of learning Perl is memorization: committing all the operators and contexts and special global dollar-sign-plus-Chinese-character variables to memory and learning how to make them work together. And even though I’m fairly good at it, I hate learning things by memorization. I like to understand things, to know what makes them work and how their parts fit together; I don’t like hearing “oh, just assign this value to the the magic global $make_it_work variable, and remember that for next time”.

This also explained a large part of why I didn’t like PHP, because PHP is almost as bad. A lot of its problems on the memorization front could be solved by either A) implementing namespaces or B) choosing a consistent naming scheme for built-in functions or C) preferably both, but that’s probably never going to happen because the existing system has way too much inertia.

All of this is part of why I use Python.

Why Python, part 1

Python asks for very little in the way of memorization. The core language is small and the built-ins have sensible, consistent names. The standard library is large, but everything is in module namespaces, and you can be an advanced and very productive Python programmer without having to memorize every symbol exported from every standard module — knowing a few important modules well, and having a good general understanding of what the rest of them do, is enough to take you a long, long way.

Yearning to be free

I’d been hearing rumblings for a little while about something called “Ruby on Rails”, and how it basically kicked the crap out of everything else in the web-development world the way PHP used to, and I was intrigued. So I started learning Ruby and picking up Rails.

This was a pretty interesting experience, because it organized and cemented a lot of things I hadn’t really understood previously, like metaprogramming. Rails really isn’t “Ruby” so much as it’s a domain-specific language for web programming which happens to be implemented in Ruby. And Ruby as a language is exceptionally well-suited to writing domain-specific languages. It was the first time I’d seen that sort of “bottom-up” approach in the real world, and it was an eye-opener.

Unfortunately, from a professional perspective I was still stuck firmly with PHP and Perl, and getting more and more stuck every day. I’d built a reputation on being handy with a couple of niche CMS products, and business generated from that reputation was paying my bills and putting food on my table, so I couldn’t just dive headlong into something else. And, of course, the Rails hype machine and the associated bevy of companies willing to throw money at people with any sort of Rails knowledge hadn’t yet kicked into full gear; if the timing had been different, I would now be writing Ruby by day and snorting coke off the bellies of hookers by night.

And even though Ruby and Rails were unarguably cool, I still really liked Python.

And all that jazz

In the summer of 2005, a new Python web framework popped up, and immediately people started comparing it to Rails. I set it up on my testing machine (by this point I was rich enough to afford two computers!) and started fiddling with it, and I was almost immediately hooked. There were some un-Pythonic things about it, and there was a fair amount of “magic” in it (both have been dealt with since), but I realized I’d finally found what I was looking for. I could finally use Python on the Web.

The rest, of course, is history. I got involved in the Django community, one thing led to another, and now here I am, working at the Journal-World, writing Python full-time, maintaining a couple branches of Django and loving every minute of it.

But playing with Django was the final little nudge that made me understand the other thing I’d always liked about Python, even though I’d never been completely conscious of it before. It tends to get glossed over a lot, but it’s probably the single most important feature of Python.

It makes sense

When I worked in PHP and Perl, I was mostly working with a couple of off-the-shelf open-source CMS products, which I learned to adapt to various tasks. In PHP I was using Textpattern, and in Perl I was using Scoop.

Of the two, Scoop is by far the more massive, and I was extremely fortunate in mostly being a subcontractor for a couple of the people who develop it; when a client needed Scoop to be hacked up, I didn’t have to do the heavy lifting. And that’s good because, even though Scoop’s Perl is pretty clear and straightforward, it’s still a massive system written in Perl, and massive systems written in Perl are not things that you can just dive into the source of and start understanding.

Textpattern is smaller and simpler, and is written in PHP. PHP can be written in an obscure and confusing manner, but Textpattern isn’t, or wasn’t the last time I looked at it; most of it is clean, well-written code. But figuring out what was going on inside Textpattern still took me a little while, and wasn’t as easy as I’d have liked it to be.

When I was learning Rails, I took a few peeks under the hood; the face it presented to an end user was so tightly organized that I figured its internals would be pretty easy to work out once I got over a few speed bumps related to my inexperience to Ruby. I figured wrong. As it turns out, even some of Rails’ biggest evangelists and core people will tell you that its source is not for the faint of heart. There’s so much metaprogramming and, worse, monkeypatching of monkeypatching, that just figuring out where you are in the code can take a good long while.

A little while back I wrote an entry which walks through all the steps Django takes in processing a request; I wrote that mostly because someone asked for it, and until I started writing I had only a rough, general idea of what went on inside Django (if that sounds bad, keep in mind that Django was, at the time, nearing the end of a major rewrite, and huge swathes of code had changed).

That entry took about four hours to write. That’s including the time I spent writing, and the time I spent poking around in the code to see what was going on at every step. Given all the stuff it does, Django’s internals are amazingly simple and clear, and you can easily carry the whole thing around in your head.

Why Python, part 2

Get ten programmers in a room and ask them to rank the things they value most in a programming language, and you’ll get ten different sets of rankings. Some value conciseness above everything else. Others value expressiveness (which isn’t the same thing) more. Others look for strong standard libraries. Still others will go on about the merits of different philosophies of type handling, or availability of multiple implementations or all sorts of other things.

If you’ve got a Python programmer in that hypothetical room, odds are that at or near the top of her list will be “readability”.

Pretty much from the beginning, Guido has stressed that Python should be a language that’s easy to read (and, by extension, easy to understand), and several features of the language itself work to enforce that. On top of that, the official style guide seems to be fairly widely used, and there is a general sense in the community that, outside of things like “obfuscated Python” contests, code that’s clever at the expense of readability is bad.

And with the sole exception of Zope, pretty much every significant piece of Python code I’ve ever looked at has been clear, consistent, and relatively easy to follow along with. When I’ve had to stop and take a while to think something through, the language has rarely been the cause; it’s almost always been the fact that whatever I was looking at was dealing with some genuinely hard and complex problems, and so understanding the code required a corresponding understanding of those problems.

It’s an interesting variation on one of the Perl slogans: in Python the easy things are easy to read, and the language doesn’t make the hard things unreadable. To someone who’s constantly trying to learn and understand newer and harder things, that’s enough to forgive almost any other sin of language design (and Python does commit several of those, but on the whole it’s surprising how little there is about it that needs forgiveness, compared to other languages I’ve tried).

It may not be right for everyone, and I won’t ever try to argue that it is, but that’s why Python is right for me. That’s why I’m writing Python instead of PHP or Perl or Ruby or Java or C# or any other language that’s applicable to the domain I work in. It took a long time, and it took some radical changes in how people think about web development, but I’ve finally gotten to where I can do this, and it makes me happy.

On October 16, 2006, CoolGoose said:

I’ve only played with pascal/c/php/ruby and python but i can say that python is my one true love for the fact that it’s code is readable. I think you must try VERY HARD to make a python code unreadable. My only problem so far is that not many webhosts accept python.

On October 16, 2006, onno said:

Hi, I’m also a philosopher of education with dyslexia. I’m following almost the same path as you. I’m now full time prof. in webdev and turning to django.

On October 16, 2006, Adam Spooner said:

I love reading about how people got started in programming. It seems that most of the best programmers (in the world of the web) started in some arena other than programming.

Python and Ruby tie in my book in the readability department, though Python wins out for web programming because Django makes sense to me more than Rails does.

I’d also note that PHP is not so readable in that upon reading one must decipher PHP and HTML at the same time. I like clear separation of the logic and the view.

Great read!

On October 16, 2006, Bastos said:

Python is beautiful! I’m php hacker (on job) , but i’m a python lover ( django too )!

On October 16, 2006, Matt Boersma said:

My story is similar to yours, James. I’ve been a full-time programmer since 1991, but my background was in Russian Studies and Public Policy. But my formative childhood experiences were things such as soldering together a HeathKit Z80 computer so I could write assembler and CP/M programs. (And lots of riding my bike around town, fishing, skiing, etc.)

It took me many years to figure out this hobby I had, tinkering with computers, was the only thing I could see myself doing as a career. And as luck would have it, my girlfriend lived in Silicon Valley, where it wasn’t hard to get my foot in the door.

My evolution was from Z80 Assembly to BASIC and Pascal, to C, to C++, to Java. Java was the first big revelation for me. Suddenly I was much more productive and began to see the patterns I’d been using emerge intentionally.

After four years of doing nothing but Java, I linked in jython.jar to a client application to see how scripting might help us. I had another epiphany similar to my Java awakening, except my python epiphany hasn’t really stopped.

The next project I had, I wrote all in jython. Without asking anyone. They all thought I was writing Java, and the app was fast enough and interoperated fine with all our libraries.

Now I get paid to write real python code, and I have to pinch myself every day.

It’s been another few years living only in Python-land. I don’t want to wear blinders, so recently I made myself learn Ruby and write a Rails app. If Ruby were the first agile language I’d learned, I’d probably be as jazzed about it as the Rails crowd is, but as it is I can’t imagine using Ruby for anything voluntarily. I learned Perl, and that was enough cruft in my brain.

I’m also getting into Erlang, which has some fantastic ideas, but I’m having a hard time seeing how functional programming solves some problems I see as OO patterns. Maybe I’ll get there someday.

On October 16, 2006, Robert Simplicio said:

Hey James, glad I found your new ‘blog, as I know from previous experience you have no shortage of great information and inspiration (and not in “Defenders of Design Theft” sense).

This is a great post, and I just have a couple of questions for you: Knowing what you know of Django, and that you have used Textpattern in a previous incarnation, can you recommend a Free Django CMS?

Secondly, I’d be interested to hear which little town in WV you grew up in; my entire family is from McDowell County (though I was born in VA). E-mail me that if you’d like.

On October 16, 2006, Max Battcher said:

Knowing what you know of Django, and that you have used Textpattern in a previous incarnation, can you recommend a Free Django CMS?

Django. I know it sounds like a joke and I’ve heard a score of complaints that each and every person tends to implement their own individual Django CMS for their project, but to me that speaks to a lot of the strengths of Django. My personal website and the website I maintain for my student council (SpeedCouncil.org) both have very widely different needs from a CMS, and share very little code, but I haven’t “rewritten” anything and there’s no unnecessary duplication. The same absolutely cannot be said for the websites when I was using PHP.

Keep in mind too that the key piece needed for a CMS is provided largely out of the box by Django: the brilliant, well-designed, Admin site. 90% of writing or dealing with a CMS is “How do I input data?” and the Admin site removes that worry leaving you with the much simpler problem of “What data do I actually need for this website? What’s the best way to store that data?”. With Django’s Admin I get the cool features that constrained PHP CMSes provided and yet I much more constrained data types, better data integrity, and an easier time to doing real cool data queries that actually make use of the relationship power of a modern RDBMS rather than treating the RDBMS like a glorified file store.

Obviously there are bits and pieces that you might want to borrow from others. For instance, I’ve borrowed Ivan Sagalaev’s Tag library for my personal site. But such pieces are rarely the types of monolithic behaviors that “CMS Engines” require on other languages, they are much more organic components that graft into your own design rather than force you into someone else’s.

I’ve been all over the PHP CMS spectrum (DIY, Nucleus, Drupal) and the freedom and the power over the design of Django websites has just been empowering and I’d certainly have a hard time going back to an “off the shelf CMS” again.

On October 16, 2006, Jeff Croft said:

Django. I know it sounds like a joke and I’ve heard a score of complaints that each and every person tends to implement their own individual Django CMS for their project, but to me that speaks to a lot of the strengths of Django.

I agree completely. People are constantly asking me why there are few (no?) free Django-based CMSes on the market. My answer is always the same: because it’s so easy to custom-build one that is absolutely, 100% tailored to your specific needs that taking one “off-the-shelf” that only manages to come close to what you’re looking for just seems silly.

I can write a Django CMS in less time than I can customize most off-the-shelf CMSes to do what I’m needing them to do — and I’m not even really a programmer. So, why would I pick an off-the-shelf one?

On October 17, 2006, Robert Simplicio said:

Thanks to both Matt and Jeff for your schooling of the newb. I’m just so used to, you know…needing that stock implementation to feel right.

Now that I type it, it kinda sounds like crack. Interesting metaphor, no?

On October 17, 2006, bobvar said:

Hey James, I heard about python long time ago but got interested in it after reading your story. One blogger said not many webhosts use it. Do you know of any that use it? Thnx!

On October 18, 2006, mrben said:

Always good to hear other peoples stories. For me the biggest draw of Python was that, for the first time since BASIC, I would see things and think ‘I can do that’. The mix of simplicity and power was undeniably alluring.

I’m still learning with Django, but I’m beginning to get that feeling.

bobvar: I have a Dreamhost account, which works fine with Django (having followed Jeff Crofts instructions), although I’m sure there are others.

On October 18, 2006, Josh Blount said:

I was going to send you an email with the following, however I didn’t see a contact form (forgive me if I overlooked it)

Your personal site has been incredibly useful to me in the past few days. I’m working my way through django and python on the whole and both the conversational style of your writing and the in depth nature of the articles you have posted so far have been invaluable. Thanks so much for your contribution to that community, I certainly appreciate your hard work.

On October 19, 2006, Maleika E.A. said:

A big reason for liking your site as much as I do is because I, too, studied philosophy at Uni. I have no formal education in programming or any IT field. :)

Thank you for your insights. A very interesting read that makes me curious to take a peak at Python.

On October 19, 2006, Robert Simplicio said:

bobvar, I can tell you that TextDrive does Python and Django, and I know James from TextDrive and the TextDrive forums (not to mention the former Anemone project; but that’s another story). In fact, this site is hosted by TextDrive.

They’re over at http://www.textdrive.com

James also has a Django forum up and running that he moderates over on http://forum.textdrive.com/viewforum.php?id=28

Come check it out (I obviously am also a TextDriver). It’s a little different, but we think you’ll like it because of that. If you have any further questions, feel free to find me on the forums (rsimplicio) and send me an e-mail.

Comments for this entry are closed. If you'd like to share your thoughts on this entry with me, please contact me directly.

ponybadge