(12 ratings)   
By: Steve Ferg
A programmer can be significantly more productive in Python than in Java. How much more productive? The most widely accepted estimate is 5-10 times. On the basis of my own personal experience with the two languages, I agree with this estimate.
Added: 02 June 2008    Views: 94  
PathComputers    Programming    Python
Keywords: computer   programming   python   code   coder   java   versus  
Do you like this tutorial? Now you can support our team to add more :     
 
 
 

A programmer can be significantly more productive in Python than in Java. How much more productive? The most widely accepted estimate is 5-10 times. On the basis of my own personal experience with the two languages, I agree with this estimate.

Managers who are considering adding Python to their organization's list of approved development tools, however, cannot afford to accept such reports uncritically. They need evidence, and some understanding of why programmers are making such claims. This page is for those managers.

On this page, I present a list of side-by-side comparisons of features of Java and Python. If you look at these comparisons, you can see why Python can be written much more quickly, and maintained much more easily, than Java. The list is not long — it is meant to be representative, not exhaustive.

This page looks only at programmer productivity, and does not attempt to compare Java and Python on any other basis. There is, however, one related topic that is virtually impossible to avoid. Python is a dynamically-typed language, and this feature is an important reason why programmers can be more productive with Python; they don't have to deal with the overhead of Java's static typing. So the debates about Java/Python productivity inevitably turn into debates about the comparative advantages and drawbacks of static typing versus dynamic typing — or strong typing versus weak typing — in programming languages. I will not discuss that issue here, other than to note that in the last five years a number of influential voices in the programming community have been expressing serious doubts about the supposed advantages of static typing. For those who wish to pursue the matter, Strong versus Weak Typing: A Conversation with Guido van Rossum, Part V is a good place to start. See also Bruce Eckel's weblog discussion Strong Typing vs. Strong Testing and Robert C. Martin's weblog discussion Are Dynamic Languages Going to Replace Static Languages?. For background, see one of the papers that started it all in 1998 — Scripting: Higher Level Programming for the 21st Century by John Ousterhout.

Several of these discussions contain valuable comparisons of Java and Python. For other language comparisons, see the Python language comparisons page at www.python.org, and the PythonComparedToJava page at Python for Java Programmers.

Finally, it is important to note that asserting that a programmer can be more productive in Python than in Java, is not the same as asserting that one ought always to use Python and never to use Java. Programming languages are tools, and different tools are appropriate for different jobs. It is a poor workman whose toolbox contains only a hammer (no matter how big it is!), and it is a poor programmer (or software development organization) whose development toolkit contains only one programming language. Our toolboxes should contain both Python and Java, so that in any given situation we have the option of choosing the best tool for the job. So our claim is not that Python is the only programming language that you'll ever need — only that the number of jobs for which Python is the best tool is much larger than is generally recognized.

There are three main language characteristics that make programmers more productive with Python than with Java.

Java Python
statically typed

In Java, all variable names (along with their types) must be explicitly declared. Attempting to assign an object of the wrong type to a variable name triggers a type exception. That's what it means to say that Java is a statically typed language.

Java container objects (e.g. Vector and ArrayList) hold objects of the generic type Object, but cannot hold primitives such as int. To store an int in a Vector, you must first convert the int to an Integer. When you retrieve an object from a container, it doesn't remember its type, and must be explicitly cast to the desired type.

dynamically typed

In Python, you never declare anything. An assignment statement binds a name to an object, and the object can be of any type. If a name is assigned to an object of one type, it may later be assigned to an object of a different type. That's what it means to say that Python is a dynamically typed language.

Python container objects (e.g. lists and dictionaries) can hold objects of any type, including numbers and lists. When you retrieve an object from a container, it remembers its type, so no casting is required.

For more information on static vs. dynamic typing, see the appendix.

verbose "abounding in words; using or containing more words than are necessary" concise (aka terse) "expressing much in a few words. Implies clean-cut brevity, attained by excision of the superfluous"
not compact compact

In The New Hacker's Dictionary, Eric S. Raymond gives the following definition for "compact":

Compact adj. Of a design, describes the valuable property that it can all be apprehended at once in one's head. This generally means the thing created from the design can be used with greater facility and fewer errors than an equivalent tool that is not compact.

Example

The classic "Hello, world!" program illustrates the relative verbosity of Java.

Java Python
public class HelloWorld
{
public static void main (String[] args)
{
System.out.println("Hello, world!");
}
}
print "Hello, world!"

Example

