Monday, December 06, 2004

Java is not Python, either...

With the overwhelming response to my earlier Python Is Not Java post, I thought I'd take a little time to be fair and point out that Java Is Not Python, either. While Python is more powerful as a language, Java beats the crap out of it in the area of standards and specifications like JDBC, JNDI, and OSGi, to name just a few.

Of course, Python folks typically react with disdain towards such things, preferring in most cases to "roll their own". For Python, the only standards are PEPs and the standard library. While a Java spec can run to hundreds of printed pages, a PEP is pretty much limited to what you can humanly read in a single web page, and the standard library is defined by its documentation and implementation, and only gets updated once a year or so.

In a way, the current flap in the Python community over standard library improvements versus language changes is a symptom of the cultural difference between Python and Java. In the Java world, it's generally understood that there may be reasons to have multiple implementations of a specification, so the specification is the community focus rather than a single implementation. It also isn't necessarily assumed that once a specification is implemented, it becomes part of the Java platform. (For one thing, nobody wants to wait around for a new platform version.)

Specifications themselves are an inherent part of Java, too. Java has interfaces, Python doesn't. Of course, larger frameworks like Zope, Twisted, and PEAK all have interfaces, but since they're not part of the language or standard library, for most Python developers it's as if they don't exist. The existence of interfaces in Java means that the body of a specification can talk about named and rigorously defined kinds of objects, for whatever the specification is about. Python specifications, by contrast, are often characterized by handwavy notions of the "protocols" that objects implement, or are merely documentation for an implementation.

As long as one is dealing with libraries, this can perhaps suffice. But to create frameworks and platforms, it isn't enough to specify what one implementation does. You have to be able to talk about what implementations in general are supposed to do, because some of the users of a framework or platform will be creating their own implementations of needed functionality.

Consider OSGi, for example. OSGi is the Open Services Gateway Initiative, and they've defined a standard service platform for component-oriented, networked services. Basically, an OSGi platform implementation lets you install software "bundles". Bundles can import classes from other bundles, or export them, with managed version dependencies. They can be started or stopped, offer services to other bundles, and dynamically access services provided by other bundles. This allows you to create customized applications, such as a web server bundle that is dynamically notified when any bundles offer servlets that it should serve.

OSGi is used in a variety of products and systems, including "smart home" applications, vehicle electronics, and service provisioning systems. It's also used as the basis of the Eclipse IDE platform's "plug-in" system. Currently, the Python world has nothing like it. By comparison, Zope 2's Products and Chandler's Parcels are crude toys.

By the very nature of what something like OSGi does, it has to be specified in terms of interfaces. There are multiple platform implementations that load bundles, and of course there are many, many bundles, and services offered by those bundles. Without interfaces, there would be "no there there" -- nothing to exist or document.

And many Python developers would say, "So what? We don' need no stinkin' standards." Maybe especially not 600-page Java standards like OSGi. Arguably, only a handful of application platforms in the Python world are complex enough to truly need something like OSGi anyway: mainly IDEs, application servers, and extensible application platforms (like Chandler).

But, in the Java world, you don't have to "truly need" something in order to be able to benefit from it. If you use functionality of that kind, the sensible thing to do is to follow the standard, either by dropping in an existing implementation, or using your own mocked-up subset of the standard until you need a more sophisticated implementation. Either way, you have an established model to follow.

In this way, a savvy Java developer can avoid much of the head-scratching and prototyping that a Python developer would be doing in order to flesh out their needs in a given application area. Instead of reinventing the concept of the wheel, the Java developer just writes an IWheel implementation.

Of course, individual Python developers can and do pilfer from Java specs. I myself make it a particular point to examine the state-of-the-art in Java before undertaking the design of any complex facility for Python. I then have to go through a fairly lengthy process of "Pythonification", often involving multiple rewrites, to get the API truly Pythonic.

But when I'm done, my implementation and interfaces are still not a standard in the Python world. Nobody is going to know about what I did, and the next guy over is going to either do the same thing I did, or throw together their own little thing. Individually, perhaps, we are all productive, but our collective productivity is lower in the Python community, because we are all forced to reinvent 'IWheel', up until there's a 'Wheel' implementation in the standard library.

And of course that implementation will have to be all things to all people, or odds are good that it won't actually get into the standard library. And, by a curious coincidence, a surprising number of modules adopted by the standard library are in fact derived from equivalent Java interfaces or implementations! For example the 'logging' module comes from log4j, the 'threading' module mimics Java thread classes, and 'unitttest' is a JUnit clone.

So, does something about the Java language inherently inspire better specifications? Could it be that this is a byproduct of having, and consistently using, interfaces? Maybe the fact that Java forces you to think about interfaces (at least a little), encourages Java architects to design better frameworks? More to the point, is there any way we can leverage this characteristic in Python, such that we're not always begging scraps from Java's table?

Maybe that will never happen, perhaps because the Python community simply doesn't have the critical mass needed to have enough of the right people to design such specs. Or maybe kneejerk reactions against interfaces as "creeping static-ism" will keep the community from adopting the current de-facto standards for interfaces that exist in Zope, Twisted and PEAK.

Who can say? As for me, I'll just keep on picking my scraps of Java where I can find them, and working towards the day when Python won't have to rely on interfaces defined by ad-hoc description, and specifications defined by their implementation.

<< Dec 06: Mocking wxPython
>> Dec 07: From BBS to Blog

^^ Home