I used to say that when it comes to comparing Ruby and Python, my personal opinion is that Ruby is worse. I absolutely was wrong. To misquote Stalin, they are both worse.

It’s about a month since I switched to working in Python. The project consists of few layers: an infrastructure to control ffmpeg-based video transcoding, elastic cloud running on AWS that hosts those transcoders, and a web front-end to control all that. The more I deal with it, the more I think fondly of the time when I’ve worked on similarly-structured projects in Java.

Don’t get me wrong: what comes below is not a criticism of Python as a language or an ecosystem, it’s more of “what a pity that a great platform like Java gets so little love from hackers.”

For example, a typical setup for a Python web app is nginx, WSGI and some framework (we use Bottle). Now, a typical setup for Java web app is a container (say, Tomcat) and a framework. In Java, when I need to debug my web application, I go to $TOMCAT_HOME/log directory and find all the logging output there. The logging libraries everyone loves to hate, log4j and slf4j, do an enormous amount of heavy lifting to allow a fine-grained control of the logging output not only of your program, but of all the libraries you depend on, plus the container itself. Where do logs from nginx go? Oh, it’s /var/log, whereas WSGI and your app normally log to some different place. Want to reconcile them? Good luck with that.

The famous slogan of Java, “Write once, run everywhere” was a foundation for a mindset that Sun used to enforce. Dependency on the external native libraries was considered a bad taste and a last resort. For example, JDBC drivers were split into four types, from least portable type 1 to pure-Java type 4. Python language is portable, but Python libraries are not — most of them are just wrappers around native binaries, and when Pythonistas say “native”, they mean “Linux”. It took me about an hour to run into a library that our project needs and that does not work on my favourite operating system. That’s pyinotify, a wrapper around a Linux kernel function called inotify, used to watch for changes in the file system. I do understand that it’s hard to develop a library like this that will be portable, but developers of Java managed to.

The situation with native libraries is made even more complex by the fact that Python processes themselves are rarely long-running. They are normally spawned by more stable processes, in our case crond and nginx. Controlling native libraries with LD_LIBRARY_PATH gets even more painful. How do those processes inherit environment variables? How to debug it?

You may ask why I mention Ruby here at all. I think that Ruby and Python together did a very big thing to programming. They made it popular. In parallel with that, they made it seem easy. But it’s not easy, it’s very hard. Programming only seems easy when you focus on some particular detail and ignore the rest, because in most cases it’s the communication with the rest of the world that makes software systems complicated and hard. And as much as everyone likes to say that Java is for people who like to build factories of factories, you have to give Sun credit. They didn’t ignore details they didn’t like.

What a great language.