In the following example, we initialize an integer to zero, then convert it to a string, then check to see if it is empty. Note the data declaration (highlighted), which is necessary in Java but not in Python. Notice also how verbose Java is, even in an operation as basic as comparing two strings for equality.

Java Python
int    myCounter = 0;
String myString = String.valueOf(myCounter);
if (myString.equals("0")) ...
myCounter = 0
myString = str(myCounter)
if myString == "0": ...
// print the integers from 1 to 9
for (int i = 1; i < 10; i++) {
System.out.println(i);
}
# print the integers from 1 to 9
for i in range(1,10):
print i

Example

Your application has 15 classes. (More precisely, it has 15 top-level public classes.)

Java Python
Each top-level public class must be defined in its own file. If your application has 15 such classes, it has 15 files. Multiple classes can be defined in a single file. If your application has 15 classes, the entire application could be stored in a single file, although you would probably want to partition it sensibly into perhaps 4, 5, or 6 files.

Example

In your application, method A calls B calls C calls D calls E calls F. You discover that F must throw exception SpecialException, and it must be caught by A.

Java Python
You must throw SpecialException in F, and catch it in A.
and
You must add "throws SpecialException" to the signatures of methods B, C, D, E, and F.
You must raise SpecialException in F, and catch it in A.

Exceptions will propagate upward automatically; there is nothing more that you must do.

The reason for this is that Java, virtually alone among object-oriented programming languages, uses checked exceptions — exceptions that must be caught or thrown by every method in which they might appear, or the code will fail to compile. Recently (as of June 2003) there seems to be an increasing amount of unhappiness with Java's use of checked exceptions. See Bruce Eckel's "Does Java need Checked Exceptions?" and Ron Waldhoff's "Java's checked exceptions were a mistake".

As chromatic, the Technical Editor of the O'Reilly Network, put it:

I like the idea of checked exceptions in some situations, but forcing every method to deal with (catching or throwing) all exceptions that its child calls or may call can be tedious. I'd rather be able to ignore an exception and let it propagate upwards. Sometimes, I'd rather not worry about exceptions at all.

Example

Your application has an Employee class. When an instance of Employee is created, the constructor may be passed one, two, or three arguments.

If you are programming in Java, this means that you write three constructors, with three different signatures. If you are programming in Python, you write only a single constructor, with default values for the optional arguments.

