Java and Python: a perfect couple

Monday Aug 17th 1998 by Guido van Rossum

Programming and scripting languages are supposed to complement one another. The open-source scripting language Python is proving ideal for the cross-platform Java programming language, and the new JPython blend of the two may be the next "insanely great" tool for Web developers.

Introduction: The hope for a single language

Every once in a while a new, general programming language receives broad acceptance. A natural response, especially when the language receives as much media attention as Java, is to hope that in the future, all programs will be written in this one language.

True, historically this has never happened. Remember PL/1? Or C++? But we keep hoping, in the belief that there's progress in the field of programming language design. The high cost of learning several different languages, each useful for only a fraction of the spectrum of programming tasks, makes managers and programmers alike hope that this next language is "the one."

Maybe we're wrong, though. Maybe there will never be a single language covering the whole programming spectrum. After all, that spectrum covers such diverse activities as finding cheap airline tickets, predicting the weather, and producing 3D animations of giant lizards. (Not to mention more mundane activities, such as formatting expense reports or spell-checking documents.)

We may modify our expectations, hoping that in the future a single programmer will never have to learn more than one language. In our world of super-specialists, the task areas are likely to be disjoint anyway. If you're a game programmer in the future, you will use "the" 3D real-time language. If you're drilling for oil, you'll use "the" geological analysis language. If you're writing a data-entry tool, "the" GUI definition language will be all you ever need.

We need more than one language

I have a different vision. I'm not so naïve as to believe that we could all be renaissance programmers, capable of writing any kind of program. But I believe strongly that the tasks of most programmers are so diverse that a single language just doesn't cut it.

The designers of Unix knew this. They built two languages into their system right from the start: C as the system programming language to write applications and tools, and the shell for scripting: a casual language to glue those C programs together. Lately, more powerful languages like Python, Tcl and Perl are replacing the shell, but the principle remains the same.

Microsoft knows it. They offer developers two choices: C++ and Visual Basic, and many applications are written in a mixture of the two. For example, VB programs have easy access to controls written in C++.

John Ousterhout, the father of the scripting language Tcl, knows it. Several ideas here are taken from his paper "Scripting: Higher Level Programming for the 21st Century."

In general, we see more and more successful applications written in a combination of system programming language and scripting language. The two languages complement each other nicely, so that for a typical subtask, it will be clear cut which language to use. Adding a scripting language also makes it possible to provide much more flexible customization of an application.

The most commonly used general scripting languages are Visual Basic, Perl, Tcl and Python. (You may ask, what about JavaScript? So far it has found few applications outside Web browsers.) It is interesting to see which scripting languages are used most in conjunction with which system programming languages and on which platforms. VB is clearly the scripting language of choice for C++ on Windows; it is platform-specific and cannot easily fulfill the same role on other platforms. Perl and Tcl are used most often with C on Unix platforms.

Python is traditionally used with C and C++, but is less focused on Unix than Perl or Tcl. Python has a large following on Windows, and is exceptionally well integrated with COM and the Microsoft Scripting Host architecture on that platform. (It is said to be second only to VB in this respect.) Python also has pretty darn good Macintosh integration, providing direct access to a wide variety of native MacOS toolboxes.

So, what about Java?

First of all: I classify Java as a system programming language, not a scripting language. While it is interpreted, much of the JVM's architecture is very similar to a typical modern CPU -- a stack containing untyped 32-bit words, pointers, the works.

Java is mostly statically typed, requiring declarations of all variables. The highest-level data type supported directly by the language is a string -- while this is an improvement over C++, it's a far cry from the built-in hash tables and flex arrays that make scripting languages so pleasant to use.

A typical Java program will be a bit shorter than a C++ program that solves the same problem. This has relevance for development time: At best, a Java programmer is perhaps twice as productive as a C++ programmer -- a far cry from the productivity factors of 5 to 10 observed over and over for real scripting languages.

If Java is a system programming language, it needs a companion scripting language. In the rest of this article, I'll argue that Python is an ideal choice as Java's scripting companion, as well as show some examples of Java-Python interaction to back up this claim.

What is Python?

