Editor: Kevin Tostado
Notes from Allen:
Python vs Java
Programming Language Death Match:
1. Choose whether to be an advocate or an adjudicator.
2. Tell me something that you either like or dislike about Python or Java.
3. Let's ask some questions:
- Intrinsic or incidental? Could the problem be fixed? b. Pet Peeve or Important in practice? c. Universally good/bad or context dependent?
Some Differences (mostly intrinsic)
- Java has interfaces (that is, compile-time checking of whether a particular type can be used in a particular context). Python waits until run-time to check.
- Java has private variables (that is, compiler-enforced restrictions on some kinds of variable access). Python doesn't enforce encapsulation."
- Java has more and better support for security.
- Threading facilities are similar, but Java provides synchronized objects.
- Python provides access to system tools, tries to wrap and standardize. Java is strictly system-independent.
- Python supports multiple inheritance.
- Python functions and classes are first-class objects.
- Python has extensive operator overloading. Java doesn't.
- Python doesn't have method overloading, but variable argument lists make 75% of method overloading unneccessary. The other 25% is a pain.
- Polymorphism is possible in both, but in Java you have to plan to make it happen; in Python it can be discovered (as in the example Guido cites below).
- Data structures are built-into Python at the syntax level, not the library level.
- Support for distributed programming is more mature and standard in Java.
- Software development tools (like IDEs and documentation tools) are more mature in Java.
- Python is dynamically-typed, Java is statically-typed.
What did they know, and when did they know it?
1. compile/link time
2. run time
Even in interpreted languages, it is still necessary to have a mental model of
1. what happens at compile time vs run time
2. what kind of erros happen at compile time vs run time
3. what information is available at compile time vs run time
In this context,
1. static means things that happen at compile time, and
2. dynamic means things that happen at run time.
1. static typing means that the compiler/interpreter can tell at compile time what type each expression has (that is, will have)
2. dynamic typing means that the compiler doesn't know the type of all expressions, so if there is type-checking, it has to be done at run time.
You will aslo hear people talk about strongly-typed and weakly-typed languages, but these terms are relative (that is, defined by their context). Out of context, they are almost meaningless.
Some dynamic information isn't available at compile time.
Examples from class:
- Python does not usually know types at compile time, Java usually does.
Some static information isn't saved for run time.
Examples from class:
- Values of variables, return values.
- (Accessing static information at run time is sometimes called "reflection")
Some good quotes
Bertrand Meyer claims that static typing improves:
Comes from the use of static typing to detect errors that would otherwise manifest themselves only at run time, and only in certain runs. The rule that forces you to declare entities and fucntions introduces redundancies into the software text; this enables the compiler to detect inconsistencies between the purpose and actual use of an entity, feature, or expression.
Declaring every entity and function with a certain type is a powerful way of conveying to the software reader some information about its intended uses. This is particularly precious for maintainers of the software.
This benefit can make the difference between the success and failure of object technology in practice. Without static typing, the execution of x.f (arg) can take an arbitrary long time-- the basic algorithm looks for a feature f in the base class C of x's type; if it does not find it, it looks in C's parents, and so on. This can be a fatal source of inefficiency. It can be mitigated by improvements in the basic algorithm, and the authors of the Self language have done extensive work to enable better code generation for a dynamically typed language. But it is through static typing that OO software has been able to approach or equal the efficency of traditional software.
Guido van Rossum
People who fear that someone will call their code with the wrong arguments, and who are used to having static-typed language prevent that at the compiler level, will try to prevent that happening in their code by adding explicity assertions. People will check the types. They'll think, "Oh, this only works for strings, so now I'll assert that the input argument is a string."
That is the completely wrong approach, because someone could easily implement something that works just as well with your code and behaves sufficiently like a string. Maybe it's a proxy for a string, which behaves in almost every aspect as a string, except that its type is a proxy. That's something we use in Zope a lot. The persistency mechanism uses proxies, as does the security mechanism that executes untrusted Web-submitted codoe. Untrusted code is executed in a sandbox environment using proxies for objects that the code shouldn't be accessing directly. So the fact that the language doesn't enforce types at either the compiler level or the implementation level is actually helpful.
Also from Guido
Python programs are generally expected to run slower than Java programs, but they also take much less time to develop. Python programs are typically 3-5 times shorter than equivalent Java programs. This difference can be attributed to Python's built-in high-level data types and its dynamic typing. For example, a Python programmer wastes no time declaring the types of arguments or variables, and Python's powerful polymorphic list and dictionary types, for which rich syntactic support is built straight into the language, find a use in almost every Python program.
Because of the run-time typing, Python's run time must work harder than Java's. For example, when evaluating the expression a+b, it must first inspect the the objects a and b to find out their type, which is not known at compile time. It then invokes the appropriate addition operation, which may be an overloaded user-defined method. Java, on the other hand, can perform an efficient integer or floating point addition, but requires variable declarations for a and b, and does not allow overloading of the + operator for instances of user-defined classes.