Java Python
public class Employee
{
private String myEmployeeName;
private int myTaxDeductions = 1;
private String myMaritalStatus =
"single";

//--------- constructor #1 ------
public Employee(String EmployeName)
{
this(employeeName, 1);
}

//--------- constructor #2 ------
public Employee(String EmployeName,
int taxDeductions)
{
this(employeeName, taxDeductions,
"single");
}

//--------- constructor #3 ------
public Employee(String EmployeName,
int taxDeductions,
String maritalStatus)
{
this.employeeName = employeeName;
this.taxDeductions = taxDeductions;
this.maritalStatus = maritalStatus;
}
...
class Employee():

def __init__(self,
employeeName, taxDeductions=1,
maritalStatus="single"):

self.employeeName = employeeName
self.taxDeductions = taxDeductions
self.maritalStatus = maritalStatus
...






In Python, a class has only one constructor. The constructor method is simply another method of the class, but one that has a special name: __init__

Example

In Why Python? Eric S. Raymond notes that:

Python ... is compact — you can hold its entire feature set (and at least a concept index of its libraries) in your head.

In Why I Love Python Bruce Eckel notes that Java is not compact.

I can remember many Python idioms because they're simpler. That's one more reason I program faster [in Python]. I still have to look up how to open a file every time I do it in Java. In fact, most things in Java require me to look something up.
Java Python
import java.io.*;

...

BufferedReader myFile =
new BufferedReader(
new FileReader(argFilename));
# open an input file
myFile = open(argFilename)

Example

Java's string-handling capabilities are surprisingly weak. (But they have improved considerably with the addition of the split method to the String class in Java 1.4.)

Function or Method Java Python
Remove leading and trailing whitespace from string s s.trim() s.strip()
Remove leading whitespace from string s
(not available)
s.lstrip()
Remove trailing whitespace from string s
(not available)
s.rstrip()

Example

Code to add an int to a Vector, and then retrieve it.

Prior to Java 1.5, a new Integer object had to be created and initialized from the int before it could be added to a Vector. In order to retrieve the value, the member of the Vector had to be cast back to an Integer, and then converted back to an int.

Java (before version 1.5) Python
public Vector aList        = new Vector;
public int aNumber = 5;
public int anotherNumber;

aList.addElement(new Integer(aNumber));
anotherNumber =
((Integer)aList.getElement(0)).intValue();
aList = []
aNumber = 5


aList.append(aNumber)
anotherNumber = aList[0]

This clumsiness was eliminated in Java 1.5 with the introduction of generics (which allows you to "type" a container object) and autoboxing (which automates conversion between primitive types and their corresponding wrapper classes). With generics, it is possible to code ContainerType ( which reads as ContainerType restricted to objects of ContainedType).

Java (after version 1.5) Python
public Vector aList = new Vector;
public int aNumber = 5;
public int anotherNumber;

aList.addElement(aNumber);
anotherNumber = aList.getElement(0);
aList = []
aNumber = 5


aList.append(aNumber)
anotherNumber = aList[0]

Example

Verbosity is not just a matter of increasing the number of characters that must be typed — it is also a matter of increasing the number of places where mistakes can be made. The Java code on the left has 5 control characters: ( ) { } ; where the corresponding Python code has only one control character, the colon. (Or two, if you count indentation. See below.)

Java Python
if ( a > b )
{
a = b;
b = c;
}
if  a > b :
a = b
b = c

Omitting or duplicating such characters is easy to do accidentally, and constitutes a severe error in the code. In my personal estimate, I spend 5 times as much time fixing such errors in Java as I do in Python. It really cuts into your productivity — and your creative energy — when you spend that much of your time just trying to satisfy the compiler.

Technically, Python has another control character that Java does not — indentation. But the requirement for correct indentation is the same in Java as it is in Python, because in both languages correct indentation is a practical requirement for human-readable code. The Python interpreter automatically enforces correct indentation, whereas the Java compiler does not. With Java, you need an add-on product such as the Jalopy code formatter to provide automated enforcement of indentation standards.



APPENDIX: About static vs. dynamic typing, and strong vs. weak typing, of programming languages.

There is widespread confusion or disagreement about the meanings of the words static, dynamic, strong and weak when used to describe the type systems of programming languages. What follows is a description of the way (or at least one of the ways) these terms are most commonly used.

In a statically typed language, every variable name is bound both (1) to a type (at compile time, by means of a data declaration) and (2) to an object. The binding to an object is optional — if a name is not bound to an object, the name is said to be null. Once a variable name has been bound to a type (that is, declared) it can be bound (via an assignment statement) only to objects of that type; it cannot ever be bound to an object of a different type. An attempt to bind the name to an object of the wrong type will raise a type exception.

In a dynamically typed language, every variable name is (unless it is null) bound only to an object. Names are bound to objects at execution time by means of assignment statements, and it is possible to bind a name to objects of different types during the execution of the program.

Here is an example. In a statically-typed language, the following sequence of statements (which binds an integer object, then a string object, to the name employeeName) is illegal. If employeeName had been declared to be an int, then the second statement would be illegal; if it had been declared to be a String, then the first statement would be illegal. But in a dynamically-typed language this sequence of statements is perfectly fine.

employeeName = 9
employeeName = "Steve Ferg"

Python is a dynamically-typed language. Java is a statically-typed language.

In a weakly typed language, variables can be implicitly coerced to unrelated types, whereas in a strongly typed language they cannot, and an explicit conversion is required. (Note that I said unrelated types. Most languages will allow implicit coercions between related types — for example, the addition of an integer and a float. By unrelated types I mean things like numbers and strings.) In a typical weakly typed language, the number 9 and the string "9" are interchangeable, and the following sequence of statements is legal.

a  = 9
b = "9"
c = concatenate(a, b) // produces "99"
d = add(a, b) // produces 18

In a strongly typed language, on the other hand, the last two statements would raise type exceptions. To avoid these exceptions, some kind of explicit type conversion would be necessary, like this.

a  = 9
b = "9"
c = concatenate( str(a), b)
d = add(a, int(b) )

Both Java and Python are strongly typed languages. Examples of weakly typed languages are Perl and Rexx.

A third distinction may be made between manifestly typed languages in which variable names must have explicit type declarations, and implictly typed languages in which this is not required. Most static languages are also manifestly typed (Java certainly is), but Frank Mitchell notes that some are not: "Haskell and the dialects of ML, for example, can infer the type of any variable based on the operations performed on it, with only occasional help from an explicit type."

About the Author :
Visit : www.ferg.org
 Rate this tutorial : Rate 1Rate 2Rate 3Rate 4Rate 5
  |    Add to Favorites
  |    Send to Friend
  |    Print
Comments