Python is a dynamic, interpreted, object-oriented language with a remarkably clean syntax. You can learn enough Python in an afternoon to start feeling productive. Python has been around since the early 1990s and has a very active following (though not yet as large as Perl or Tcl). Python is free (it's being developed as an open source project) and its implementation in portable C runs on almost every conceivable platform.

Here's a small sample of Python code: a function to invert a table.

def invert(table):
    index = {}                           # empty dictionary
    for key in table.keys():
        value = table[key]
        if not index.has_key(value):
            index[value] = []            # empty list
    return index

Here's a simple interactive Python session using this function:

>>> animals = {'schapen': 'sheep', 'schaap': 'sheep',
'koe': 'cow'}
>>> invert(animals)
{'cow': ['koe'], 'sheep': ['schapen', 'schaap']}

Notice the general look of Python code. Python has been called executable pseudo code: it is clean, without type declarations, using a colon and indentation to start a new block. Blocks are closed by matching dedentation. Curly braces denote dictionaries, a powerful built-in data type resembling an associative array; square brackets denote lists (built-in flexible arrays). Dictionaries can contain lists (and vice versa).

For more general information about Python, go to the Python Web site, which contains documentation, downloads, archives, and much more, including comparisons between Python and other languages; or read the Python newsgroup, comp.lang.python -- a very helpful and lively online community.

JPython -- the killer scripting language

Python is a good match for Java: it's object-oriented from the ground up. Contrast this with Perl, where OO was grafted on in version 5, or Tcl, where OO is only available as an extension (itcl).

But it's more than just a good match. The killer reason for choosing Python as Java's scripting companion is JPython, a Python interpreter written in 100% Pure Java. For example, using JPython, you can write applets in Python that will run in any JDK-1.1 compliant web browser. (But JPython can be used for many other things besides writing applets!) JPython executes Python code almost as fast as the C implementation (a.k.a., CPython). Since JVMs are still getting faster, there's even hope that it will eventually overtake CPython.

JPython obtains its remarkable speed by translating Python source code directly into Java bytecode. This is in contrast to Jacl, a 100% Java reimplementation of Tcl -- it is an actual Tcl interpreter written in Java, and as such it is much slower. Other Java scripting solutions, available for Tcl (Tcl Blend) and Perl (JPL), are not 100% pure Java: they attach a JVM to the C implementation of Tcl or Perl. This obviously creates portability problems: in order to use either Tcl Blend or JPL on a particular platform, you need to find a Tcl or Perl implementation and a JVM that will talk to each other. JPython, on the other hand, needs only a JVM.

JPython's integration between Java and Python is remarkably seamless. A Python script can import any Java class that's accessible on the class path. Python can call static and instance methods of Java classes, create instances, and even create subclasses of Java classes. Instances of those subclasses can be passed back to Java, and their methods (implemented in Python) can be called by Java code.

For example, here's a JPython applet displaying the string "Hello world":

from java.applet import Applet

class HelloWorld(Applet):
    def paint(self, gc):
        gc.drawString("Hello world", 20, 30)

This tiny program demonstrates many of JPython's key features: it runs in any (JDK-1.1-compliant) browser, it imports a Java class and creates a subclass of it, and its

method will be invoked by the Java code of the AWT event loop.

Here's a somewhat larger example: an applet that implements a simple but functional calculator.

from java import awt
from pawt import swing

labels = ['7', '8', '9', '+',
          '4', '5', '6', '-',
          '1', '2', '3', '*',
          '0', '.', '=', '/' ]

keys = swing.JPanel(awt.GridLayout(4, 4))
display = swing.JTextField()

def push(event):                # Callback for regular keys

def enter(event):               # Callback for '=' key
    display.text = str(eval(display.text))

for label in labels:
    key = swing.JButton(label)
    if label == '=':
        key.actionPerformed = enter
        key.actionPerformed = push

panel = swing.JPanel(awt.BorderLayout())
panel.add("North", display)
panel.add("Center", keys)

Readers familiar with Java code will appreciate the conciseness of these examples, compared to code that accomplishes the equivalent in Java.

Notice in particular the use of

in the
callback. The built-in Python function
takes a string representing an arbitrary Python expression, compiles it into Java bytecode, executes it and returns the resulting value. This is a standard feature of scripting languages, which is absent in typical system programming languages, including Java: the Java runtime doesn't typically have the Java compiler around.

How can you best use Java and JPython together?

There are a number of approaches.

One option is to prototype the entire application in JPython, do several test/redesign/reimplement cycles, and finally rewrite the whole application in Java. This leverages the increased flexibility and development speed of a scripting language during the early project phases. With a much faster redesign cycle, design experiments are much less costly, and design mistakes are easier to fix. The final design, to be implemented in Java, will be much more thorough than when programming had started in Java. Since JPython has access to the same user interface libraries (AWT, Swing) as Java, the Java rewrite will encounter few surprises.

If you try this approach to build a large system, you'll find that its different components or layers often have independent development cycles. Typically the top-level components keeps evolving while the lower layers are already frozen. This suggests a variant of the rewrite-in-Java approach: rewrite individual components in Java as their design stabilizes. Now JPython's seamless Java integration is essential: interfaces can remain the same while the implementation changes from JPython to Java. (Of course, there is no reason why some components can't be written in Java from the start; JPython makes reuse of existing Java code very easy.)

The next time-saving option is only to rewrite those components in Java for which performance is critical. The high-level components can generally remain written in JPython. For many applications, this may mean that only a few low-level parts ever need to be recoded in Java. (Sometimes the whole application can remain in JPython!) When using good judgment, time-to-market can be reduced drastically in this way.

Once parts of the released version of a system are coded in JPython, the road is open for end-user customization through JPython scripts. Python is an easy language to learn for end users, and the application can easily invoke user scripts at critical points during initialization or execution. JPython programs can be distributed as Java bytecode, so there's little danger that adventurous end users will rewrite components they aren't supposed to touch (and standard precautions against decompilation or reverse engineering can also be taken).

This approach has already been shown to be very successful in the CPython world. For example, Infoseek's Ultraseek site search product is a Python application built on top of a search engine coded in C; it can be customized via user-supplied Python scripts. Version 1.0 of the product was designed and built in a few weeks by a single programmer who had to learn Python first -- and it had more features than any of its competitors. As another example, in 1995-1996 a small company called eShop built a Web-based electronic shopping server in Python. It was so successful that the company was bought by Microsoft based on this one product. The short development time made possible by the use of Python was key in their success relative to competitors. (The product is now called Merchant Server 3.0 and has been gradually rewritten in C++.)

Similar success stories are already emerging for JPython, but it is too early to report on specific cases -- JPython 1.0 was only released in July 1998 (after a public alpha and beta test cycle that started in late 1997).


Many implementation efforts benefit from the combination of a system programming language and a scripting language. The system programming language Java needs a scripting companion. JPython, a dialect of the general-purpose scripting language Python, is the ideal candidate: object-oriented from the start, seamlessly integrated, and 100% pure Java. We expect that the success stories from Python users will soon be repeated for JPython's.

Guido van Rossum created Python in the early 1990s and still manages its development. He works as a researcher for the Corporation for National Research Initiatives, where he uses Python to develop infrastructural software for the Internet of the future.

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved